private string GetString() { Consume(); var start = _position; var len = 0; while (true) { if (_isEnd) { throw JsonParserException.UnexpectedEnd(start + len); } var ch = _nextChar; if (ch == '"') { Consume(); return(new string(_charBuffer, 0, len)); } if (ch == '\\') { ch = UnEscape(); } else if (ch < ' ') { throw JsonParserException.UnexpectedError(ch, _position); } if (len >= _charBuffer.Length) { Array.Resize(ref _charBuffer, _charBuffer.Length * 2); } _charBuffer[len++] = ch; Consume(); } }
private object ParseInternal(TextReader reader, int maxDepth) { Setup(reader); var stack = new Context[maxDepth]; var depth = 0; var context = new Context(); SkipWhiteSpaces(); while (true) { var value = new InternalObject(); switch (_nextChar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': value.Number = GetNumber(); break; case 'n': CheckToken("ull"); value.Type = JsonType.Null; break; case 't': CheckToken("rue"); value.Type = JsonType.True; break; case 'f': // ReSharper disable once StringLiteralTypo CheckToken("alse"); value.Type = JsonType.False; break; case '"': value.Type = JsonType.String; value.String = GetString(); break; case '[': if (depth == maxDepth) { throw JsonParserException.TooDeepNesting(depth, _position); } Consume(); stack[depth++] = context; context = new Context { Array = new JsonArray() }; SkipWhiteSpaces(); continue; case ']': if (context.Array == null) { throw JsonParserException.UnexpectedError(_nextChar, _position); } Consume(); value.Type = JsonType.Array; value.Array = context.Array; context = stack[--depth]; break; case '{': if (depth == maxDepth) { throw JsonParserException.TooDeepNesting(depth, _position); } Consume(); stack[depth++] = context; context = new Context { Dictionary = new JsonDictionary() }; goto GetKey; case '}': if (context.Dictionary == null) { throw JsonParserException.UnexpectedError(_nextChar, _position); } Consume(); value.Type = JsonType.Object; value.Dictionary = context.Dictionary; context = stack[--depth]; break; default: if (_isEnd) { throw JsonParserException.UnexpectedEnd(_position); } throw JsonParserException.UnexpectedError(_nextChar, _position); } SkipWhiteSpaces(); // Start if (depth == 0) { if (_isEnd) { return(JsonObject.ToValue(value)); } throw JsonParserException.UnexpectedError(_nextChar, _position); } // Array if (context.Key == null) { context.Array.Add(value); if (_nextChar == ']') { continue; } if (_nextChar != ',') { throw JsonParserException.ExpectingError("',' or ']'", _position); } Consume(); SkipWhiteSpaces(); continue; } // Object context.Dictionary.Add(context.Key, value); if (_nextChar == '}') { continue; } if (_nextChar != ',') { throw JsonParserException.ExpectingError("',' or '}'", _position); } Consume(); GetKey: SkipWhiteSpaces(); if (_nextChar == '}') { continue; } if (_nextChar != '"') { throw JsonParserException.ExpectingError("string", _position); } context.Key = GetString(); SkipWhiteSpaces(); if (_nextChar != ':') { throw JsonParserException.ExpectingError("':'", _position); } Consume(); SkipWhiteSpaces(); } }