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 } |
