/// <summary> /// Remove the value at the given index, if it exists. /// </summary> /// <param name="index"></param> public void Remove(int index) { if (index >= 0 && index < values.Count) { values.RemoveAt(index); } else { JSONLogger.Error("index out of range: " + index + " (Expected 0 <= index < " + values.Count + ")"); } }
public JSONArray GetArray(string key) { var value = GetValue(key); if (value == null) { JSONLogger.Error(key + " == null"); return(null); } return(value.Array); }
public bool GetBoolean(string key) { var value = GetValue(key); if (value == null) { JSONLogger.Error(key + " == null"); return(false); } return(value.Boolean); }
public JSONObject GetObject(string key) { var value = GetValue(key); if (value == null) { JSONLogger.Error(key + " == null"); return(null); } return(value.Obj); }
public double GetNumber(string key) { var value = GetValue(key); if (value == null) { JSONLogger.Error(key + " == null"); return(double.NaN); } return(value.Number); }
public string GetString(string key) { var value = GetValue(key); if (value == null) { JSONLogger.Error(key + "(string) == null"); return(string.Empty); } return(value.Str); }
private static JSONObject Fail(string expected, int position) { JSONLogger.Error("Invalid json string, expecting " + expected + " at " + position); return(null); }
/// <summary> /// Attempt to parse a string into a JSONObject. /// </summary> /// <param name="jsonString"></param> /// <returns>A new JSONObject or null if parsing fails.</returns> public static JSONObject Parse(string jsonString) { if (string.IsNullOrEmpty(jsonString)) { return(null); } JSONValue currentValue = null; var keyList = new List <string>(); var state = JSONParsingState.Object; for (var startPosition = 0; startPosition < jsonString.Length; ++startPosition) { startPosition = SkipWhitespace(jsonString, startPosition); switch (state) { case JSONParsingState.Object: if (jsonString[startPosition] != '{') { return(Fail('{', startPosition)); } JSONValue newObj = new JSONObject(); if (currentValue != null) { newObj.Parent = currentValue; } currentValue = newObj; state = JSONParsingState.Key; break; case JSONParsingState.EndObject: if (jsonString[startPosition] != '}') { return(Fail('}', startPosition)); } if (currentValue.Parent == null) { return(currentValue.Obj); } switch (currentValue.Parent.Type) { case JSONValueType.Object: currentValue.Parent.Obj.values[keyList.Pop()] = new JSONValue(currentValue.Obj); break; case JSONValueType.Array: currentValue.Parent.Array.Add(new JSONValue(currentValue.Obj)); break; default: return(Fail("valid object", startPosition)); } currentValue = currentValue.Parent; state = JSONParsingState.ValueSeparator; break; case JSONParsingState.Key: if (jsonString[startPosition] == '}') { --startPosition; state = JSONParsingState.EndObject; break; } var key = ParseString(jsonString, ref startPosition); if (key == null) { return(Fail("key string", startPosition)); } keyList.Add(key); state = JSONParsingState.KeyValueSeparator; break; case JSONParsingState.KeyValueSeparator: if (jsonString[startPosition] != ':') { return(Fail(':', startPosition)); } state = JSONParsingState.Value; break; case JSONParsingState.ValueSeparator: switch (jsonString[startPosition]) { case ',': state = currentValue.Type == JSONValueType.Object ? JSONParsingState.Key : JSONParsingState.Value; break; case '}': state = JSONParsingState.EndObject; --startPosition; break; case ']': state = JSONParsingState.EndArray; --startPosition; break; default: return(Fail(", } ]", startPosition)); } break; case JSONParsingState.Value: { var c = jsonString[startPosition]; if (c == '"') { state = JSONParsingState.String; } else if (char.IsDigit(c) || c == '-') { state = JSONParsingState.Number; } else { switch (c) { case '{': state = JSONParsingState.Object; break; case '[': state = JSONParsingState.Array; break; case ']': if (currentValue.Type == JSONValueType.Array) { state = JSONParsingState.EndArray; } else { return(Fail("valid array", startPosition)); } break; case 'f': case 't': state = JSONParsingState.Boolean; break; case 'n': state = JSONParsingState.Null; break; default: return(Fail("beginning of value", startPosition)); } } --startPosition; //To re-evaluate this char in the newly selected state break; } case JSONParsingState.String: var str = ParseString(jsonString, ref startPosition); if (str == null) { return(Fail("string value", startPosition)); } switch (currentValue.Type) { case JSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new JSONValue(str); break; case JSONValueType.Array: currentValue.Array.Add(str); break; default: JSONLogger.Error("Fatal error, current JSON value not valid"); return(null); } state = JSONParsingState.ValueSeparator; break; case JSONParsingState.Number: var number = ParseNumber(jsonString, ref startPosition); if (double.IsNaN(number)) { return(Fail("valid number", startPosition)); } switch (currentValue.Type) { case JSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new JSONValue(number); break; case JSONValueType.Array: currentValue.Array.Add(number); break; default: JSONLogger.Error("Fatal error, current JSON value not valid"); return(null); } state = JSONParsingState.ValueSeparator; break; case JSONParsingState.Boolean: if (jsonString[startPosition] == 't') { if (jsonString.Length < startPosition + 4 || jsonString[startPosition + 1] != 'r' || jsonString[startPosition + 2] != 'u' || jsonString[startPosition + 3] != 'e') { return(Fail("true", startPosition)); } switch (currentValue.Type) { case JSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new JSONValue(true); break; case JSONValueType.Array: currentValue.Array.Add(new JSONValue(true)); break; default: JSONLogger.Error("Fatal error, current JSON value not valid"); return(null); } startPosition += 3; } else { if (jsonString.Length < startPosition + 5 || jsonString[startPosition + 1] != 'a' || jsonString[startPosition + 2] != 'l' || jsonString[startPosition + 3] != 's' || jsonString[startPosition + 4] != 'e') { return(Fail("false", startPosition)); } switch (currentValue.Type) { case JSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new JSONValue(false); break; case JSONValueType.Array: currentValue.Array.Add(new JSONValue(false)); break; default: JSONLogger.Error("Fatal error, current JSON value not valid"); return(null); } startPosition += 4; } state = JSONParsingState.ValueSeparator; break; case JSONParsingState.Array: if (jsonString[startPosition] != '[') { return(Fail('[', startPosition)); } JSONValue newArray = new JSONArray(); if (currentValue != null) { newArray.Parent = currentValue; } currentValue = newArray; state = JSONParsingState.Value; break; case JSONParsingState.EndArray: if (jsonString[startPosition] != ']') { return(Fail(']', startPosition)); } if (currentValue.Parent == null) { return(currentValue.Obj); } switch (currentValue.Parent.Type) { case JSONValueType.Object: currentValue.Parent.Obj.values[keyList.Pop()] = new JSONValue(currentValue.Array); break; case JSONValueType.Array: currentValue.Parent.Array.Add(new JSONValue(currentValue.Array)); break; default: return(Fail("valid object", startPosition)); } currentValue = currentValue.Parent; state = JSONParsingState.ValueSeparator; break; case JSONParsingState.Null: if (jsonString[startPosition] == 'n') { if (jsonString.Length < startPosition + 4 || jsonString[startPosition + 1] != 'u' || jsonString[startPosition + 2] != 'l' || jsonString[startPosition + 3] != 'l') { return(Fail("null", startPosition)); } switch (currentValue.Type) { case JSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new JSONValue(JSONValueType.Null); break; case JSONValueType.Array: currentValue.Array.Add(new JSONValue(JSONValueType.Null)); break; default: JSONLogger.Error("Fatal error, current JSON value not valid"); return(null); } startPosition += 3; } state = JSONParsingState.ValueSeparator; break; } } JSONLogger.Error("Unexpected end of string"); return(null); }