public static dynamic Parse(String s) { // todo. strictly speaking, this should be inserted directly into lexer // and exposed via JsonReader configuration (similarly to AllowComments and AllowSingleQuotedStrings) // however, I'm too feeble to manually tinker lexer's FSM: http://litjson.sourceforge.net/doc/manual.html#appendix.parser.lexer.table s = QuotePropertyNames(s ?? String.Empty); var reader = new JsonReader(s); if (!reader.Read()) throw new JsonException("Input string is empty"); return ReadJson(reader); }
private static JsonArray ReadArray(JsonReader reader) { (reader.Token == JsonToken.ArrayStart).AssertTrue(); var json = new JsonArray(); while (reader.Read()) { var end_of_array = false; switch (reader.Token) { case JsonToken.Int: case JsonToken.Long: case JsonToken.Double: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: case JsonToken.ObjectStart: case JsonToken.ArrayStart: json.Add(ReadJson(reader)); break; case JsonToken.ArrayEnd: end_of_array = true; break; case JsonToken.None: case JsonToken.PropertyName: case JsonToken.ObjectEnd: default: throw new JsonException(String.Format("Unexpected token {0} when reading array", reader.Token)); } if (end_of_array) break; } if (reader.Token != JsonToken.ArrayEnd) throw new JsonException(String.Format("Unexpected end of array at token {0}", reader.Token)); return json; }
private static JsonObject ReadObject(JsonReader reader) { (reader.Token == JsonToken.ObjectStart).AssertTrue(); var json = new JsonObject(); const int gief_key = 0, gief_value = 1; var state = gief_key; String key = null; while (reader.Read()) { var end_of_object = false; switch (reader.Token) { case JsonToken.PropertyName: if (state != gief_key) throw new JsonException(String.Format("Unexpected token {0} when reading object in state {1}", reader.Token, state)); key = reader.Value.AssertCast<String>(); state = gief_value; break; case JsonToken.Int: case JsonToken.Long: case JsonToken.Double: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: case JsonToken.ObjectStart: case JsonToken.ArrayStart: if (state != gief_value) throw new JsonException(String.Format("Unexpected token {0} when reading object in state {1}", reader.Token, state)); json.Add(key, ReadJson(reader)); state = gief_key; break; case JsonToken.ObjectEnd: if (state != gief_key) throw new JsonException(String.Format("Unexpected end of object in state {0}", state)); end_of_object = true; break; case JsonToken.None: case JsonToken.ArrayEnd: default: throw new JsonException(String.Format("Unexpected token {0} when reading object in state {1}", reader.Token, state)); } if (end_of_object) break; } if (reader.Token != JsonToken.ObjectEnd) throw new JsonException(String.Format("Unexpected end of object at token {0} in state {1}", reader.Token, state)); return json; }
private static JsonPrimitive ReadPrimitive(JsonReader reader) { return new JsonPrimitive(reader.Value); }
private static Json ReadJson(JsonReader reader) { switch (reader.Token) { case JsonToken.ObjectStart: return ReadObject(reader); case JsonToken.ArrayStart: return ReadArray(reader); case JsonToken.Int: case JsonToken.Long: case JsonToken.Double: case JsonToken.String: case JsonToken.Boolean: case JsonToken.Null: return ReadPrimitive(reader); case JsonToken.None: case JsonToken.PropertyName: case JsonToken.ObjectEnd: case JsonToken.ArrayEnd: default: throw new JsonException(String.Format("Unexpected token {0} when reading json", reader.Token)); } }