Example #1
0
        public static void RegisterImporter <TJson, TValue> (
            ImporterFunc <TJson, TValue> importer)
        {
            ImporterFunc importer_wrapper =
                delegate(object input) {
                return(importer((TJson)input));
            };

            RegisterImporter(custom_importers_table, typeof(TJson),
                             typeof(TValue), importer_wrapper);
        }
Example #2
0
        private static void RegisterImporter(
            IDictionary <Type, IDictionary <Type, ImporterFunc> > table,
            Type json_type, Type value_type, ImporterFunc importer)
        {
            if (!table.ContainsKey(json_type))
            {
                table.Add(json_type, new Dictionary <Type, ImporterFunc> ());
            }

            table[json_type][value_type] = importer;
        }
Example #3
0
    public static Recording ParseRecording(string jsonRecording)
    {
        ImporterFunc <double, float> importer = delegate(double input) {
            return((float)input);
        };

        JsonMapper.RegisterImporter <double, float>(importer);          // let float values be parsed
        Recording rec = JsonMapper.ToObject <Recording>(jsonRecording);

        JsonMapper.UnregisterImporters();
        return(rec);
    }
Example #4
0
        private static void RegisterBaseImporters()
        {
            ImporterFunc importer = delegate(object input) {
                return(Convert.ToByte((int)input));
            };

            RegisterImporter(base_importers_table, typeof(int), typeof(byte), importer);
            importer = delegate(object input) {
                return(Convert.ToUInt64((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(ulong), importer);
            importer = delegate(object input) {
                return(Convert.ToSByte((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(sbyte), importer);
            importer = delegate(object input) {
                return(Convert.ToInt16((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(short), importer);
            importer = delegate(object input) {
                return(Convert.ToUInt16((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(ushort), importer);
            importer = delegate(object input) {
                return(Convert.ToUInt32((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(uint), importer);
            importer = delegate(object input) {
                return(Convert.ToSingle((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(float), importer);
            importer = delegate(object input) {
                return(Convert.ToDouble((int)input));
            };
            RegisterImporter(base_importers_table, typeof(int), typeof(double), importer);
            importer = delegate(object input) {
                return(Convert.ToDecimal((double)input));
            };
            RegisterImporter(base_importers_table, typeof(double), typeof(decimal), importer);
            importer = delegate(object input) {
                return(Convert.ToUInt32((long)input));
            };
            RegisterImporter(base_importers_table, typeof(long), typeof(uint), importer);
            importer = delegate(object input) {
                return(Convert.ToChar((string)input));
            };
            RegisterImporter(base_importers_table, typeof(string), typeof(char), importer);
            importer = delegate(object input) {
                return(Convert.ToDateTime((string)input, datetime_format));
            };
            RegisterImporter(base_importers_table, typeof(string), typeof(DateTime), importer);
        }
Example #5
0
        public static void AddExtentds()
        {
            // Rect exporter
            ExporterFunc <UnityEngine.Rect> rectExporter = new ExporterFunc <UnityEngine.Rect>(JsonExtend.rectexp);

            JsonMapper.RegisterExporter <UnityEngine.Rect>(rectExporter);

            // UnityEngine.Color exporter
            ExporterFunc <UnityEngine.Color> colorExporter = new ExporterFunc <UnityEngine.Color>(JsonExtend.colorexp);

            JsonMapper.RegisterExporter <UnityEngine.Color>(colorExporter);

            // UnityEngine.GameObject exporter
            ExporterFunc <UnityEngine.GameObject> gameObjectExporter = new ExporterFunc <UnityEngine.GameObject>(JsonExtend.gameObjexp);

            JsonMapper.RegisterExporter <UnityEngine.GameObject>(gameObjectExporter);

            // UnityEngine.Quaternion exporter
            ExporterFunc <UnityEngine.Quaternion> quaternionExporter = new ExporterFunc <UnityEngine.Quaternion>(JsonExtend.quaternionexp);

            JsonMapper.RegisterExporter <UnityEngine.Quaternion>(quaternionExporter);

            // UnityEngine.Object exporter
            ExporterFunc <UnityEngine.Object> objectExporter = new ExporterFunc <UnityEngine.Object>(JsonExtend.objectexp);

            JsonMapper.RegisterExporter <UnityEngine.Object>(objectExporter);

            // Vector4 exporter
            ExporterFunc <Vector4> vector4Exporter = new ExporterFunc <Vector4>(JsonExtend.vector4exp);

            JsonMapper.RegisterExporter <Vector4>(vector4Exporter);

            // Vector3 exporter
            ExporterFunc <Vector3> vector3Exporter = new ExporterFunc <Vector3>(JsonExtend.vector3exp);

            JsonMapper.RegisterExporter <Vector3>(vector3Exporter);

            // Vector2 exporter
            ExporterFunc <Vector2> vector2Exporter = new ExporterFunc <Vector2>(JsonExtend.vector2exp);

            JsonMapper.RegisterExporter <Vector2>(vector2Exporter);

            // float to double
            ExporterFunc <float> float2double = new ExporterFunc <float>(JsonExtend.float2double);

            JsonMapper.RegisterExporter <float>(float2double);

            // double to float
            ImporterFunc <double, Single> double2float = new ImporterFunc <double, Single>(JsonExtend.double2float);

            JsonMapper.RegisterImporter <double, Single>(double2float);
        }
Example #6
0
        private static void RegisterImporter(
            IDictionary <Type, IDictionary <Type, ImporterFunc> > table,
            Type json_type, Type value_type, ImporterFunc importer)
        {
            if (value_type.IsAssignableFrom(json_type))
            {
                return;  // no need
            }
            if (!table.ContainsKey(json_type))
            {
                table.Add(json_type, new Dictionary <Type, ImporterFunc> ());
            }

            table[json_type][value_type] = importer;
        }
Example #7
0
        public static object ReadBaseTypeProperty(Type value_type, object value)
        {
            Type json_type = value.GetType();

            if (value_type.IsAssignableFrom(json_type))
            {
                return(value);
            }

            // If there's a custom importer that fits, use it
            if (custom_importers_table.ContainsKey(json_type) &&
                custom_importers_table[json_type].ContainsKey(
                    value_type))
            {
                ImporterFunc importer =
                    custom_importers_table[json_type][value_type];
                return(importer(value));
            }

            // Maybe there's a base importer that works
            if (base_importers_table.ContainsKey(json_type) &&
                base_importers_table[json_type].ContainsKey(
                    value_type))
            {
                ImporterFunc importer =
                    base_importers_table[json_type][value_type];
                return(importer(value));
            }

            // Maybe it's an enum
            if (value_type.IsEnum)
            {
                return(Enum.ToObject(value_type, value));
            }

            // Try using an implicit conversion operator
            MethodInfo conv_op = GetConvOp(value_type, json_type);

            if (conv_op != null)
            {
                return(conv_op.Invoke(null,
                                      new object[] { value }));
            }

            throw new JsonException(String.Format(
                                        "Can't assign value '{0}' (type {1}) to type {2}",
                                        value, json_type, value_type));
        }
Example #8
0
        public static void AddExtentds()
        {
            // Vector4 exporter
            ExporterFunc <Vector4> vector4Exporter = new ExporterFunc <Vector4>(JsonExtend.vector4exp);

            JsonMapper.RegisterExporter <Vector4>(vector4Exporter);

            // Vector3 exporter
            ExporterFunc <Vector3> vector3Exporter = new ExporterFunc <Vector3>(JsonExtend.vector3exp);

            JsonMapper.RegisterExporter <Vector3>(vector3Exporter);

            // Vector2 exporter
            ExporterFunc <Vector2> vector2Exporter = new ExporterFunc <Vector2>(JsonExtend.vector2exp);

            JsonMapper.RegisterExporter <Vector2>(vector2Exporter);

            // float to double
            ExporterFunc <float> float2double = new ExporterFunc <float>(JsonExtend.float2double);

            JsonMapper.RegisterExporter <float>(float2double);

            // double to float
            ImporterFunc <double, Single> double2float = new ImporterFunc <double, Single>(JsonExtend.double2float);

            JsonMapper.RegisterImporter <double, Single>(double2float);

            // string to vector3
            ImporterFunc <string, Vector3> string2vector3 = new ImporterFunc <string, Vector3>(JsonExtend.string2vector3);

            JsonMapper.RegisterImporter <string, Vector3>(string2vector3);

            // string to int
            ImporterFunc <string, int> string2int = new ImporterFunc <string, int>(JsonExtend.string2int);

            JsonMapper.RegisterImporter <string, int>(string2int);

            JsonMapper.RegisterImporter <int, long>((int value) => {
                return((long)value);
            });

            JsonMapper.RegisterImporter <uint, Int64>((uint value) => {
                return((Int64)value);
            });
        }
Example #9
0
        public void CustomImporterTest()
        {
            // Custom DateTime importer that only uses the Year value
            // (assuming January 1st of that year)
            ImporterFunc <long, DateTime> importer =
                delegate(long obj) {
                return(new DateTime((int)obj, 1, 1));
            };

            JsonMapper.RegisterImporter <long, DateTime> (importer);

            string json = "{ \"TestDateTime\" : 1980 }";

            ValueTypesTest sample =
                JsonMapper.ToObject <ValueTypesTest> (json);

            JsonMapper.UnregisterImporters();

            Assert.AreEqual(new DateTime(1980, 1, 1), sample.TestDateTime);
        }
Example #10
0
        private static void RegisterBaseImporters()
        {
            ImporterFunc importer1 = (ImporterFunc)(input => (object)Convert.ToByte((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(byte), importer1);
            ImporterFunc importer2 = (ImporterFunc)(input => (object)Convert.ToUInt64((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(ulong), importer2);
            ImporterFunc importer3 = (ImporterFunc)(input => (object)Convert.ToSByte((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(sbyte), importer3);
            ImporterFunc importer4 = (ImporterFunc)(input => (object)Convert.ToInt16((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(short), importer4);
            ImporterFunc importer5 = (ImporterFunc)(input => (object)Convert.ToUInt16((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(ushort), importer5);
            ImporterFunc importer6 = (ImporterFunc)(input => (object)Convert.ToUInt32((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(uint), importer6);
            ImporterFunc importer7 = (ImporterFunc)(input => (object)Convert.ToSingle((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(float), importer7);
            ImporterFunc importer8 = (ImporterFunc)(input => (object)Convert.ToDouble((int)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(int), typeof(double), importer8);
            ImporterFunc importer9 = (ImporterFunc)(input => (object)Convert.ToDecimal((double)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(double), typeof(Decimal), importer9);
            ImporterFunc importer10 = (ImporterFunc)(input => (object)Convert.ToUInt32((long)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(long), typeof(uint), importer10);
            ImporterFunc importer11 = (ImporterFunc)(input => (object)Convert.ToChar((string)input));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(string), typeof(char), importer11);
            ImporterFunc importer12 = (ImporterFunc)(input => (object)Convert.ToDateTime((string)input, JsonMapper.datetime_format));

            JsonMapper.RegisterImporter(JsonMapper.base_importers_table, typeof(string), typeof(DateTime), importer12);
        }
Example #11
0
        public static void AddExtensions()
        {
            // Vector4 exporter
            ExporterFunc <Vector4> vector4Exporter = Vector4Exp;

            JsonMapper.RegisterExporter(vector4Exporter);

            // Vector3 exporter
            ExporterFunc <Vector3> vector3Exporter = Vector3Exp;

            JsonMapper.RegisterExporter(vector3Exporter);

            // Vector2 exporter
            ExporterFunc <Vector2> vector2Exporter = Vector2Exp;

            JsonMapper.RegisterExporter(vector2Exporter);

            // Quaternion exporter
            ExporterFunc <Quaternion> quaternionExporter = QuaternionExp;

            JsonMapper.RegisterExporter(quaternionExporter);

            // Color exporter
            ExporterFunc <Color> colorExporter = ColorExp;

            JsonMapper.RegisterExporter(colorExporter);

            // float to double
            ExporterFunc <float> float2Double = Float2Double;

            JsonMapper.RegisterExporter(float2Double);

            // double to float
            ImporterFunc <double, Single> double2Float = Double2Float;

            JsonMapper.RegisterImporter(double2Float);
        }
Example #12
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            //ILRuntime doesn't support nullable valuetype
            Type underlying_type = inst_type;//Nullable.GetUnderlyingType(inst_type);
            Type value_type      = inst_type;

            if (reader.Token == JsonToken.Null)
            {
                if (inst_type.IsClass || underlying_type != null)
                {
                    return(null);
                }

                throw new JsonException(String.Format(
                                            "Can't assign null to an instance of type {0}",
                                            inst_type));
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();
                var  vt        = value_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)value_type).CLRType.TypeForCLR : value_type;

                if (vt.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }
                if (vt is ILRuntime.Reflection.ILRuntimeType && ((ILRuntime.Reflection.ILRuntimeType)vt).ILType.IsEnum)
                {
                    if (json_type == typeof(int) || json_type == typeof(long) || json_type == typeof(short) || json_type == typeof(byte))
                    {
                        return(reader.Value);
                    }
                }
                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        vt))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][vt];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        vt))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][vt];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (vt.IsEnum)
                {
                    return(Enum.ToObject(vt, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(vt, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }
                    var rt = elem_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)elem_type).RealType : elem_type;
                    if (elem_type is ILRuntime.Reflection.ILRuntimeType && ((ILRuntime.Reflection.ILRuntimeType)elem_type).ILType.IsEnum)
                    {
                        item = (int)item;
                    }
                    else
                    {
                        item = rt.CheckCLRTypes(item);
                    }
                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(value_type);
                ObjectMetadata t_data = object_metadata[value_type];
                if (value_type is ILRuntime.Reflection.ILRuntimeType)
                {
                    instance = ((ILRuntime.Reflection.ILRuntimeType)value_type).ILType.Instantiate();
                }
                else
                {
                    instance = Activator.CreateInstance(value_type);
                }
                bool isIntKey = t_data.IsDictionary && value_type.GetGenericArguments()[0] == typeof(int);

                var hotArguments = (inst_type as ILRuntimeWrapperType)?.CLRType.GenericArguments
                                   .Select(i => i.Value)
                                   .ToList()
                                   .FindAll(t => !(t is CLRType));

                var valid = hotArguments?.Count == 1;

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string key = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(key))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[key];

                        if (prop_data.IsField)
                        {
                            var val      = ((FieldInfo)prop_data.Info);
                            var realType = prop_data.Type;
                            if (val.FieldType.ToString() == "ILRuntime.Runtime.Intepreter.ILTypeInstance")
                            {
                                //支持一下本地泛型<热更类型>,这种属于CLRType,会new ILTypeIns导致错误
                                //这里要做的就是把泛型参数里面的热更类型获取出来
                                //但如果有超过1个热更类型在参数里,就没办法判断哪个是这个字段的ILTypeIns了,所以只能1个
                                if (!valid)
                                {
                                    throw new NotSupportedException("仅支持解析1个热更类型做泛型参数的本地泛型类");
                                }

                                realType = hotArguments[0].ReflectionType;
                            }

                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(realType, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            var val      = ((PropertyInfo)prop_data.Info);
                            var realType = prop_data.Type;
                            if (val.PropertyType.ToString() == "ILRuntime.Runtime.Intepreter.ILTypeInstance")
                            {
                                if (!valid)
                                {
                                    throw new NotSupportedException("仅支持解析1个热更类型做泛型参数的本地泛型类");
                                }

                                realType = hotArguments[0].ReflectionType;
                            }

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(realType, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(realType, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(String.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, key));
                            }
                            else
                            {
                                ReadSkip(reader);
                                continue;
                            }
                        }

                        var    dict      = ((IDictionary)instance);
                        var    elem_type = t_data.ElementType;
                        object readValue = ReadValue(elem_type, reader);
                        var    rt        = t_data.ElementType is ILRuntime.Reflection.ILRuntimeWrapperType
                            ? ((ILRuntime.Reflection.ILRuntimeWrapperType)t_data.ElementType).RealType
                            : t_data.ElementType;
                        //value 是枚举的情况没处理,毕竟少
                        if (isIntKey)
                        {
                            var          dictValueType = value_type.GetGenericArguments()[1];
                            IConvertible convertible   = dictValueType as IConvertible;
                            if (convertible == null)
                            {
                                //自定义类型扩展
                                if (dictValueType == typeof(double)) //CheckCLRTypes() 没有double,也可以修改ilruntime源码实现
                                {
                                    var v = Convert.ChangeType(readValue.ToString(), dictValueType);
                                    dict.Add(Convert.ToInt32(key), v);
                                }
                                else
                                {
                                    readValue = rt.CheckCLRTypes(readValue);
                                    dict.Add(Convert.ToInt32(key), readValue);
                                    // throw new JsonException (String.Format("The type {0} doesn't not support",dictValueType));
                                }
                            }
                            else
                            {
                                var v = Convert.ChangeType(readValue, dictValueType);
                                dict.Add(Convert.ToInt32(key), v);
                            }
                        }
                        else
                        {
                            readValue = rt.CheckCLRTypes(readValue);
                            dict.Add(key, readValue);
                        }
                    }
                }
            }

            return(instance);
        }
Example #13
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
            Type value_type      = underlying_type ?? inst_type;

            if (reader.Token == JsonToken.Null)
            {
                if (inst_type.IsClass || underlying_type != null)
                {
                    return(null);
                }

                throw new JsonException(string.Format(
                                            "Can't assign null to an instance of type {0}",
                                            inst_type));
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (value_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (value_type.IsEnum)
                {
                    return(Enum.ToObject(value_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(value_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new[] { reader.Value }));
                }

                // No luck
                throw new JsonException(string.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type + "_" + reader.Value.ToString()));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                // If there's a custom importer that fits, use it
                ImporterFunc importer = null;
                if (custom_importers_table.ContainsKey(typeof(JsonData)) &&
                    custom_importers_table[typeof(JsonData)].ContainsKey(
                        inst_type))
                {
                    importer  = custom_importers_table[typeof(JsonData)][inst_type];
                    inst_type = typeof(JsonData);
                }

                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(string.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }

                if (importer != null)
                {
                    instance = importer(instance);
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                bool   done     = false;
                string property = null;
                reader.Read();
                if (reader.Token == JsonToken.ObjectEnd)
                {
                    done = true;
                }
                else
                {
                    property = (string)reader.Value;
                    if (reader.TypeHinting && property == reader.HintTypeName)
                    {
                        reader.Read();
                        string typeName = (string)reader.Value;
                        reader.Read();
                        if ((string)reader.Value == reader.HintValueName)
                        {
                            value_type = Type.GetType(typeName);
                            object value = ReadValue(value_type, reader);
                            reader.Read();
                            if (reader.Token != JsonToken.ObjectEnd)
                            {
                                throw new JsonException("Invalid type hinting object, has too many properties");
                            }
                            return(value);
                        }
                        throw new JsonException("Expected __value__ property for type hinting but instead got " +
                                                reader.Value);
                    }
                }

                // If there's a custom importer that fits, use to create a JsonData type instead.
                // Once the object is deserialzied, it will be invoked to create the actual converted object.
                ImporterFunc importer = null;
                if (custom_importers_table.ContainsKey(typeof(JsonData)) &&
                    custom_importers_table[typeof(JsonData)].ContainsKey(
                        value_type))
                {
                    importer   = custom_importers_table[typeof(JsonData)][value_type];
                    value_type = typeof(JsonData);
                }

                AddObjectMetadata(value_type);
                ObjectMetadata t_data = object_metadata[value_type];

                instance = CreateInstance(value_type);

                bool firstRun = true;
                while (!done)
                {
                    if (firstRun)
                    {
                        firstRun = false;
                    }
                    else
                    {
                        reader.Read();
                        if (reader.Token == JsonToken.ObjectEnd)
                        {
                            break;
                        }
                        property = (string)reader.Value;
                    }
                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        // Don't deserialize a field or property that has a JsonIgnore attribute with deserialization usage.
                        if ((prop_data.Ignore & JsonIgnoreWhen.Deserializing) > 0)
                        {
                            ReadSkip(reader);
                            continue;
                        }

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(string.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, property));
                            }
                            ReadSkip(reader);
                            continue;
                        }

                        ((IDictionary)instance).Add(
                            property, ReadValue(
                                t_data.ElementType, reader));
                    }
                }

                if (importer != null)
                {
                    instance = importer(instance);
                }
            }

            return(instance);
        }
Example #14
0
 public static void RegisterImporter(Type TJson, Type TValue, ImporterFunc importer)
 {
     JsonMapper.RegisterImporter(JsonMapper.custom_importers_table, TJson, TValue, importer);
 }
Example #15
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            if (reader.Token == JsonToken.Null)
            {
                if (!inst_type.IsClass)
                {
                    throw new JsonException(String.Format(
                                                "Can't assign null to an instance of type {0}",
                                                inst_type));
                }

                return(null);
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (inst_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (inst_type.IsEnum)
                {
                    return(Enum.ToObject(inst_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(inst_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // 値が数値、型が文字列型の場合、文字列型に変換して返す
                if (inst_type == typeof(System.String))
                {
                    if (json_type == typeof(System.Int32) ||
                        json_type == typeof(System.Int64) ||
                        json_type == typeof(System.Single) ||
                        json_type == typeof(System.Double))
                    {
                        return(String.Format("{0}", reader.Value));
                    }
                }

                // 値がint、型がlongの場合、longに変換して返す
                if (json_type == typeof(System.Int32) && inst_type == typeof(System.Int64))
                {
                    return(Int64.Parse(String.Format("{0}", reader.Value), 0));
                }

                // 値が String, 型が数値の場合、数値に変換して返す。
                if (json_type == typeof(System.String))
                {
                    string strVal = (string)reader.Value;

                    try{
                        if (inst_type == typeof(System.Int32))
                        {
                            return(Int32.Parse(strVal));
                        }
                        else if (inst_type == typeof(System.Int64))
                        {
                            return(Int64.Parse(strVal));
                        }
                        else if (inst_type == typeof(System.Single))
                        {
                            return(Single.Parse(strVal));
                        }
                        else if (inst_type == typeof(System.Double))
                        {
                            return(Double.Parse(strVal));
                        }
                    }
                    catch (Exception e)
                    {
                        // 数値へのパースに失敗したので、変換処理を行わないで、次に進む
                    }
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(inst_type);
                ObjectMetadata t_data = object_metadata[inst_type];

                instance = Activator.CreateInstance(inst_type);

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(String.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, property));
                            }
                            else
                            {
                                ReadSkip(reader);
                                continue;
                            }
                        }

                        ((IDictionary)instance).Add(
                            property, ReadValue(
                                t_data.ElementType, reader));
                    }
                }
            }

            return(instance);
        }
Example #16
0
 public static void RegisterImporter <TJson, TValue>(ImporterFunc <TJson, TValue> importer)
 {
     RegisterImporter(custom_importers_table, typeof(TJson), typeof(TValue), input => importer((TJson)input));
 }
Example #17
0
 private static void RegisterImporter(IDictionary table, Type json_type, Type value_type, ImporterFunc importer)
 {
     if (!table.Contains(json_type))
     {
         table.Add(json_type, new Hashtable());
     }
     (table[json_type] as IDictionary)[value_type] = importer;
 }
Example #18
0
        /// <summary>
        ///     Registers the importer.
        /// </summary>
        /// <typeparam name="TJson">The type of the json.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="importer">The importer.</param>
        public void RegisterImporter <TJson, TValue>(ImporterFunc <TJson, TValue> importer)
        {
            ImporterFunc importerWrapper = input => importer((TJson)input);

            RegisterImporter(_customImportersTable, typeof(TJson), typeof(TValue), importerWrapper);
        }
Example #19
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();
            object result;

            if (reader.Token == JsonToken.ArrayEnd)
            {
                result = null;
            }
            else if (reader.Token == JsonToken.Null)
            {
                if (!inst_type.IsClass)
                {
                    JsonException.Throw(new JsonException(string.Format("Can't assign null to an instance of type {0}", inst_type)));
                }
                result = null;
            }
            else if (reader.Token == JsonToken.Double || reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean)
            {
                Type type = reader.Value.GetType();
                if (inst_type.IsAssignableFrom(type))
                {
                    result = reader.Value;
                }
                else if (JsonMapper.custom_importers_table.ContainsKey(type) && JsonMapper.custom_importers_table[type].ContainsKey(inst_type))
                {
                    ImporterFunc importerFunc = JsonMapper.custom_importers_table[type][inst_type];
                    result = importerFunc(reader.Value);
                }
                else if (JsonMapper.base_importers_table.ContainsKey(type) && JsonMapper.base_importers_table[type].ContainsKey(inst_type))
                {
                    ImporterFunc importerFunc = JsonMapper.base_importers_table[type][inst_type];
                    result = importerFunc(reader.Value);
                }
                else if (inst_type.IsEnum)
                {
                    result = Enum.ToObject(inst_type, reader.Value);
                }
                else
                {
                    MethodInfo convOp = JsonMapper.GetConvOp(inst_type, type);
                    if (convOp == null)
                    {
                        JsonException.Throw(new JsonException(string.Format("Can't assign value '{0}' (type {1}) to type {2}", reader.Value, type, inst_type)));
                    }
                    result = convOp.Invoke(null, new object[]
                    {
                        reader.Value
                    });
                }
            }
            else
            {
                object obj = null;
                if (reader.Token == JsonToken.ArrayStart)
                {
                    JsonMapper.AddArrayMetadata(inst_type);
                    ArrayMetadata arrayMetadata = JsonMapper.array_metadata[inst_type];
                    if (!arrayMetadata.IsArray && !arrayMetadata.IsList)
                    {
                        JsonException.Throw(new JsonException(string.Format("Type {0} can't act as an array", inst_type)));
                    }
                    IList list;
                    Type  elementType;
                    if (!arrayMetadata.IsArray)
                    {
                        list        = (IList)Activator.CreateInstance(inst_type);
                        elementType = arrayMetadata.ElementType;
                    }
                    else
                    {
                        list        = new ArrayList();
                        elementType = inst_type.GetElementType();
                    }
                    while (true)
                    {
                        object value = JsonMapper.ReadValue(elementType, reader);
                        if (reader.Token == JsonToken.ArrayEnd)
                        {
                            break;
                        }
                        list.Add(value);
                    }
                    if (arrayMetadata.IsArray)
                    {
                        int count = list.Count;
                        obj = Array.CreateInstance(elementType, count);
                        for (int i = 0; i < count; i++)
                        {
                            ((Array)obj).SetValue(list[i], i);
                        }
                    }
                    else
                    {
                        obj = list;
                    }
                }
                else if (reader.Token == JsonToken.ObjectStart)
                {
                    JsonMapper.AddObjectMetadata(inst_type);
                    ObjectMetadata objectMetadata = JsonMapper.object_metadata[inst_type];
                    obj = Activator.CreateInstance(inst_type);
                    string text;
                    while (true)
                    {
                        reader.Read();
                        if (reader.Token == JsonToken.ObjectEnd)
                        {
                            break;
                        }
                        text = (string)reader.Value;
                        if (objectMetadata.Properties.ContainsKey(text))
                        {
                            PropertyMetadata propertyMetadata = objectMetadata.Properties[text];
                            if (propertyMetadata.IsField)
                            {
                                ((FieldInfo)propertyMetadata.Info).SetValue(obj, JsonMapper.ReadValue(propertyMetadata.Type, reader));
                            }
                            else
                            {
                                PropertyInfo propertyInfo = (PropertyInfo)propertyMetadata.Info;
                                if (propertyInfo.CanWrite)
                                {
                                    propertyInfo.SetValue(obj, JsonMapper.ReadValue(propertyMetadata.Type, reader), null);
                                }
                                else
                                {
                                    JsonMapper.ReadValue(propertyMetadata.Type, reader);
                                }
                            }
                        }
                        else
                        {
                            if (!objectMetadata.IsDictionary)
                            {
                                goto Block_28;
                            }
                            ((IDictionary)obj).Add(text, JsonMapper.ReadValue(objectMetadata.ElementType, reader));
                        }
                    }
                    goto IL_440;
Block_28:
                    JsonException.Throw(new JsonException(string.Format("The type {0} doesn't have the property '{1}'", inst_type, text)));
                }
IL_440:
                result = obj;
            }
            return(result);
        }
Example #20
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            //ILRuntime doesn't support nullable valuetype
            Type underlying_type = inst_type;//Nullable.GetUnderlyingType(inst_type);
            Type value_type      = inst_type;

            if (reader.Token == JsonToken.Null)
            {
                if (inst_type.IsClass || underlying_type != null)
                {
                    return(null);
                }

                throw new JsonException(String.Format(
                                            "Can't assign null to an instance of type {0}",
                                            inst_type));
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();
                var  vt        = value_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)value_type).CLRType.TypeForCLR : value_type;

                if (vt.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }
                if (vt is ILRuntime.Reflection.ILRuntimeType && ((ILRuntime.Reflection.ILRuntimeType)vt).ILType.IsEnum)
                {
                    if (json_type == typeof(int) || json_type == typeof(long) || json_type == typeof(short) || json_type == typeof(byte))
                    {
                        return(reader.Value);
                    }
                }
                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        vt))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][vt];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        vt))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][vt];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (vt.IsEnum)
                {
                    return(Enum.ToObject(vt, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(vt, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }
                    var rt = elem_type is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)elem_type).RealType : elem_type;
                    item = rt.CheckCLRTypes(item);
                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(value_type);
                ObjectMetadata t_data = object_metadata[value_type];
                if (value_type is ILRuntime.Reflection.ILRuntimeType)
                {
                    instance = ((ILRuntime.Reflection.ILRuntimeType)value_type).ILType.Instantiate();
                }
                else
                {
                    if (value_type is ILRuntime.Reflection.ILRuntimeWrapperType)
                    {
                        value_type = ((ILRuntime.Reflection.ILRuntimeWrapperType)value_type).RealType;
                    }
                    instance = Activator.CreateInstance(value_type);
                }
                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(String.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, property));
                            }
                            else
                            {
                                ReadSkip(reader);
                                continue;
                            }
                        }
                        //这里是为了 扩展可以让他支持 字典的key为int类型
                        if (t_data.IsDictionary)
                        {
                            var dicTypes  = instance.GetType().GetGenericArguments();
                            var converter = System.ComponentModel.TypeDescriptor.GetConverter(dicTypes[0]);
                            if (converter != null)
                            {
                                var temp = converter.ConvertFromString(property);
                                t_data.ElementType = dicTypes[1];
                                ((IDictionary)instance).Add(temp, ReadValue(t_data.ElementType, reader));
                                continue;
                            }
                        }

                        var rt = t_data.ElementType is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)t_data.ElementType).RealType : t_data.ElementType;
                        ((IDictionary)instance).Add(
                            property, rt.CheckCLRTypes(ReadValue(
                                                           t_data.ElementType, reader)));
                    }
                }
            }

            return(instance);
        }
Example #21
0
 		private static void RegisterImporter (IDictionary table, Type json_type, Type value_type, ImporterFunc importer)
        {
            if (!table.Contains(json_type))
                table.Add(json_type, new Hashtable());

            (table[json_type] as IDictionary)[value_type] = importer;
        }       
Example #22
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            if (reader.Token == JsonToken.Null)
            {
                if (!inst_type.IsClass)
                {
                    throw new JsonException(String.Format(
                                                "Can't assign null to an instance of type {0}",
                                                inst_type));
                }

                return(null);
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (inst_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (inst_type.IsEnum)
                {
                    return(Enum.ToObject(inst_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(inst_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // PhuongTD
                if (reader.Token == JsonToken.Int && inst_type.Name.CompareTo("Int64") == 0)
                {
                    long result = Convert.ToInt64(reader.Value);
                    return(result);
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(inst_type);
                ObjectMetadata t_data = object_metadata[inst_type];

                instance = Activator.CreateInstance(inst_type);

                string prv_property = null;
                string property     = null;
                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    prv_property = property;
                    property     = (string)reader.Value;

                    if (property == null)
                    {
                        int a = 0;
                    }

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            /*
                             * throw new JsonException(String.Format(
                             *      "The type {0} doesn't have the " +
                             *      "property '{1}'", inst_type, property));*/


                            // PhuongTD start ignore this prop
                            reader.Read();

                            LitJson.JsonToken start_token = reader.Token;

                            if (reader.Token == JsonToken.Double ||
                                reader.Token == JsonToken.Int ||
                                reader.Token == JsonToken.Long ||
                                reader.Token == JsonToken.String ||
                                reader.Token == JsonToken.Boolean
                                )
                            {
                                // Done
                            }
                            else
                            {
                                LitJson.JsonToken end_token = start_token;

                                if (start_token == JsonToken.ArrayStart)
                                {
                                    end_token = JsonToken.ArrayEnd;
                                }
                                else if (start_token == JsonToken.ObjectStart)
                                {
                                    end_token = JsonToken.ObjectEnd;
                                }

                                int nested = 1;
                                while (reader.Read())
                                {
                                    if (reader.Token == start_token)
                                    {
                                        nested++;
                                    }

                                    if (reader.Token == end_token)
                                    {
                                        nested--;
                                    }

                                    if (nested == 0)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        else if (((IDictionary)instance).Contains(property))
                        {
                        }
                        else
                        {
                            ((IDictionary)instance).Add(
                                property, ReadValue(
                                    t_data.ElementType, reader));
                        }
                    }
                }
            }

            return(instance);
        }
Example #23
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            if (reader.Token == JsonToken.Null)
            {
                if (!inst_type.IsClass)
                {
                    throw new JsonException(String.Format(
                                                "Can't assign null to an instance of type {0}",
                                                inst_type));
                }

                return(null);
            }

            if (reader.Token == JsonToken.Single || // 让LitJson支持 Single(float)[10/12/2017 ZhangDi]
                reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                // typeof(double).IsAssignableFrom (typeof(float)) 结果为 false [10/12/2017 ZhangDi]
                // 我写的让LitJson支持single逻辑,导致有可能把double识别成single,例如当double d = 2。
                // 所以,这里是允许把single赋值给double的
                if (inst_type == typeof(double) && json_type == typeof(float))
                {
                    return(reader.Value);
                }

                if (inst_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (inst_type.IsEnum)
                {
                    return(Enum.ToObject(inst_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(inst_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(inst_type);
                ObjectMetadata t_data = object_metadata[inst_type];

                instance = Activator.CreateInstance(inst_type);

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (t_data.IsDictionary)
                        {
                            ((IDictionary)instance).Add(property, ReadValue(t_data.ElementType, reader));
                        }
                        else
                        {
                            // 如果A比B多一个成员变量,把A的json数据反序列化成B时,会报这个Exception。而我们不需要报错 [10/12/2017 ZhangDi]
                            //throw new JsonException(String.Format(
                            //		"The type {0} doesn't have the " +
                            //		"property '{1}'", inst_type, property));
                            // 但也要把这个变量读出来,否则会出错
                            ReadValue(t_data.ElementType, reader);
                        }
                    }
                }
            }

            return(instance);
        }
Example #24
0
		/**
		 */
		public static void RegisterImporter(Type TJson, Type TValue, ImporterFunc importer)
        {
            RegisterImporter(custom_importers_table, TJson, TValue, importer);
        }
Example #25
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();
            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            if (reader.Token == JsonToken.Null)
            {
                if (!inst_type.IsClass)
                {
                    throw new JsonException(String.Format(
                                                "Can't assign null to an instance of type {0}",
                                                inst_type));
                }

                return(null);
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();
                // guofei (扩展从string自动转成int的功能)
                if (json_type == typeof(string) && inst_type == typeof(int))
                {
                    reader.Value = (object)int.Parse(reader.Value.ToString());
                    json_type    = reader.Value.GetType();
                }
                // guofei (扩展从string自动转成float的功能)
                if (json_type == typeof(string) && inst_type == typeof(float))
                {
                    reader.Value = (object)float.Parse(reader.Value.ToString());
                    json_type    = reader.Value.GetType();
                }

                // guofei (扩展从int自动转成string的功能)
                if (json_type == typeof(int) && inst_type == typeof(string))
                {
                    reader.Value = (object)reader.Value.ToString();
                    json_type    = reader.Value.GetType();
                }

                // guofei (扩展从float自动转成string的功能)
                if (json_type == typeof(float) && inst_type == typeof(string))
                {
                    reader.Value = (object)reader.Value.ToString();
                    json_type    = reader.Value.GetType();
                }
                // (扩展从long自动转成string的功能)
                if (json_type == typeof(long) && inst_type == typeof(string))
                {
                    reader.Value = (object)reader.Value.ToString();
                    json_type    = reader.Value.GetType();
                }

                if (inst_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (inst_type.IsEnum)
                {
                    return(Enum.ToObject(inst_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(inst_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }
                object item = ReadValue(elem_type, reader);
                while (item != null)
                {
                    list.Add(item);
                    item = ReadValue(elem_type, reader);
                }
//                while (true)
//				{
//                    object item = ReadValue (elem_type, reader);
//					if(item!=null)
//                      list.Add (item);
//
//                    if (reader.Token == JsonToken.ArrayEnd)
//					{
//                        break;
//					}
//                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(inst_type);
                ObjectMetadata t_data = object_metadata[inst_type];
                try
                {
                    instance = Activator.CreateInstance(inst_type);
                }catch (Exception e)
                {
                    UnityEngine.Debug.LogError(inst_type);
                    UnityEngine.Debug.LogError(e.ToString());
                }
                while (true)
                {
                    reader.Read();
                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;
                    if (property == null)
                    {
                        break;
                    }
                    if (property != null && t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            throw new JsonException(String.Format(
                                                        "The type {0} doesn't have the " +
                                                        "property '{1}'", inst_type, property));
                        }
                        ((IDictionary)instance).Add(
                            property, ReadValue(
                                t_data.ElementType, reader));
                    }
                }
            }
            return(instance);
        }
Example #26
0
        /// <summary>
        ///     Registers the base importers.
        /// </summary>
        private void RegisterBaseImporters()
        {
            ImporterFunc importer = input => Convert.ToByte((int)input);

            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(byte), importer);

            importer = input => Convert.ToInt64((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(long), importer);

            importer = input => Convert.ToUInt64((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(ulong), importer);

            importer = input => Convert.ToSByte((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(sbyte), importer);

            importer = input => Convert.ToInt16((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(short), importer);

            importer = input => Convert.ToUInt16((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(ushort), importer);

            importer = input => Convert.ToUInt32((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(uint), importer);

            importer = input => Convert.ToSingle((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(float), importer);

            importer = input => Convert.ToDouble((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(double), importer);

            importer = input => Convert.ToDouble((float)input);
            RegisterImporter(_baseImportersTable, typeof(float),
                             typeof(double), importer);

            importer = input => Convert.ToString((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(string), importer);

            importer = input => Convert.ToDecimal((double)input);
            RegisterImporter(_baseImportersTable, typeof(double),
                             typeof(decimal), importer);

            importer = input => Convert.ToSingle((double)input);
            RegisterImporter(_baseImportersTable, typeof(double),
                             typeof(float), importer);

            importer = input => Convert.ToUInt32((long)input);
            RegisterImporter(_baseImportersTable, typeof(long),
                             typeof(uint), importer);

            importer = input => Convert.ToChar((string)input);
            RegisterImporter(_baseImportersTable, typeof(string),
                             typeof(char), importer);

            importer = input => Convert.ToDateTime((string)input, _datetimeFormat);
            RegisterImporter(_baseImportersTable, typeof(string),
                             typeof(DateTime), importer);

            importer = input => Convert.ToDateTime((string)input, _datetimeFormat);
            RegisterImporter(_baseImportersTable, typeof(string),
                             typeof(TimeSpan), importer);

            importer = input => Convert.ToSingle((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(float), importer);

            importer = input => Convert.ToSingle((int)input);
            RegisterImporter(_baseImportersTable, typeof(int),
                             typeof(float?), importer);
        }
Example #27
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
            Type value_type      = underlying_type ?? inst_type;

            if (reader.Token == JsonToken.Null)
            {
                if (inst_type.IsClass || underlying_type != null)
                {
                    return(null);
                }

                throw new JsonException(String.Format(
                                            "Can't assign null to an instance of type {0}",
                                            inst_type));
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (value_type.IsAssignableFrom(json_type))
                {
                    ////调试
                    //if(reader.Token == JsonToken.String)
                    //{
                    //    string s = (string)reader.Value;
                    //    if(s == "flyer_xuanfengzhan")
                    //    {
                    //        Debuger.LogError("调试");
                    //    }
                    //    return s;
                    //}
                    //else
                    return(reader.Value);
                }


                switch (reader.Token)
                {
                case JsonToken.Int:
                    if (value_type == typeof(long))
                    {
                        return((long)(int)reader.Value);
                    }
                    if (value_type == typeof(Property))
                    {
                        return(new Property((int)reader.Value));
                    }
                    break;

                case JsonToken.Long:
                    if (value_type == typeof(int))
                    {
                        return((int)(long)reader.Value);
                    }
                    if (value_type == typeof(Property))
                    {
                        return(new Property((long)reader.Value));
                    }
                    break;

                case JsonToken.String:
                    if (value_type == typeof(Property))
                    {
                        return(new Property((string)reader.Value));
                    }
                    break;

                case JsonToken.Double:
                    if (value_type == typeof(float))
                    {
                        return((float)(double)reader.Value);
                    }
                    if (value_type == typeof(long))
                    {
                        return((long)(double)reader.Value);
                    }
                    if (value_type == typeof(int))
                    {
                        return((int)(double)reader.Value);
                    }
                    if (value_type == typeof(Property))
                    {
                        return(new Property((float)(double)reader.Value));
                    }
                    break;
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (value_type.IsEnum)
                {
                    return(Enum.ToObject(value_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(value_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddInheritMetadata(value_type);

                InheritMetadata i_data = inherit_metadata[value_type];


                //如果允许多态的话要判断当前的类型
                if (i_data.IsInherit)
                {
                    reader.Read();
                    string property = (string)reader.Value;
                    if (property == "__type")
                    {
                        string trueTypeName = (string)ReadValue(typeof(string), reader);

                        Type trueType;
                        if (!typeDict.TryGetValue(trueTypeName, out trueType))
                        {
                            trueType = Type.GetType(trueTypeName);
                            typeDict[trueTypeName] = trueType;
                        }

                        if (trueType != null)
                        {
                            value_type = trueType;
                        }
                        else
                        {
                            Debuger.LogError("找不到类名对应的类型:{0}", trueTypeName);
                        }
                    }
                    else
                    {
                        Debuger.LogError("逻辑错误,可能是老版本");
                    }
                }

                instance = Activator.CreateInstance(value_type);

                AddObjectMetadata(value_type);
                ObjectMetadata t_data = object_metadata[value_type];

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else if (t_data.IsList)
                    {
                        IList l = (IList)instance;
                        int   idx;
                        if (!int.TryParse(property, out idx))
                        {
                            Debuger.LogError("json尝试将键值对转为数组失败,类型:{0},转换失败的key:{1}", value_type.Name, property);
                            ReadSkip(reader);
                            continue;
                        }

                        //如果不够,那么先补上
                        for (int i = l.Count; i <= idx; ++i)
                        {
                            if (t_data.ElementType.IsValueType)
                            {
                                l.Add(Activator.CreateInstance(value_type));
                            }
                            else
                            {
                                l.Add(null);
                            }
                        }

                        //设置值
                        l[idx] = ReadValue(t_data.ElementType, reader);
                    }
                    else if (t_data.IsDictionary)
                    {
                        if (t_data.KeyType == typeof(string))
                        {
                            ((IDictionary)instance).Add(property, ReadValue(t_data.ElementType, reader));
                        }
                        else
                        {
                            object k;
                            if (!StringUtil.TryParse(property, t_data.KeyType, out k))
                            {
                                Debuger.LogError("json尝试将键值对转换成:{0}时失败,转换失败的key:{1}", value_type.Name, property);
                                ReadSkip(reader);
                                continue;
                            }

                            ((IDictionary)instance).Add(k, ReadValue(t_data.ElementType, reader));
                        }
                    }
                    else if (!reader.SkipNonMembers)
                    {
                        throw new JsonException(String.Format(
                                                    "The type {0} doesn't have the " +
                                                    "property '{1}'",
                                                    inst_type, property));
                    }
                    else
                    {
                        ReadSkip(reader);
                        continue;
                    }
                }
            }

            return(instance);
        }
Example #28
0
        private static System.Object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            if (reader.Token == JsonToken.Null)
            {
                if (!inst_type.IsClass)
                {
                    throw new JsonException(String.Format(
                                                "Can't assign null to an instance of type {0}",
                                                inst_type));
                }

                return(null);
            }

            if (reader.Token == JsonToken.Single ||
                reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (inst_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        inst_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][inst_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                if (inst_type.IsEnum)
                {
                    return(Enum.ToObject(inst_type, reader.Value));
                }

                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(inst_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new System.Object[] { reader.Value }));
                }

                //////////////////////////////////// ADD ////////////////////////////////////
                // ÀàÐÍת»»
                if (inst_type.Name == "String" && json_type.Name != "String")
                {
                    return(reader.Value.ToString());
                }
                else if (json_type.Name == "String")
                {
                    if (inst_type.Name == "Int32")
                    {
                        int re = 0;
                        int.TryParse(reader.Value as string, out re);
                        return(re);
                    }
                    else if (inst_type.Name == "Single")
                    {
                        float re = 0;
                        float.TryParse(reader.Value as string, out re);
                        return(re);
                    }
                    else if (inst_type.Name == "Double")
                    {
                        double re = 0;
                        double.TryParse(reader.Value as string, out re);
                        return(re);
                    }
                }
                else if (inst_type.Name == "Int32" && json_type.Name == "Double")
                {
                    return(Convert.ToInt32((double)(reader.Value)));
                }
                else if (inst_type.Name == "Double" && json_type.Name == "Int32")
                {
                    return((double)(reader.Value));
                }
                else if (inst_type.Name == "Single" && json_type.Name == "Double")
                {
                    return(Convert.ToSingle((double)(reader.Value)));
                }
                else if (inst_type.Name == "Single" && json_type.Name == "Int32")
                {
                    return(Convert.ToSingle((int)(reader.Value)));
                }
                else if (inst_type.Name == "Int32" && json_type.Name == "Single")
                {
                    return(Convert.ToInt32((float)(reader.Value)));
                }
                else if (inst_type.Name == "Double" && json_type.Name == "Single")
                {
                    return(Convert.ToDouble((float)(reader.Value)));
                }
                ////////////////////////////////// ADD OVER /////////////////////////////////
                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            System.Object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    System.Object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(inst_type);
                ObjectMetadata t_data = object_metadata[inst_type];

                instance = Activator.CreateInstance(inst_type);

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(String.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, property));
                            }
                            else
                            {
                                ReadSkip(reader);
                                continue;
                            }
                        }

                        ((IDictionary)instance).Add(
                            property, ReadValue(
                                t_data.ElementType, reader));
                    }
                }
            }

            return(instance);
        }
Example #29
0
        public static void RegisterImporter <TJson, TValue>(ImporterFunc <TJson, TValue> importer)
        {
            ImporterFunc importer2 = (object input) => importer((TJson)((object)input));

            JsonMapper.RegisterImporter(JsonMapper.custom_importers_table, typeof(TJson), typeof(TValue), importer2);
        }
        //support unity
        private static void RegisterUnityImporters()
        {
            ImporterFunc <string, Vector2> vec2importer;

            vec2importer = new ImporterFunc <string, Vector2>(delegate(string input)
            {
                return(TypeConvert.ToVector2(input));
            });
            JsonMapper.RegisterImporter(vec2importer);

            ImporterFunc <string, Vector3> vec3importer;

            vec3importer = new ImporterFunc <string, Vector3>(delegate(string input)
            {
                return(TypeConvert.ToVector3(input));
            });
            JsonMapper.RegisterImporter(vec3importer);

            ImporterFunc <string, Vector4> vec4importer;

            vec4importer = new ImporterFunc <string, Vector4>(delegate(string input)
            {
                return(TypeConvert.ToVector4(input));
            });
            JsonMapper.RegisterImporter(vec4importer);

            ImporterFunc <string, Vector2Int> vec2Intimporter;

            vec2Intimporter = new ImporterFunc <string, Vector2Int>(delegate(string input)
            {
                return(TypeConvert.ToVector2Int(input));
            });
            JsonMapper.RegisterImporter(vec2Intimporter);

            ImporterFunc <string, Vector3Int> vec3Intimporter;

            vec3Intimporter = new ImporterFunc <string, Vector3Int>(delegate(string input)
            {
                return(TypeConvert.ToVector3Int(input));
            });
            JsonMapper.RegisterImporter(vec3Intimporter);

            ImporterFunc <string, Rect> rectimporter;

            rectimporter = new ImporterFunc <string, Rect>(delegate(string input)
            {
                return(TypeConvert.ToRect(input));
            });
            JsonMapper.RegisterImporter(rectimporter);

            ImporterFunc <string, RectInt> rectIntimporter;

            rectIntimporter = new ImporterFunc <string, RectInt>(delegate(string input)
            {
                return(TypeConvert.ToRectInt(input));
            });
            JsonMapper.RegisterImporter(rectIntimporter);

            ImporterFunc <string, Color> colorimporter;

            colorimporter = new ImporterFunc <string, Color>(delegate(string input)
            {
                return(TypeConvert.ToColor(input));
            });
            JsonMapper.RegisterImporter(colorimporter);

            ImporterFunc <string, Color32> color32importer;

            color32importer = new ImporterFunc <string, Color32>(delegate(string input)
            {
                return(TypeConvert.ToColor32(input));
            });
            JsonMapper.RegisterImporter(color32importer);
        }
Example #31
0
        private static object ReadValue(Type inst_type, JsonReader reader)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
            Type value_type      = underlying_type ?? inst_type;

            if (reader.Token == JsonToken.Null)
            {
                #if NETSTANDARD1_5
                if (inst_type.IsClass() || underlying_type != null)
                {
                    return(null);
                }
                #else
                if (inst_type.IsClass || underlying_type != null)
                {
                    return(null);
                }
                #endif

                throw new JsonException(String.Format(
                                            "Can't assign null to an instance of type {0}",
                                            inst_type));
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (value_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                #if NETSTANDARD1_5
                if (value_type.IsEnum())
                {
                    return(Enum.ToObject(value_type, reader.Value));
                }
                #else
                if (value_type.IsEnum)
                {
                    return(Enum.ToObject(value_type, reader.Value));
                }
                #endif
                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(value_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            object instance = null;

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(value_type);
                ObjectMetadata t_data = object_metadata[value_type];

                instance = Activator.CreateInstance(value_type);

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(String.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, property));
                            }
                            else
                            {
                                ReadSkip(reader);
                                continue;
                            }
                        }

                        ((IDictionary)instance).Add(
                            property, ReadValue(
                                t_data.ElementType, reader));
                    }
                }
            }

            return(instance);
        }
Example #32
0
        private object ConvertValue(Type propType, object value, object fallbackValue)
        {
            object result = null;

            // TODO temp check, need to throw exc?
            if (value == null)
            {
                if (fallbackValue != null)
                {
                    result = fallbackValue;
                }
                return(result);
            }

            try
            {
                var propWrapper = propType.GetTypeWrapper();
                var valueType   = value.GetType();

                if (propWrapper.IsAssignableFrom(valueType))
                {
                    result = value;
                }
                else
                {
                    ImporterFunc importer = null;
                    if (_baseImportersTable.ContainsKey(valueType))
                    {
                        var importers = _baseImportersTable[valueType];
                        if (importers.ContainsKey(propType))
                        {
                            importer = importers[propType];
                        }
                    }

                    if (importer == null)
                    {
                        if (_customImportersTable.ContainsKey(valueType))
                        {
                            var importers = _customImportersTable[valueType];
                            if (importers.ContainsKey(propType))
                            {
                                importer = importers[propType];
                            }
                        }

                        if (importer == null)
                        {
                            Error("Cannot resolve proper value importer for property type '{0}' from value type '{1}'",
                                  propType, valueType);
                        }
                    }

                    result = importer(value);
                }
            }
            catch (Exception ex)
            {
                if (fallbackValue == null)
                {
                    Error("Error during value conversion: {0}", ex);
                }
                else
                {
                    result = fallbackValue;
                }
            }
            return(result);
        }