Mercurial > pub > ImplabNet
diff Implab/JSON/JSONParser.cs @ 59:21611344d366
code cleanup
author | cin |
---|---|
date | Wed, 18 Jun 2014 03:54:02 +0400 |
parents | 7759c80cad95 |
children | 62b440d46313 |
line wrap: on
line diff
--- a/Implab/JSON/JSONParser.cs Tue Jun 17 19:40:43 2014 +0400 +++ b/Implab/JSON/JSONParser.cs Wed Jun 18 03:54:02 2014 +0400 @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -19,12 +20,12 @@ /// <summary> /// Pull парсер JSON данных. /// </summary> - public class JSONParser : DFAutomaton<JSONParserContext> { + public class JSONParser : DFAutomaton<JSONParserContext>, IDisposable { enum MemberContext { MemberName, MemberValue - } + } static readonly EnumAlphabet<JsonTokenType> _alphabet = EnumAlphabet<JsonTokenType>.FullAlphabet; static readonly DFAStateDescriptior[] _jsonDFA; @@ -75,25 +76,55 @@ JSONElementType m_elementType; object m_elementValue; + /// <summary> + /// Создает новый парсер на основе строки, содержащей JSON + /// </summary> + /// <param name="text"></param> public JSONParser(string text) - : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty } ) { + : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) { Safe.ArgumentNotEmpty(text, "text"); m_scanner = new JSONScanner(); m_scanner.Feed(text.ToCharArray()); } + /// <summary> + /// Создает новый экземпляр парсера, на основе текстового потока. + /// </summary> + /// <param name="reader">Текстовый поток.</param> + /// <param name="dispose">Признак того, что парсер должен конролировать время жизни входного потока.</param> + public JSONParser(TextReader reader, bool dispose) + : base(_jsonDFA, INITIAL_STATE, new JSONParserContext { elementContext = JSONElementContext.None, memberName = String.Empty }) { + Safe.ArgumentNotNull(reader, "reader"); + m_scanner = new JSONScanner(); + m_scanner.Feed(reader, dispose); + } + + /// <summary> + /// Тип текущего элемента на котором стоит парсер. + /// </summary> public JSONElementType ElementType { get { return m_elementType; } } + /// <summary> + /// Имя элемента - имя свойства родительского контейнера. Для элементов массивов и корневого всегда + /// пустая строка. + /// </summary> public string ElementName { get { return m_context.info.memberName; } } + /// <summary> + /// Значение элемента. Только для элементов типа <see cref="JSONElementType.Value"/>, для остальных <c>null</c> + /// </summary> public object ElementValue { get { return m_elementValue; } } + /// <summary> + /// Читает слеюудущий объект из потока + /// </summary> + /// <returns><c>true</c> - операция чтения прошла успешно, <c>false</c> - конец данных</returns> public bool Read() { if (m_context.current == UNREACHEBLE_STATE) throw new InvalidOperationException("The parser is in invalid state"); @@ -109,7 +140,7 @@ Switch( _objectDFA, INITIAL_STATE, - new JSONParserContext { + new JSONParserContext { memberName = m_context.info.memberName, elementContext = JSONElementContext.Object } @@ -178,7 +209,7 @@ switch (literal) { case "null": return null; - case "false" : + case "false": return false; case "true": return true; @@ -193,11 +224,32 @@ } + /// <summary> + /// Признак конца потока + /// </summary> public bool EOF { get { return m_scanner.EOF; } } + + protected virtual void Dispose(bool disposing) { + if (disposing) { + m_scanner.Dispose(); + } + } + + /// <summary> + /// Освобождает парсер и связанный с ним сканнер. + /// </summary> + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~JSONParser() { + Dispose(false); + } } }