/// <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); }
public static void Serialize(object obj, JSONObject jsonObject) { Type rootType = obj.GetType(); foreach (var member in rootType.GetMembers()) { // Iterate through all fields with JSONAttribute from root object JSONAttribute[] attrFields = (JSONAttribute[])member.GetCustomAttributes(typeof(JSONAttribute), true); foreach (JSONAttribute attrField in attrFields) { string data = attrField.data; // Get the data name of the field FieldInfo info = rootType.GetField(data); // Create a connection with the field if (info == null) // If no field next (probably wrong design of the class) { continue; } AttrEnum attrType = attrField.attrType; // Get the type of the attribute // Type is either object, item or array. switch (attrType) { case AttrEnum.AttrObject: { JSONObject jsonChild = new JSONObject(); jsonObject.Add(data, jsonChild); Serialize(info.GetValue(obj), jsonChild); break; } case AttrEnum.AttrItem: { object val = info.GetValue(obj); string result = val.ToString(); Type attrFieldType = attrField.type; if (attrFieldType == typeof(Color)) { Color col = (Color)val; result = ((int)(col.r * 255f)).ToString() + "," + ((int)(col.g * 255f)).ToString() + "," + ((int)(col.b * 255f)).ToString() + "," + ((int)(col.a * 255f)).ToString(); } else if (attrFieldType == typeof(Vector2)) { Vector2 v = (Vector2)val; result = v.x.ToString() + "," + v.y.ToString(); } else if (attrFieldType == typeof(Vector3)) { Vector3 v = (Vector3)val; result = v.x.ToString() + "," + v.y.ToString() + "," + v.z.ToString(); } else if (attrFieldType == typeof(Vector4)) { Vector4 v = (Vector4)val; result = v.x.ToString() + "," + v.y.ToString() + "," + v.z.ToString() + v.z.ToString(); } JSONValue value = new JSONValue(result); jsonObject.Add(data, value); break; } case AttrEnum.AttrArray: { object[] val = (object[])info.GetValue(obj); JSONArray jsonArray = new JSONArray(); jsonObject.Add(data, jsonArray); foreach (object v in val) { JSONObject jsonChild = new JSONObject(); Serialize(v, jsonChild); jsonArray.Add(jsonChild); } break; } } } } }
public static JSONValue GetJSONValue(object objValue) { JSONValue jsonValue = null; if (objValue == null) { //空对象进来 return(new JSONNullValue()); } Type thisType = objValue.GetType(); if (thisType == typeof(System.Int32)) { jsonValue = new JSONNumberValue(Convert.ToInt32(objValue)); } else if (thisType == typeof(System.Single)) { jsonValue = new JSONNumberValue(Convert.ToSingle(objValue)); } else if (thisType == typeof(System.Double)) { jsonValue = new JSONNumberValue(Convert.ToDouble(objValue)); } else if (thisType == typeof(System.Decimal)) { jsonValue = new JSONNumberValue(Convert.ToDecimal(objValue)); } else if (thisType == typeof(System.Byte)) { jsonValue = new JSONNumberValue(Convert.ToByte(objValue)); } else if (thisType == typeof(System.String)) { jsonValue = new JSONStringValue(Convert.ToString(objValue)); } else if (thisType == typeof(System.Boolean)) { jsonValue = new JSONBoolValue(Convert.ToBoolean(objValue)); } else if (thisType.BaseType == typeof(System.Enum)) { jsonValue = new JSONStringValue(Enum.GetName(thisType, objValue)); } else if (thisType.IsArray) { List <JSONValue> jsonValues = new List <JSONValue>(); Array arrValue = (Array)objValue; for (int x = 0; x < arrValue.Length; x++) { JSONValue jsValue = GetJSONValue(arrValue.GetValue(x)); jsonValues.Add(jsValue); } jsonValue = new JSONArray(jsonValues); } else if (thisType == typeof(System.Data.DataTable)) { //数据表的格式 System.Data.DataTable dt = new System.Data.DataTable(); } else { //其他的数据类型,尝试转换为JSONObject jsonValue = ObjectToJSONObject(objValue); } return(jsonValue); }
public JSONValue(JSONArray array) { Type = JSONValueType.Array; Array = array; }
public static JSONNode Deserialize(System.IO.BinaryReader aReader) { JSONBinaryTag type = (JSONBinaryTag)aReader.ReadByte(); switch (type) { case JSONBinaryTag.Array: { int count = aReader.ReadInt32(); JSONArray tmp = new JSONArray(); for (int i = 0; i < count; i++) { tmp.Add(Deserialize(aReader)); } return(tmp); } case JSONBinaryTag.Class: { int count = aReader.ReadInt32(); JSONClass tmp = new JSONClass(); for (int i = 0; i < count; i++) { string key = aReader.ReadString(); var val = Deserialize(aReader); tmp.Add(key, val); } return(tmp); } case JSONBinaryTag.Value: { return(new JSONData(aReader.ReadString())); } case JSONBinaryTag.IntValue: { return(new JSONData(aReader.ReadInt32())); } case JSONBinaryTag.DoubleValue: { return(new JSONData(aReader.ReadDouble())); } case JSONBinaryTag.BoolValue: { return(new JSONData(aReader.ReadBoolean())); } case JSONBinaryTag.FloatValue: { return(new JSONData(aReader.ReadSingle())); } default: { throw new Exception("Error deserializing JSON. Unknown tag: " + type); } } }