Mercurial > pub > ImplabNet
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 } |