comparison Implab/JSON/JSONParser.cs @ 59:21611344d366

code cleanup
author cin
date Wed, 18 Jun 2014 03:54:02 +0400
parents 7759c80cad95
children 62b440d46313
comparison
equal deleted inserted replaced
58:1710dcda34bb 59:21611344d366
1 using Implab; 1 using Implab;
2 using Implab.Parsing; 2 using Implab.Parsing;
3 using System; 3 using System;
4 using System.Collections.Generic; 4 using System.Collections.Generic;
5 using System.Diagnostics; 5 using System.Diagnostics;
6 using System.IO;
6 using System.Linq; 7 using System.Linq;
7 using System.Text; 8 using System.Text;
8 using System.Threading.Tasks; 9 using System.Threading.Tasks;
9 10
10 namespace Implab.JSON { 11 namespace Implab.JSON {
17 } 18 }
18 19
19 /// <summary> 20 /// <summary>
20 /// Pull парсер JSON данных. 21 /// Pull парсер JSON данных.
21 /// </summary> 22 /// </summary>
22 public class JSONParser : DFAutomaton<JSONParserContext> { 23 public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable {
23 24
24 enum MemberContext { 25 enum MemberContext {
25 MemberName, 26 MemberName,
26 MemberValue 27 MemberValue
27 } 28 }
28 29
29 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet; 30 static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet;
30 static readonly DFAStateDescriptior[] _jsonDFA; 31 static readonly DFAStateDescriptior[] _jsonDFA;
31 static readonly DFAStateDescriptior[] _objectDFA; 32 static readonly DFAStateDescriptior[] _objectDFA;
32 static readonly DFAStateDescriptior[] _arrayDFA; 33 static readonly DFAStateDescriptior[] _arrayDFA;
73 MemberContext m_memberContext; 74 MemberContext m_memberContext;
74 75
75 JSONElementType m_elementType; 76 JSONElementType m_elementType;
76 object m_elementValue; 77 object m_elementValue;
77 78
79 /// <summary>
80 /// Создает новый парсер на основе строки, содержащей JSON
81 /// </summary>
82 /// <param name="text"></param>
78 public JSONParser(string text) 83 public JSONParser(string text)
79 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty } ) { 84 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
80 Safe.ArgumentNotEmpty(text, "text"); 85 Safe.ArgumentNotEmpty(text, "text");
81 m_scanner = new JSONScanner(); 86 m_scanner = new JSONScanner();
82 m_scanner.Feed(text.ToCharArray()); 87 m_scanner.Feed(text.ToCharArray());
83 } 88 }
84 89
90 /// <summary>
91 /// Создает новый экземпляр парсера, на основе текстового потока.
92 /// </summary>
93 /// <param name="reader">Текстовый поток.</param>
94 /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param>
95 public JSONParser(TextReader reader, bool dispose)
96 : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) {
97 Safe.ArgumentNotNull(reader, "reader");
98 m_scanner = new JSONScanner();
99 m_scanner.Feed(reader, dispose);
100 }
101
102 /// <summary>
103 /// Тип текущего элемента на котором стоит парсер.
104 /// </summary>
85 public JSONElementType ElementType { 105 public JSONElementType ElementType {
86 get { return m_elementType; } 106 get { return m_elementType; }
87 } 107 }
88 108
109 /// <summary>
110 /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда
111 /// пустая строка.
112 /// </summary>
89 public string ElementName { 113 public string ElementName {
90 get { return m_context.info.memberName; } 114 get { return m_context.info.memberName; }
91 } 115 }
92 116
117 /// <summary>
118 /// Значение элемента. Только для элементов типа <see cref="JSONElementType.Value"/>, для остальных <c>null</c>
119 /// </summary>
93 public object ElementValue { 120 public object ElementValue {
94 get { return m_elementValue; } 121 get { return m_elementValue; }
95 } 122 }
96 123
124 /// <summary>
125 /// Читает слеюудущий объект из потока
126 /// </summary>
127 /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns>
97 public bool Read() { 128 public bool Read() {
98 if (m_context.current == UNREACHEBLE_STATE) 129 if (m_context.current == UNREACHEBLE_STATE)
99 throw new InvalidOperationException("The parser is in invalid state"); 130 throw new InvalidOperationException("The parser is in invalid state");
100 object tokenValue; 131 object tokenValue;
101 JsonTokenType tokenType; 132 JsonTokenType tokenType;
107 switch (tokenType) { 138 switch (tokenType) {
108 case JsonTokenType.BeginObject: 139 case JsonTokenType.BeginObject:
109 Switch( 140 Switch(
110 _objectDFA, 141 _objectDFA,
111 INITIAL_STATE, 142 INITIAL_STATE,
112 new JSONParserContext { 143 new JSONParserContext {
113 memberName = m_context.info.memberName, 144 memberName = m_context.info.memberName,
114 elementContext = JSONElementContext.Object 145 elementContext = JSONElementContext.Object
115 } 146 }
116 ); 147 );
117 m_elementValue = null; 148 m_elementValue = null;
176 207
177 object ParseLiteral(string literal) { 208 object ParseLiteral(string literal) {
178 switch (literal) { 209 switch (literal) {
179 case "null": 210 case "null":
180 return null; 211 return null;
181 case "false" : 212 case "false":
182 return false; 213 return false;
183 case "true": 214 case "true":
184 return true; 215 return true;
185 default: 216 default:
186 UnexpectedToken(literal, JsonTokenType.Literal); 217 UnexpectedToken(literal, JsonTokenType.Literal);
191 void UnexpectedToken(object value, JsonTokenType tokenType) { 222 void UnexpectedToken(object value, JsonTokenType tokenType) {
192 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value)); 223 throw new ParserException(String.Format("Unexpected token {0}: '{1}'", tokenType, value));
193 } 224 }
194 225
195 226
227 /// <summary>
228 /// Признак конца потока
229 /// </summary>
196 public bool EOF { 230 public bool EOF {
197 get { 231 get {
198 return m_scanner.EOF; 232 return m_scanner.EOF;
199 } 233 }
200 } 234 }
235
236 protected virtual void Dispose(bool disposing) {
237 if (disposing) {
238 m_scanner.Dispose();
239 }
240 }
241
242 /// <summary>
243 /// Освобождает парсер и связанный с ним сканнер.
244 /// </summary>
245 public void Dispose() {
246 Dispose(true);
247 GC.SuppressFinalize(this);
248 }
249
250 ~JSONParser() {
251 Dispose(false);
252 }
201 } 253 }
202 254
203 } 255 }