##// END OF EJS Templates
Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler...
Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler Any unhandled OperationCanceledException will cause the promise cancelation

File last commit:

r183:4f82e0f161c3 ref20160224
r187:dd4a3590f9c6 ref20160224
Show More
JSONScanner.cs
109 lines | 4.7 KiB | text/x-csharp | CSharpLexer
cin
DFA refactoring
r165 using System;
cin
JSON moved to Formats namespace...
r163 using System.Globalization;
cin
DFA refactoring
r165 using Implab.Automaton;
cin
rewritten the text scanner
r176 using System.Text;
using Implab.Components;
using System.IO;
cin
JSON moved to Formats namespace...
r163
cin
DFA refactoring
r165 namespace Implab.Formats.JSON {
cin
JSON moved to Formats namespace...
r163 /// <summary>
/// Сканнер (лексер), разбивающий поток символов на токены JSON.
/// </summary>
cin
rewritten the text scanner
r176 public class JSONScanner : Disposable {
readonly StringBuilder m_builder = new StringBuilder();
cin
sync
r179 readonly ScannerContext<JSONGrammar.TokenType> m_jsonContext = JSONGrammar.Instance.JsonExpression;
readonly ScannerContext<JSONGrammar.TokenType> m_stringContext = JSONGrammar.Instance.JsonStringExpression;
cin
rewritten the text scanner
r176
readonly TextScanner m_scanner;
cin
JSON moved to Formats namespace...
r163
/// <summary>
/// Создает новый экземпляр сканнера
/// </summary>
cin
rewritten the text scanner
r176 public JSONScanner(string text) {
Safe.ArgumentNotEmpty(text, "text");
m_scanner = new StringScanner(text);
}
public JSONScanner(TextReader reader, int bufferMax, int chunkSize) {
Safe.ArgumentNotNull(reader, "reader");
cin
refactoring
r177 m_scanner = new ReaderScanner(reader, bufferMax, chunkSize);
cin
JSON moved to Formats namespace...
r163 }
cin
refactoring complete, JSONParser rewritten
r180 public JSONScanner(TextReader reader) : this(reader, 1024*1024, 1024){
}
cin
JSON moved to Formats namespace...
r163 /// <summary>
/// Читает следующий лексический элемент из входных данных.
/// </summary>
/// <param name="tokenValue">Возвращает значение прочитанного токена.</param>
/// <param name="tokenType">Возвращает тип прочитанного токена.</param>
/// <returns><c>true</c> - чтение произведено успешно. <c>false</c> - достигнут конец входных данных</returns>
/// <remarks>В случе если токен не распознается, возникает исключение. Значения токенов обрабатываются, т.е.
/// в строках обрабатываются экранированные символы, числа становтся типа double.</remarks>
public bool ReadToken(out object tokenValue, out JsonTokenType tokenType) {
cin
rewritten the text scanner
r176 JSONGrammar.TokenType[] tag;
cin
fixed DFA optimization, JSON is fully functional
r183 while (m_jsonContext.Execute(m_scanner, out tag)) {
cin
rewritten the text scanner
r176 switch (tag[0]) {
cin
JSON moved to Formats namespace...
r163 case JSONGrammar.TokenType.StringBound:
tokenValue = ReadString();
tokenType = JsonTokenType.String;
break;
case JSONGrammar.TokenType.Number:
cin
rewritten the text scanner
r176 tokenValue = Double.Parse(m_scanner.GetTokenValue(), CultureInfo.InvariantCulture);
cin
JSON moved to Formats namespace...
r163 tokenType = JsonTokenType.Number;
break;
cin
fixed DFA optimization, JSON is fully functional
r183 case JSONGrammar.TokenType.Whitespace:
continue;
cin
JSON moved to Formats namespace...
r163 default:
cin
rewritten the text scanner
r176 tokenType = (JsonTokenType)tag[0];
tokenValue = m_scanner.GetTokenValue();
cin
JSON moved to Formats namespace...
r163 break;
}
return true;
}
tokenValue = null;
tokenType = JsonTokenType.None;
return false;
}
string ReadString() {
int pos = 0;
cin
refactoring
r177 var buf = new char[6]; // the buffer for unescaping chars
cin
rewritten the text scanner
r176
JSONGrammar.TokenType[] tag;
m_builder.Clear();
cin
refactoring
r177 while (m_stringContext.Execute(m_scanner, out tag)) {
cin
rewritten the text scanner
r176 switch (tag[0]) {
cin
JSON moved to Formats namespace...
r163 case JSONGrammar.TokenType.StringBound:
cin
rewritten the text scanner
r176 return m_builder.ToString();
cin
JSON moved to Formats namespace...
r163 case JSONGrammar.TokenType.UnescapedChar:
cin
rewritten the text scanner
r176 m_scanner.CopyTokenTo(m_builder);
cin
JSON moved to Formats namespace...
r163 break;
cin
rewritten the text scanner
r176 case JSONGrammar.TokenType.EscapedUnicode: // \xXXXX - unicode escape sequence
m_scanner.CopyTokenTo(buf, 0);
m_builder.Append(StringTranslator.TranslateHexUnicode(buf, 2));
cin
JSON moved to Formats namespace...
r163 pos++;
break;
cin
rewritten the text scanner
r176 case JSONGrammar.TokenType.EscapedChar: // \t - escape sequence
m_scanner.CopyTokenTo(buf, 0);
m_builder.Append(StringTranslator.TranslateEscapedChar(buf[1]));
cin
JSON moved to Formats namespace...
r163 break;
}
}
throw new ParserException("Unexpected end of data");
}
cin
refactoring
r177
protected override void Dispose(bool disposing) {
if (disposing)
Safe.Dispose(m_scanner);
base.Dispose(disposing);
}
cin
JSON moved to Formats namespace...
r163 }
}