static JsonArray DeserializeArray(JsonToken head, JsonBuffer buffer) { var list = new List <JsonValue>(); while (true) { var next = buffer.Read(); if (next.Type == JsonTokenType.RightSquareBracket) { break; } list.Add(DeserializeInternal(next, buffer)); next = buffer.Read(); if (next.Type == JsonTokenType.EOF) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxExpectation("JSON array", ']', ','), next); } else if (next.Type == JsonTokenType.RightSquareBracket) { break; } else if (next.Type != JsonTokenType.Comma) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxExpectation("JSON array", ','), next); } } return(new JsonArray(list.ToArray(), head.Line, head.Column)); }
public JsonNumber(JsonToken token) : base(token.Line, token.Column) { try { _raw = token.Value; _double = double.Parse(_raw, NumberStyles.Float); } catch (FormatException ex) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidFloatNumberFormat(_raw), ex, token.Line, token.Column); } catch (OverflowException ex) { throw new JsonDeserializerException( JsonDeserializerResource.Format_FloatNumberOverflow(_raw), ex, token.Line, token.Column); } }
void ReadLiteral(string literal) { for (int i = 1; i < literal.Length; ++i) { var next = _reader.Peek(); if (next != literal[i]) { throw new JsonDeserializerException( JsonDeserializerResource.Format_UnrecognizedLiteral(literal), _line, _column); } else { ReadNextChar(); } } var tail = _reader.Peek(); if (tail != '}' && tail != ']' && tail != ',' && tail != '\n' && tail != -1 && !IsWhitespace(tail)) { throw new JsonDeserializerException( JsonDeserializerResource.Format_IllegalTrailingCharacterAfterLiteral(tail, literal), _line, _column); } }
static JsonValue DeserializeInternal(JsonToken next, JsonBuffer buffer) { if (next.Type == JsonTokenType.EOF) { return(null); } if (next.Type == JsonTokenType.LeftSquareBracket) { return(DeserializeArray(next, buffer)); } if (next.Type == JsonTokenType.LeftCurlyBracket) { return(DeserializeObject(next, buffer)); } if (next.Type == JsonTokenType.String) { return(new JsonString(next.Value, next.Line, next.Column)); } if (next.Type == JsonTokenType.True || next.Type == JsonTokenType.False) { return(new JsonBoolean(next)); } if (next.Type == JsonTokenType.Null) { return(new JsonNull(next.Line, next.Column)); } if (next.Type == JsonTokenType.Number) { return(new JsonNumber(next)); } throw new JsonDeserializerException(JsonDeserializerResource.Format_InvalidTokenExpectation( next.Value, "'{', '[', true, false, null, JSON string, JSON number, or the end of the file"), next); }
public static JsonValue Deserialize(TextReader reader) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } var buffer = new JsonBuffer(reader); var result = DeserializeInternal(buffer.Read(), buffer); // There are still unprocessed char. The parsing is not finished. Error happened. var nextToken = buffer.Read(); if (nextToken.Type != JsonTokenType.EOF) { throw new JsonDeserializerException( JsonDeserializerResource.Format_UnfinishedJSON(nextToken.Value), nextToken); } return(result); }
public JsonToken Read() { int first; while (true) { first = ReadNextChar(); if (first == -1) { _token.Type = JsonTokenType.EOF; return(_token); } else if (!IsWhitespace(first)) { break; } } _token.Value = ((char)first).ToString(); _token.Line = _line; _token.Column = _column; if (first == '{') { _token.Type = JsonTokenType.LeftCurlyBracket; } else if (first == '}') { _token.Type = JsonTokenType.RightCurlyBracket; } else if (first == '[') { _token.Type = JsonTokenType.LeftSquareBracket; } else if (first == ']') { _token.Type = JsonTokenType.RightSquareBracket; } else if (first == ':') { _token.Type = JsonTokenType.Colon; } else if (first == ',') { _token.Type = JsonTokenType.Comma; } else if (first == '"') { _token.Type = JsonTokenType.String; _token.Value = ReadString(); } else if (first == 't') { ReadLiteral(ValueTrue); _token.Type = JsonTokenType.True; } else if (first == 'f') { ReadLiteral(ValueFalse); _token.Type = JsonTokenType.False; } else if (first == 'n') { ReadLiteral(ValueNull); _token.Type = JsonTokenType.Null; } else if ((first >= '0' && first <= '9') || first == '-') { _token.Type = JsonTokenType.Number; _token.Value = ReadNumber(first); } else { throw new JsonDeserializerException( JsonDeserializerResource.Format_IllegalCharacter(first), _token); } // JsonToken is a value type return(_token); }
static JsonObject DeserializeObject(JsonToken head, JsonBuffer buffer) { var dictionary = new Dictionary <string, JsonValue>(); // Loop through each JSON entry in the input object while (true) { var next = buffer.Read(); if (next.Type == JsonTokenType.EOF) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxExpectation("JSON object", '}'), next); } if (next.Type == JsonTokenType.Colon) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxNotExpected("JSON object", ':'), next); } else if (next.Type == JsonTokenType.RightCurlyBracket) { break; } else { if (next.Type != JsonTokenType.String) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxExpectation("JSON object member name", "JSON string"), next); } var memberName = next.Value; if (dictionary.ContainsKey(memberName)) { throw new JsonDeserializerException( JsonDeserializerResource.Format_DuplicateObjectMemberName(memberName), next); } next = buffer.Read(); if (next.Type != JsonTokenType.Colon) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxExpectation("JSON object", ':'), next); } dictionary[memberName] = DeserializeInternal(buffer.Read(), buffer); next = buffer.Read(); if (next.Type == JsonTokenType.RightCurlyBracket) { break; } else if (next.Type != JsonTokenType.Comma) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxExpectation("JSON object", ',', '}'), next); } } } return(new JsonObject(dictionary, head.Line, head.Column)); }
string ReadString() { #if NET35 _buffer = new StringBuilder(); #else _buffer.Clear(); #endif var escaped = false; while (true) { var next = ReadNextChar(); if (next == -1 || next == '\n') { throw new JsonDeserializerException( JsonDeserializerResource.JSON_OpenString, _line, _column); } else if (escaped) { if ((next == '"') || (next == '\\') || (next == '/')) { _buffer.Append((char)next); } else if (next == 'b') { // '\b' backspace _buffer.Append('\b'); } else if (next == 'f') { // '\f' form feed _buffer.Append('\f'); } else if (next == 'n') { // '\n' line feed _buffer.Append('\n'); } else if (next == 'r') { // '\r' carriage return _buffer.Append('\r'); } else if (next == 't') { // '\t' tab _buffer.Append('\t'); } else if (next == 'u') { // '\uXXXX' unicode var unicodeLine = _line; var unicodeColumn = _column; #if NET35 _codePointBuffer = new StringBuilder(4); #else _codePointBuffer.Clear(); #endif for (int i = 0; i < 4; ++i) { next = ReadNextChar(); if (next == -1) { throw new JsonDeserializerException( JsonDeserializerResource.JSON_InvalidEnd, unicodeLine, unicodeColumn); } else { _codePointBuffer[i] = (char)next; } } try { var unicodeValue = int.Parse(_codePointBuffer.ToString(), NumberStyles.HexNumber, CultureInfo.InvariantCulture); _buffer.Append((char)unicodeValue); } catch (FormatException ex) { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidUnicode(_codePointBuffer.ToString()), ex, unicodeLine, unicodeColumn); } } else { throw new JsonDeserializerException( JsonDeserializerResource.Format_InvalidSyntaxNotExpected("charactor escape", "\\" + next), _line, _column); } escaped = false; } else if (next == '\\') { escaped = true; } else if (next == '"') { break; } else { _buffer.Append((char)next); } } return(_buffer.ToString()); }