changeset 60:10c7337d29e7

+JSONXmlReaderOptions *JSONScanner: fixed reading from TextReader *code cleanup
author cin
date Thu, 19 Jun 2014 03:41:28 +0400
parents 21611344d366
children 90069a2ec20a
files Implab/Implab.csproj Implab/JSON/JSONScanner.cs Implab/JSON/JSONXmlReader.cs Implab/JSON/JSONXmlReaderOptions.cs Implab/Parsing/Scanner.cs
diffstat 5 files changed, 109 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/Implab/Implab.csproj	Wed Jun 18 03:54:02 2014 +0400
+++ b/Implab/Implab.csproj	Thu Jun 19 03:41:28 2014 +0400
@@ -63,6 +63,7 @@
     <Compile Include="JSON\JsonTokenType.cs" />
     <Compile Include="JSON\JSONWriter.cs" />
     <Compile Include="JSON\JSONXmlReader.cs" />
+    <Compile Include="JSON\JSONXmlReaderOptions.cs" />
     <Compile Include="JSON\StringTranslator.cs" />
     <Compile Include="Parallels\DispatchPool.cs" />
     <Compile Include="Parallels\ArrayTraits.cs" />
--- a/Implab/JSON/JSONScanner.cs	Wed Jun 18 03:54:02 2014 +0400
+++ b/Implab/JSON/JSONScanner.cs	Thu Jun 19 03:41:28 2014 +0400
@@ -8,13 +8,16 @@
 
 namespace Implab.JSON {
     /// <summary>
-    /// Сканнер, разбивающий поток символов на токены JSON.
+    /// Сканнер (лексер), разбивающий поток символов на токены JSON.
     /// </summary>
     public class JSONScanner : Scanner {
         char[] m_stringBuffer;
         DFAStateDescriptior[] m_stringDFA;
         int[] m_stringAlphabet;
 
+        /// <summary>
+        /// Создает новый экземпляр сканнера
+        /// </summary>
         public JSONScanner()
             : base(JSONGrammar.Instance.JsonDFA) {
             m_stringBuffer = new char[1024];
@@ -23,6 +26,14 @@
             m_stringDFA = dfa.States;
         }
 
+        /// <summary>
+        /// Читает следующий лексический элемент из входных данных.
+        /// </summary>
+        /// <param name="tokenValue">Возвращает значение прочитанного токена.</param>
+        /// <param name="tokenType">Возвращает тип прочитанного токена.</param>
+        /// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns>
+        /// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
+        /// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks>
         public bool ReadToken(out object tokenValue, out JsonTokenType tokenType) {
             if (ReadTokenInternal()) {
                 switch ((JSONGrammar.TokenType)m_currentState.tag[0]) {
--- a/Implab/JSON/JSONXmlReader.cs	Wed Jun 18 03:54:02 2014 +0400
+++ b/Implab/JSON/JSONXmlReader.cs	Thu Jun 19 03:41:28 2014 +0400
@@ -1,14 +1,14 @@
 using Implab;
-using Implab.JSON;
 using Implab.Parsing;
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Xml;
 
-namespace ConsPlay {
+namespace Implab.JSON {
     public class JSONXmlReader : XmlReader {
 
         enum ValueContext {
@@ -29,16 +29,34 @@
         ReadState m_state = ReadState.Initial;
         Stack<LocalNameContext> m_localNameStack = new Stack<LocalNameContext>();
         LocalNameContext m_localName;
-        string m_rootName = "json";
-        string m_prefix = String.Empty;
-        string m_namespaceUri = String.Empty;
-        bool m_flattenArrays = false;
-        NameTable m_nameTable = new NameTable();
         int m_depthCorrection = 0;
 
-        public JSONXmlReader(JSONParser parser) {
+        readonly string m_rootName;
+        readonly string m_prefix;
+        readonly string m_namespaceUri;
+        readonly bool m_flattenArrays;
+        readonly string m_arrayItemName;
+        readonly XmlNameTable m_nameTable;
+        
+        public JSONXmlReader(JSONParser parser, JSONXmlReaderOptions options) {
             Safe.ArgumentNotNull(parser, "parser");
             m_parser = parser;
+
+            if (options != null) {
+                m_prefix = options.NodesPrefix ?? String.Empty;
+                m_namespaceUri = options.NamespaceURI ?? String.Empty;
+                m_rootName = options.RootName ?? "json";
+                m_flattenArrays = options.FlattenArrays;
+                m_arrayItemName = options.ArrayItemName ?? "item";
+                m_nameTable = options.NameTable ?? new NameTable();
+            } else {
+                m_prefix = String.Empty;
+                m_namespaceUri = String.Empty;
+                m_rootName = "json";
+                m_flattenArrays = false;
+                m_arrayItemName = "item";
+                m_nameTable = new NameTable();
+            }
         }
 
         /// <summary>
@@ -194,7 +212,7 @@
                         RestoreLocalName();
                         break;
                 }
-                string itemName = m_parser.ElementType == JSONElementType.None ? m_rootName : m_flattenArrays ? m_localName.localName : "item";
+                string itemName = m_parser.ElementType == JSONElementType.None ? m_rootName : m_flattenArrays ? m_localName.localName : m_arrayItemName;
                 while (m_parser.Read()) {
                     if (!String.IsNullOrEmpty(m_parser.ElementName))
                         itemName = m_parser.ElementName;
@@ -282,5 +300,11 @@
             base.Dispose(disposing);
         }
 
+
+        public static JSONXmlReader OpenFile(string file, JSONXmlReaderOptions options) {
+            var stream = File.OpenText(file);
+            var parser = new JSONParser(stream, true);
+            return new JSONXmlReader(parser, options);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/JSON/JSONXmlReaderOptions.cs	Thu Jun 19 03:41:28 2014 +0400
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+
+namespace Implab.JSON {
+    /// <summary>
+    /// Набор необязательных параметров для <see cref="JSONXmlReader"/>, позволяющий управлять процессом
+    /// интерпретации <c>JSON</c> документа.
+    /// </summary>
+    public class JSONXmlReaderOptions {
+        /// <summary>
+        /// Пространство имен в котором будут располагаться читаемые элементы документа
+        /// </summary>
+        public string NamespaceURI {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Интерпретировать массивы как множественные элементы (убирает один уровень вложенности)
+        /// </summary>
+        public bool FlattenArrays {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Префикс, для узлов документа
+        /// </summary>
+        public string NodesPrefix {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Имя корневого элемента в xml документе
+        /// </summary>
+        public string RootName {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Имя элемента для массивов, если не включена опция <see cref="FlattenArrays"/>.
+        /// </summary>
+        public string ArrayItemName {
+            get;
+            set;
+        }
+
+        /// <summary>
+        /// Таблица атомизированных строк для построения документа.
+        /// </summary>
+        public XmlNameTable NameTable {
+            get;
+            set;
+        }
+    }
+}
--- a/Implab/Parsing/Scanner.cs	Wed Jun 18 03:54:02 2014 +0400
+++ b/Implab/Parsing/Scanner.cs	Thu Jun 19 03:41:28 2014 +0400
@@ -167,7 +167,8 @@
             m_pointer++;
 
             if (m_pointer >= m_bufferSize) {
-                return ReadNextChunk();
+                if (!ReadNextChunk())
+                    return false;
             }
 
             m_previewCode = m_alphabetMap[m_buffer[m_pointer]];