/// <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;
                    }
                    }
                }
            }
        }
示例#3
0
        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;
 }
示例#5
0
        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);
            }
            }
        }