/// <summary> /// Construct a copy of the tfxJSONValue given as a parameter /// </summary> /// <param name="value"></param> public tfxJSONValue(tfxJSONValue value) { Type = value.Type; switch (Type) { case tfxJSONValueType.String: Str = value.Str; break; case tfxJSONValueType.Boolean: Boolean = value.Boolean; break; case tfxJSONValueType.Number: Number = value.Number; break; case tfxJSONValueType.Object: if (value.Obj != null) { Obj = new tfxJSONObject(value.Obj); } break; case tfxJSONValueType.Array: Array = new tfxJSONArray(value.Array); break; } }
/// <summary> /// Construct a new array and copy each value from the given array into the new one /// </summary> /// <param name="array"></param> public tfxJSONArray(tfxJSONArray array) { values = new List <tfxJSONValue>(); foreach (var v in array.values) { values.Add(new tfxJSONValue(v)); } }
/// <summary> /// Concatenate two tfxJSONArrays /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> /// <returns>A new tfxJSONArray that is the result of adding all of the right-hand side array's values to the left-hand side array.</returns> public static tfxJSONArray operator +(tfxJSONArray lhs, tfxJSONArray rhs) { var result = new tfxJSONArray(lhs); foreach (var value in rhs.values) { result.Add(value); } return(result); }
/// <summary> /// Attempt to parse a string into a tfxJSONObject. /// </summary> /// <param name="jsonString"></param> /// <returns>A new tfxJSONObject or null if parsing fails.</returns> public static tfxJSONObject Parse(string jsonString, bool force_hide_errors = false) { if (string.IsNullOrEmpty(jsonString)) { return(null); } tfxJSONValue 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, force_hide_errors)); } tfxJSONValue newObj = new tfxJSONObject(); if (currentValue != null) { newObj.Parent = currentValue; } currentValue = newObj; state = JSONParsingState.Key; break; case JSONParsingState.EndObject: if (jsonString[startPosition] != '}') { return(Fail('}', startPosition, force_hide_errors)); } if (currentValue.Parent == null) { return(currentValue.Obj); } switch (currentValue.Parent.Type) { case tfxJSONValueType.Object: currentValue.Parent.Obj.values[keyList.Pop()] = new tfxJSONValue(currentValue.Obj); break; case tfxJSONValueType.Array: currentValue.Parent.Array.Add(new tfxJSONValue(currentValue.Obj)); break; default: return(Fail("valid object", startPosition, force_hide_errors)); } currentValue = currentValue.Parent; state = JSONParsingState.ValueSeparator; break; case JSONParsingState.Key: if (jsonString[startPosition] == '}') { --startPosition; state = JSONParsingState.EndObject; break; } var key = ParseString(jsonString, ref startPosition, force_hide_errors); if (key == null) { return(Fail("key string", startPosition, force_hide_errors)); } keyList.Add(key); state = JSONParsingState.KeyValueSeparator; break; case JSONParsingState.KeyValueSeparator: if (jsonString[startPosition] != ':') { return(Fail(':', startPosition, force_hide_errors)); } state = JSONParsingState.Value; break; case JSONParsingState.ValueSeparator: switch (jsonString[startPosition]) { case ',': state = currentValue.Type == tfxJSONValueType.Object ? JSONParsingState.Key : JSONParsingState.Value; break; case '}': state = JSONParsingState.EndObject; --startPosition; break; case ']': state = JSONParsingState.EndArray; --startPosition; break; default: return(Fail(", } ]", startPosition, force_hide_errors)); } 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 == tfxJSONValueType.Array) { state = JSONParsingState.EndArray; } else { return(Fail("valid array", startPosition, force_hide_errors)); } break; case 'f': case 't': state = JSONParsingState.Boolean; break; case 'n': state = JSONParsingState.Null; break; default: return(Fail("beginning of value", startPosition, force_hide_errors)); } } --startPosition; //To re-evaluate this char in the newly selected state break; } case JSONParsingState.String: var str = ParseString(jsonString, ref startPosition, force_hide_errors); if (str == null) { return(Fail("string value", startPosition, force_hide_errors)); } switch (currentValue.Type) { case tfxJSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new tfxJSONValue(str); break; case tfxJSONValueType.Array: currentValue.Array.Add(str); break; default: if (!force_hide_errors) { 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, force_hide_errors)); } switch (currentValue.Type) { case tfxJSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new tfxJSONValue(number); break; case tfxJSONValueType.Array: currentValue.Array.Add(number); break; default: if (!force_hide_errors) { 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, force_hide_errors)); } switch (currentValue.Type) { case tfxJSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new tfxJSONValue(true); break; case tfxJSONValueType.Array: currentValue.Array.Add(new tfxJSONValue(true)); break; default: if (!force_hide_errors) { 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, force_hide_errors)); } switch (currentValue.Type) { case tfxJSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new tfxJSONValue(false); break; case tfxJSONValueType.Array: currentValue.Array.Add(new tfxJSONValue(false)); break; default: if (!force_hide_errors) { 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, force_hide_errors)); } tfxJSONValue newArray = new tfxJSONArray(); if (currentValue != null) { newArray.Parent = currentValue; } currentValue = newArray; state = JSONParsingState.Value; break; case JSONParsingState.EndArray: if (jsonString[startPosition] != ']') { return(Fail(']', startPosition, force_hide_errors)); } if (currentValue.Parent == null) { return(currentValue.Obj); } switch (currentValue.Parent.Type) { case tfxJSONValueType.Object: currentValue.Parent.Obj.values[keyList.Pop()] = new tfxJSONValue(currentValue.Array); break; case tfxJSONValueType.Array: currentValue.Parent.Array.Add(new tfxJSONValue(currentValue.Array)); break; default: return(Fail("valid object", startPosition, force_hide_errors)); } 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, force_hide_errors)); } switch (currentValue.Type) { case tfxJSONValueType.Object: currentValue.Obj.values[keyList.Pop()] = new tfxJSONValue(tfxJSONValueType.Null); break; case tfxJSONValueType.Array: currentValue.Array.Add(new tfxJSONValue(tfxJSONValueType.Null)); break; default: if (!force_hide_errors) { JSONLogger.Error("Fatal error, current JSON value not valid"); } return(null); } startPosition += 3; } state = JSONParsingState.ValueSeparator; break; } } if (!force_hide_errors) { JSONLogger.Error("Unexpected end of string"); } return(null); }
public tfxJSONValue(tfxJSONArray array) { Type = tfxJSONValueType.Array; Array = array; }