# HG changeset patch
# User cin
# Date 2014-06-18 23:41:28
# Node ID 10c7337d29e76b8ac13e0b09718552b9cf9af860
# Parent 21611344d366c6f5bc1d5f201f456e57a1b536ab
+JSONXmlReaderOptions
*JSONScanner: fixed reading from TextReader
*code cleanup
diff --git a/Implab/Implab.csproj b/Implab/Implab.csproj
--- a/Implab/Implab.csproj
+++ b/Implab/Implab.csproj
@@ -63,6 +63,7 @@
+
diff --git a/Implab/JSON/JSONScanner.cs b/Implab/JSON/JSONScanner.cs
--- a/Implab/JSON/JSONScanner.cs
+++ b/Implab/JSON/JSONScanner.cs
@@ -8,13 +8,16 @@ using System.Threading.Tasks;
namespace Implab.JSON {
///
- /// Сканнер, разбивающий поток символов на токены JSON.
+ /// Сканнер (лексер), разбивающий поток символов на токены JSON.
///
public class JSONScanner : Scanner {
char[] m_stringBuffer;
DFAStateDescriptior[] m_stringDFA;
int[] m_stringAlphabet;
+ ///
+ /// Создает новый экземпляр сканнера
+ ///
public JSONScanner()
: base(JSONGrammar.Instance.JsonDFA) {
m_stringBuffer = new char[1024];
@@ -23,6 +26,14 @@ namespace Implab.JSON {
m_stringDFA = dfa.States;
}
+ ///
+ /// Читает следующий лексический элемент из входных данных.
+ ///
+ /// Возвращает значение прочитанного токена.
+ /// Возвращает тип прочитанного токена.
+ /// true - чтение произведено успешно. false - достигнут конец входных данных
+ /// В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
+ /// в строках обрабатываются экранированные символы, числа становтся типа double.
public bool ReadToken(out object tokenValue, out JsonTokenType tokenType) {
if (ReadTokenInternal()) {
switch ((JSONGrammar.TokenType)m_currentState.tag[0]) {
diff --git a/Implab/JSON/JSONXmlReader.cs b/Implab/JSON/JSONXmlReader.cs
--- a/Implab/JSON/JSONXmlReader.cs
+++ b/Implab/JSON/JSONXmlReader.cs
@@ -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 @@ namespace ConsPlay {
ReadState m_state = ReadState.Initial;
Stack m_localNameStack = new Stack();
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();
+ }
}
///
@@ -194,7 +212,7 @@ namespace ConsPlay {
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 @@ namespace ConsPlay {
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);
+ }
}
}
diff --git a/Implab/JSON/JSONXmlReaderOptions.cs b/Implab/JSON/JSONXmlReaderOptions.cs
new file mode 100644
--- /dev/null
+++ b/Implab/JSON/JSONXmlReaderOptions.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+
+namespace Implab.JSON {
+ ///
+ /// Набор необязательных параметров для , позволяющий управлять процессом
+ /// интерпретации JSON документа.
+ ///
+ public class JSONXmlReaderOptions {
+ ///
+ /// Пространство имен в котором будут располагаться читаемые элементы документа
+ ///
+ public string NamespaceURI {
+ get;
+ set;
+ }
+
+ ///
+ /// Интерпретировать массивы как множественные элементы (убирает один уровень вложенности)
+ ///
+ public bool FlattenArrays {
+ get;
+ set;
+ }
+
+ ///
+ /// Префикс, для узлов документа
+ ///
+ public string NodesPrefix {
+ get;
+ set;
+ }
+
+ ///
+ /// Имя корневого элемента в xml документе
+ ///
+ public string RootName {
+ get;
+ set;
+ }
+
+ ///
+ /// Имя элемента для массивов, если не включена опция .
+ ///
+ public string ArrayItemName {
+ get;
+ set;
+ }
+
+ ///
+ /// Таблица атомизированных строк для построения документа.
+ ///
+ public XmlNameTable NameTable {
+ get;
+ set;
+ }
+ }
+}
diff --git a/Implab/Parsing/Scanner.cs b/Implab/Parsing/Scanner.cs
--- a/Implab/Parsing/Scanner.cs
+++ b/Implab/Parsing/Scanner.cs
@@ -167,7 +167,8 @@ namespace Implab.Parsing {
m_pointer++;
if (m_pointer >= m_bufferSize) {
- return ReadNextChunk();
+ if (!ReadNextChunk())
+ return false;
}
m_previewCode = m_alphabetMap[m_buffer[m_pointer]];