private static object ReadValue(Type inst_type, JsonReader reader, Func <string, object> createFun, Func <string, Type> typeFun, string prefix) { 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); } reader.ShowErrorText(); throw new JsonException(String.Format( "Can't assign null to an instance of type {0}", inst_type)); } 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(); 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 })); } //////////////////////////////////// ADD //////////////////////////////////// // 类型转换 if (value_type.Name == "String" && json_type.Name != "String") { return(reader.Value.ToString()); } else if (json_type.Name == "String") { if (value_type.Name == "Int32") { int re = 0; int.TryParse(reader.Value as string, out re); return(re); } else if (value_type.Name == "Single") { float re = 0; float.TryParse(reader.Value as string, out re); return(re); } else if (value_type.Name == "Double") { double re = 0; double.TryParse(reader.Value as string, out re); return(re); } } else if (json_type.Name == "Int32") { if (value_type.Name == "Double") { return((double)(reader.Value)); } else if (value_type.Name == "Single") { return(Convert.ToSingle((int)(reader.Value))); } else if (value_type.Name == "Int64") { return(Convert.ToInt64((int)(reader.Value))); } } else if (value_type.Name == "Int32" && json_type.Name == "Double") { return(Convert.ToInt32((double)(reader.Value))); } else if (value_type.Name == "Single" && json_type.Name == "Double") { return(Convert.ToSingle((double)(reader.Value))); } else if (value_type.Name == "Int32" && json_type.Name == "Single") { return(Convert.ToInt32((float)(reader.Value))); } else if (value_type.Name == "Double" && json_type.Name == "Single") { return(Convert.ToDouble((float)(reader.Value))); } ////////////////////////////////// ADD OVER ///////////////////////////////// // No luck reader.ShowErrorText(); 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) { reader.ShowErrorText(); 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, createFun, typeFun, (prefix == null)?null:(prefix + ".Item")); 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) { //处理自定义类型 if (typeFun != null) { Type realType = typeFun(prefix); if (realType != null) { value_type = realType; } } AddObjectMetadata(value_type); ObjectMetadata t_data = object_metadata[value_type]; //处理自定义类型 if (createFun != null) { instance = createFun(prefix); if (instance == null) { instance = Activator.CreateInstance(value_type); } } else 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, createFun, typeFun, (prefix == null) ? null : (prefix + "." + prop_data.Info.Name))); } else { PropertyInfo p_info = (PropertyInfo)prop_data.Info; if (p_info.CanWrite) { p_info.SetValue( instance, ReadValue(prop_data.Type, reader, createFun, typeFun, (prefix == null) ? null : (prefix + "." + prop_data.Info.Name)), null); } else { ReadValue(prop_data.Type, reader, createFun, typeFun, (prefix == null) ? null : (prefix + "." + prop_data.Info.Name)); } } } else { if (!t_data.IsDictionary) { if (!reader.SkipNonMembers) { reader.ShowErrorText(); throw new JsonException(String.Format( "The type {0} doesn't have the " + "property '{1}'", inst_type, property)); } else { ReadSkip(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, createFun, typeFun, (prefix == null) ? null : (prefix + ".Item")))); } } } return(instance); }
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 || reader.Token == JsonToken.Float) { Type json_type = reader.Value.GetType(); //int32 cast to int64 add by Melon if (json_type.Name.Equals("Int32") && inst_type.Name.Equals("Int64")) { return(reader.Value); } //int cast to float or double add by Melon //if ((json_type.Name.Equals("Double") || json_type.Name.Equals("Float")) && inst_type.Name.Equals("Single")) //{ // return reader.Value; //} 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 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); //use the getSetMethod.invoke instead of SetValue is to suport more platform // such as mono run in ios,jit is forbidden,so the p_info.setValue cannot be used p_info.GetSetMethod().Invoke(instance, new object[] { ReadValue(prop_data.Type, reader) }); } 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); }
private static object ReadValue(Type inst_type, JsonReader reader) { reader.Read(inst_type); 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 })); } // 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]; reader.Read(); //如果打开自动识别类型,那么就可以支持已经定义的动态类型 var AttrList = inst_type.GetCustomAttributes(typeof(LitJsonObjectAttribute), false); bool NoSelfType = false; foreach (var attr in AttrList) { var jsonObj = attr as LitJsonObjectAttribute; if (null != jsonObj && jsonObj.NoSelfType == true) { NoSelfType = true; } } string keyname = (string)reader.Value; if (NoSelfType == false && keyname == "selfType") //第一个字段为selftype 可以多态反射 { string classname = (string)ReadValue(typeof(string), reader); Type classtype = FindTypeByName(classname); if (null != classtype) { inst_type = classtype; AddObjectMetadata(inst_type); t_data = object_metadata[inst_type]; } reader.Read(); } if (inst_type.IsAbstract) { while (true) { if (reader.Token == JsonToken.ObjectEnd) { instance = null; break; } ReadSkip(reader); reader.Read(); } } else if (inst_type == typeof(object))//如果期望的类型为object那么会自动转换成JsonData { WrapperFactory factory = delegate { return(new JsonData()); }; instance = factory(); while (true) { if (reader.Token == JsonToken.ObjectEnd) { break; } string property = (string)reader.Value; ((IDictionary)instance)[property] = ReadValue(factory, reader); reader.Read(); } } else //按类的格式赋值 { if (reader.Token != JsonToken.ObjectEnd) { instance = Activator.CreateInstance(inst_type); } else { instance = null; } while (true) { 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); reader.Read(); continue; } } ((IDictionary)instance).Add( property, ReadValue( t_data.ElementType, reader)); } reader.Read(); } } } return(instance); }
private static void AddArrayMetadata(Type type) { if (array_metadata.ContainsKey(type)) { return; } ArrayMetadata data = new ArrayMetadata(); data.IsArray = type.IsArray; if (type.GetInterface("System.Collections.IList") != null) { data.IsList = true; } if (type is ILRuntime.Reflection.ILRuntimeWrapperType) { var wt = (ILRuntime.Reflection.ILRuntimeWrapperType)type; if (data.IsArray) { data.ElementType = wt.CLRType.ElementType.ReflectionType; } else { data.ElementType = wt.CLRType.GenericArguments[0].Value.ReflectionType; } } else { foreach (PropertyInfo p_info in type.GetProperties()) { if (p_info.Name != "Item") { continue; } ParameterInfo[] parameters = p_info.GetIndexParameters(); if (parameters.Length != 1) { continue; } if (parameters[0].ParameterType == typeof(int)) { data.ElementType = p_info.PropertyType; } } } lock (array_metadata_lock) { try { array_metadata.Add(type, data); } catch (ArgumentException) { return; } } }
static object ReadValue(Type inst_type, JsonData json) { if (json == null || json.JsonType == JsonType.None || (json.JsonType == JsonType.String && String.IsNullOrEmpty((string)json.Value) && !(inst_type == typeof(string)))) { if (inst_type.IsGenericType && inst_type.GetGenericTypeDefinition() == typeof(Nullable <>)) { return(Activator.CreateInstance(inst_type)); // empty nullable } if (!inst_type.IsClass && !inst_type.IsArray) { throw new JsonException(String.Format("Can't assign null to an instance of type {0}", inst_type)); } return(null); } object[] attrs; if ((attrs = inst_type.GetCustomAttributes(typeof(JsonConverterAttribute), false)) != null && attrs.Length == 1) { var jca = (JsonConverterAttribute)attrs[0]; var jc = (IJsonConverter)Activator.CreateInstance(jca.Converter); object v_; if (jc.Deserialize(json, inst_type, out v_)) { return(v_); } } if (inst_type.IsGenericType && inst_type.GetGenericTypeDefinition() == typeof(Nullable <>)) // 'json' isn't null -> has a value { return(Activator.CreateInstance(inst_type, ReadValue(inst_type.GetGenericArguments()[0], json))); } var v = json.Value; switch (json.JsonType) { case JsonType.Double: case JsonType.Int: case JsonType.Long: case JsonType.String: case JsonType.Boolean: return(ConvertTo(inst_type, json.Value, json.NetType(inst_type))); case JsonType.Array: { 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)); } var inList = (IList <JsonData>)v; IList list; Type elem_type; if (!t_data.IsArray) { list = (IList)Activator.CreateInstance(inst_type); elem_type = t_data.ElementType; } else { list = new List <object>(); elem_type = inst_type.GetElementType(); } for (int i = 0; i < inList.Count; i++) { list.Add(ReadValue(elem_type, inList[i])); } object inst; if (t_data.IsArray) { int n = list.Count; inst = Array.CreateInstance(elem_type, n); for (int i = 0; i < n; i++) { ((Array)inst).SetValue(list[i], i); } } else { inst = list; } return(inst); } case JsonType.Object: { AddObjectMetadata(inst_type); ObjectMetadata t_data = object_metadata[inst_type]; //throw new Exception("type is " + inst_type); var inst = Activator.CreateInstance(inst_type); var dict = (IDictionary <string, JsonData>)v; foreach (var kvp in dict) { var prop = kvp.Key; var value = kvp.Value; PropertyMetadata prop_data; if (TryGetValueIgnCase(t_data.Properties, prop, out prop_data)) { if (prop_data.IsField) { ((FieldInfo)prop_data.Info).SetValue(inst, ReadValue(prop_data.Type, value)); } else { var p_info = (PropertyInfo)prop_data.Info; var v_ = ReadValue(prop_data.Type, value); object converted = null; if ((attrs = p_info.GetCustomAttributes(typeof(JsonConverterAttribute), false)) != null && attrs.Length == 1) { var jca = (JsonConverterAttribute)attrs[0]; var jc = (IJsonConverter)Activator.CreateInstance(jca.Converter); jc.Deserialize(value, p_info.PropertyType, out converted); } if (p_info.CanWrite) { p_info.SetValue(inst, converted ?? ConvertTo(p_info.PropertyType, v_), null); } else { throw new MemberAccessException("Cannot set property '" + p_info + "' to '" + v_ + "'."); } } } else { if (!t_data.IsDictionary) { throw new JsonException(String.Format("The type {0} doesn't have the property '{1}'", inst_type, prop)); } ((IDictionary)inst).Add(prop, ReadValue(t_data.ElementType, value)); } } return(inst); } default: return(null); } }
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 })); } // 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); }
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); } if (inst_type == typeof(Int32)) { return(0); } else if (inst_type == typeof(String)) { return(""); } 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 (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.Parse(value_type, reader.Value.ToString())); } // 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 is IJsonReader) { ((IJsonReader)item).OnJsonToObjectFinished(); } 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]; try { instance = Activator.CreateInstance(value_type); } catch (System.Exception e) { UnityEngine.Debug.LogError(inst_type.ToString() + " convert failed"); } 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]; object item = ReadValue(prop_data.Type, reader); if (item is IJsonReader) { ((IJsonReader)item).OnJsonToObjectFinished(); } if (prop_data.IsField) { ((FieldInfo)prop_data.Info).SetValue( instance, item); } else { PropertyInfo p_info = (PropertyInfo)prop_data.Info; if (p_info.CanWrite) { p_info.SetValue( instance, item, null); } } } 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; } } Type keytype = value_type.GenericTypeArguments[0]; object value = ReadValue( value_type.GenericTypeArguments[1], reader); if (value is IJsonReader) { ((IJsonReader)value).OnJsonToObjectFinished(); } if (keytype.IsEnum) { ((IDictionary)instance).Add( Enum.Parse(keytype, property), value); } else if (keytype == typeof(int)) { ((IDictionary)instance).Add(Convert.ToInt32(property), value); } else { ((IDictionary)instance).Add( property, value); } } } } return(instance); }
private static object ReadValue(Type instType, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd) { return(null); } Type underlyingType = Nullable.GetUnderlyingType(instType); Type valueType = underlyingType ?? instType; if (reader.Token == JsonToken.Null) { #if JSON_WINRT || (UNITY_METRO && !UNITY_EDITOR) /* IsClass is made a getter here as a comparability * patch for WinRT build targets, see Platform.cs */ if (instType.IsClass() || underlyingType != null) { #else if (instType.IsClass || underlyingType != null) { #endif return(null); } throw new JsonException(string.Format("Can't assign null to an instance of type {0}", instType)); } if (reader.Token == JsonToken.Real || reader.Token == JsonToken.Natural || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean) { Type jsonType = reader.Value.GetType(); if (valueType.IsAssignableFrom(jsonType)) { return(reader.Value); } // Try to find a custom or base importer ImporterFunc importer = GetImporter(jsonType, valueType); if (importer != null) { return(importer(reader.Value)); } // Maybe it's an enum #if JSON_WINRT || (UNITY_METRO && !UNITY_EDITOR) /* IsClass is made a getter here as a comparability * patch for WinRT build targets, see Platform.cs */ if (valueType.IsEnum()) { #else if (valueType.IsEnum) { #endif return(Enum.ToObject(valueType, reader.Value)); } // Try using an implicit conversion operator MethodInfo convOp = GetConvOp(valueType, jsonType); if (convOp != null) { return(convOp.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, jsonType, instType)); } object instance = null; if (reader.Token == JsonToken.ArrayStart) { // If there's a custom importer that fits, use it ImporterFunc importer = GetImporter(typeof(JsonData), instType); if (importer != null) { instType = typeof(JsonData); } AddArrayMetadata(instType); ArrayMetadata tdata = arrayMetadata[instType]; if (!tdata.IsArray && !tdata.IsList) { throw new JsonException(string.Format("Type {0} can't act as an array", instType)); } IList list; Type elemType; if (!tdata.IsArray) { list = (IList)CreateInstance(instType); elemType = tdata.ElementType; } else { //list = new ArrayList(); list = new List <object>(); elemType = instType.GetElementType(); } while (true) { object item = ReadValue(elemType, reader); if (item == null && reader.Token == JsonToken.ArrayEnd) { break; } list.Add(item); } if (tdata.IsArray) { int n = list.Count; instance = Array.CreateInstance(elemType, 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) { valueType = Type.GetType(typeName); object value = ReadValue(valueType, reader); reader.Read(); if (reader.Token != JsonToken.ObjectEnd) { throw new JsonException(string.Format("Invalid type hinting object, has too many properties: {0}...", reader.Token)); } return(value); } else { throw new JsonException(string.Format("Expected \"{0}\" property for type hinting but instead got \"{1}\"", reader.HintValueName, 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 = GetImporter(typeof(JsonData), valueType); if (importer != null) { valueType = typeof(JsonData); } ObjectMetadata tdata = AddObjectMetadata(valueType); instance = CreateInstance(valueType); bool firstRun = true; while (!done) { if (firstRun) { firstRun = false; } else { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } property = (string)reader.Value; } PropertyMetadata pdata; if (tdata.Properties.TryGetValue(property, out pdata)) { // Don't deserialize a field or property that has a JsonIgnore attribute with deserialization usage. if ((pdata.Ignore & JsonIgnoreWhen.Deserializing) > 0) { ReadSkip(reader); continue; } if (pdata.IsField) { ((FieldInfo)pdata.Info).SetValue(instance, ReadValue(pdata.Type, reader)); } else { PropertyInfo pinfo = (PropertyInfo)pdata.Info; if (pinfo.CanWrite) { pinfo.SetValue(instance, ReadValue(pdata.Type, reader), null); } else { ReadValue(pdata.Type, reader); } } } else { if (!tdata.IsDictionary) { if (!reader.SkipNonMembers) { throw new JsonException(string.Format("The type {0} doesn't have the property '{1}'", instType, property)); } else { ReadSkip(reader); continue; } } ((IDictionary)instance).Add(property, ReadValue(tdata.ElementType, reader)); } } if (importer != null) { instance = importer(instance); } } return(instance); }
private static object ReadValue(Type inst_type, JsonReader reader) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd) { return((object)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}", (object)inst_type)); } return((object)null); } 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)) { return(reader.Value); } if (JsonMapper.custom_importers_table.ContainsKey(type) && JsonMapper.custom_importers_table[type].ContainsKey(inst_type)) { return(JsonMapper.custom_importers_table[type][inst_type](reader.Value)); } if (JsonMapper.base_importers_table.ContainsKey(type) && JsonMapper.base_importers_table[type].ContainsKey(inst_type)) { return(JsonMapper.base_importers_table[type][inst_type](reader.Value)); } if (inst_type.IsEnum) { return(Enum.ToObject(inst_type, reader.Value)); } MethodInfo convOp = JsonMapper.GetConvOp(inst_type, type); if (!(convOp != (MethodInfo)null)) { throw new JsonException(string.Format("Can't assign value '{0}' (type {1}) to type {2}", reader.Value, (object)type, (object)inst_type)); } return(convOp.Invoke((object)null, new object[1] { reader.Value })); } object obj1 = (object)null; if (reader.Token == JsonToken.ArrayStart) { JsonMapper.AddArrayMetadata(inst_type); ArrayMetadata arrayMetadata = JsonMapper.array_metadata[inst_type]; if (!arrayMetadata.IsArray && !arrayMetadata.IsList) { throw new JsonException(string.Format("Type {0} can't act as an array", (object)inst_type)); } IList list; Type elementType; if (!arrayMetadata.IsArray) { list = (IList)Activator.CreateInstance(inst_type); elementType = arrayMetadata.ElementType; } else { list = (IList) new ArrayList(); elementType = inst_type.GetElementType(); } while (true) { object obj2 = JsonMapper.ReadValue(elementType, reader); if (obj2 != null || reader.Token != JsonToken.ArrayEnd) { list.Add(obj2); } else { break; } } if (arrayMetadata.IsArray) { int count = list.Count; obj1 = (object)Array.CreateInstance(elementType, count); for (int index = 0; index < count; ++index) { ((Array)obj1).SetValue(list[index], index); } } else { obj1 = (object)list; } } else if (reader.Token == JsonToken.ObjectStart) { JsonMapper.AddObjectMetadata(inst_type); ObjectMetadata objectMetadata = JsonMapper.object_metadata[inst_type]; obj1 = Activator.CreateInstance(inst_type); string key; while (true) { reader.Read(); if (reader.Token != JsonToken.ObjectEnd) { key = (string)reader.Value; if (objectMetadata.Properties.ContainsKey(key)) { PropertyMetadata property = objectMetadata.Properties[key]; if (property.IsField) { ((FieldInfo)property.Info).SetValue(obj1, JsonMapper.ReadValue(property.Type, reader)); } else { PropertyInfo info = (PropertyInfo)property.Info; if (info.CanWrite) { info.SetValue(obj1, JsonMapper.ReadValue(property.Type, reader), (object[])null); } else { JsonMapper.ReadValue(property.Type, reader); } } } else if (!objectMetadata.IsDictionary) { if (reader.SkipNonMembers) { JsonMapper.ReadSkip(reader); } else { break; } } else { ((IDictionary)obj1).Add((object)key, JsonMapper.ReadValue(objectMetadata.ElementType, reader)); } } else { goto label_45; } } throw new JsonException(string.Format("The type {0} doesn't have the property '{1}'", (object)inst_type, (object)key)); } label_45: return(obj1); }
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); } /*UnityEngine.Debug.Log (inst_type.ToString()); * UnityEngine.Debug.Log (reader.Token);*/ 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(); /*Debug.Log (json_type); * Debug.Log (inst_type);*/ 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; if (custom_importers_table.ContainsKey(typeof(JsonReader)) && custom_importers_table[typeof(JsonReader)].ContainsKey( elem_type)) { reader.Read(); if (reader.Token == JsonToken.ArrayEnd) { break; } ImporterFunc importer = custom_importers_table[typeof(JsonReader)][elem_type]; item = importer(reader); } else { 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) { if (custom_importers_table.ContainsKey(typeof(string)) && custom_importers_table[typeof(string)].ContainsKey( inst_type)) { ImporterFunc importer = custom_importers_table[typeof(string)][inst_type]; return(importer(reader.Value)); } System.Type init_type = inst_type; if (inst_type.IsAbstract) { Dictionary <string, System.Type> childTypes = ReflectionUtils.GetChildTypes(inst_type); while (reader.Read() && reader.Token != JsonToken.PropertyName) { ; } if (childTypes.ContainsKey(reader.Value.ToString())) { inst_type = childTypes[reader.Value.ToString()]; } else { throw new JsonException(String.Format("Attempting to deserialize JSON of type '{0}'. However, the type '{1}' doesn't inherit from the abstract type '{2}'", inst_type, reader.Value, inst_type)); } while (reader.Read() && reader.Token != JsonToken.ObjectStart) { ; } } //Debug.Log ("This is my type: " + inst_type); AddObjectMetadata(inst_type); ObjectMetadata t_data = object_metadata[inst_type]; instance = Activator.CreateInstance(inst_type); while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { if (init_type != inst_type) { while (reader.Read() && 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; } } Type[] arguments = ((IDictionary)instance).GetType().GetGenericArguments(); Type keyType = arguments[0]; if (keyType == typeof(System.Int32)) { ((IDictionary)instance).Add( int.Parse(property), ReadValue( arguments[1], reader)); } else { ((IDictionary)instance).Add( property, ReadValue( t_data.ElementType, reader)); } } } } return(instance); }
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.Float || 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 })); } if (json_type.ToString() == "System.Int32" && inst_type.ToString() == "System.Boolean") { //Debug.Log("int32 to boolean"); return((int)reader.Value != 0); } if (json_type.ToString() == "System.String" && inst_type.ToString() == "System.Int32") { //Debug.Log("string to boolean"); return(Convert.ToInt32(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 { //这里的value_type = method.GenericArguments[0].ReflectionType; ToObject<T>里的T 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) { if (((FieldInfo)prop_data.Info).IsStatic) { continue; } ((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; } } 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); }
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 elem_type = t_data.ElementType; if (inst_type is ILRuntimeWrapperType)//ilrt的字典就获取它第二个泛型参数 { elem_type = (inst_type as ILRuntimeWrapperType)?.CLRType.GenericArguments[1].Value.ReflectionType; } else { var dicTypes = instance.GetType().GetGenericArguments(); var converter = System.ComponentModel.TypeDescriptor.GetConverter(dicTypes[0]); if (converter != null) { elem_type = dicTypes[1]; } } var dict = ((IDictionary)instance); 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); }
private static object ReadValue(Type inst_type, JsonReader reader, bool usingTypeInfo = false) { 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 })); } // 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; #region read array 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, usingTypeInfo); 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; } } #endregion #region read object else if (reader.Token == JsonToken.ObjectStart) { // if we are using type info we expect the type name as first field in the json bool peekedForType = false; if (usingTypeInfo && !IsDictionary(inst_type)) { reader.Read(); if ((string)reader.Value == keyTypeInfo) { string t = (string)ReadValue(typeof(System.String), reader); inst_type = Type.GetType(t); } else { // remember that we already read the next member's name peekedForType = true; } } AddObjectMetadata(inst_type); ObjectMetadata t_data = object_metadata[inst_type]; instance = Activator.CreateInstance(inst_type); while (true) { // we already read ahead if we didn't find type info if (!peekedForType) { reader.Read(); } else { peekedForType = false; } if (reader.Token == JsonToken.ObjectEnd) { break; } string 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) { reader.Read(); continue; } if (prop_data.IsField) { ((FieldInfo)prop_data.Info).SetValue( instance, ReadValue(prop_data.Type, reader, usingTypeInfo)); } else { PropertyInfo p_info = (PropertyInfo)prop_data.Info; if (p_info.CanWrite) { p_info.SetValue( instance, ReadValue(prop_data.Type, reader, usingTypeInfo), null); } else { ReadValue(prop_data.Type, reader, usingTypeInfo); } } } else { if (!t_data.IsDictionary) { reader.Read(); if (reader.Token == JsonToken.ObjectStart) { while (reader.Token != JsonToken.ObjectEnd) { reader.Read(); } } continue; } // TODO throw exception and return result as part of the exception // throw new JsonException (String.Format ( // "The type {0} doesn't have the " + // "property '{1}'", inst_type, property)); else { ((IDictionary)instance).Add( property, ReadValue( t_data.ElementType, reader, usingTypeInfo)); } } } } #endregion return(instance); }
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.FullName.Contains("BindableProperty")) { //获取泛型的T string TName = vt.FullName.Replace("JEngine.Core.BindableProperty`1<", "").Replace(">", ""); Type GenericType = Type.GetType(TName); //强转值到T object[] parameters = new object[1]; //泛型赋值的参数 parameters[0] = Convert.ChangeType(reader.Value, GenericType); //生成实例且赋值 object _instance = Init.appdomain.Instantiate(vt.FullName, parameters); //返回可绑定数据 return(_instance); } 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); 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) { ((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, 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); }
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($"Can't assign null to an instance of type {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 type = reader.Value.GetType(); if (inst_type.IsAssignableFrom(type)) { return(reader.Value); } if (custom_importers_table.ContainsKey(type) && custom_importers_table[type].ContainsKey(inst_type)) { ImporterFunc importerFunc = custom_importers_table[type][inst_type]; return(importerFunc(reader.Value)); } if (base_importers_table.ContainsKey(type) && base_importers_table[type].ContainsKey(inst_type)) { ImporterFunc importerFunc = base_importers_table[type][inst_type]; return(importerFunc(reader.Value)); } if (inst_type.IsEnum) { return(Enum.ToObject(inst_type, reader.Value)); } MethodInfo convOp = GetConvOp(inst_type, type); if (convOp != null) { return(convOp.Invoke(null, new object[1] { reader.Value })); } throw new JsonException($"Can't assign value '{reader.Value}' (type {type}) to type {inst_type}"); } object obj = null; if (reader.Token == JsonToken.ArrayStart) { if (inst_type.Equals(typeof(object))) { inst_type = typeof(List <object>); } AddArrayMetadata(inst_type); ArrayMetadata arrayMetadata = array_metadata[inst_type]; if (!arrayMetadata.IsArray && !arrayMetadata.IsList) { throw new JsonException($"Type {inst_type} can't act as an array"); } 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) { bool flag = true; object obj2 = ReadValue(elementType, reader); if (obj2 == null && reader.Token == JsonToken.ArrayEnd) { break; } list.Add(obj2); } 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) { if (inst_type.Equals(typeof(object))) { inst_type = typeof(Dictionary <string, object>); } AddObjectMetadata(inst_type); ObjectMetadata objectMetadata = object_metadata[inst_type]; obj = Activator.CreateInstance(inst_type); while (true) { bool flag = true; reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } string text = (string)reader.Value; if (objectMetadata.Properties.ContainsKey(text)) { PropertyMetadata propertyMetadata = objectMetadata.Properties[text]; if ((propertyMetadata.Ignore & JsonIgnoreWhen.Deserializing) > JsonIgnoreWhen.Never) { ReadSkip(reader); continue; } if (propertyMetadata.IsField) { ((FieldInfo)propertyMetadata.Info).SetValue(obj, ReadValue(propertyMetadata.Type, reader)); continue; } PropertyInfo propertyInfo = (PropertyInfo)propertyMetadata.Info; if (propertyInfo.CanWrite) { propertyInfo.SetValue(obj, ReadValue(propertyMetadata.Type, reader), null); } else { ReadValue(propertyMetadata.Type, reader); } } else if (!objectMetadata.IsDictionary) { if (!reader.SkipNonMembers) { throw new JsonException($"The type {inst_type} doesn't have the property '{text}'"); } ReadSkip(reader); } else { ((IDictionary)obj).Add(text, ReadValue(objectMetadata.ElementType, reader)); } } } return(obj); }
private static object ReadValue(Type inst_type, JsonReader reader) { IList list; Type elementType; object obj3; 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 c = reader.Value.GetType(); if (inst_type.IsAssignableFrom(c)) { return(reader.Value); } if (custom_importers_table.ContainsKey(c) && custom_importers_table[c].ContainsKey(inst_type)) { ImporterFunc func = custom_importers_table[c][inst_type]; return(func(reader.Value)); } if (base_importers_table.ContainsKey(c) && base_importers_table[c].ContainsKey(inst_type)) { ImporterFunc func2 = base_importers_table[c][inst_type]; return(func2(reader.Value)); } if (inst_type.IsEnum) { return(Enum.ToObject(inst_type, reader.Value)); } MethodInfo convOp = GetConvOp(inst_type, c); if (convOp == null) { throw new JsonException(string.Format("Can't assign value '{0}' (type {1}) to type {2}", reader.Value, c, inst_type)); } return(convOp.Invoke(null, new object[] { reader.Value })); } object obj2 = null; if (reader.Token != JsonToken.ArrayStart) { goto Label_023E; } AddArrayMetadata(inst_type); ArrayMetadata metadata = array_metadata[inst_type]; if (!metadata.IsArray && !metadata.IsList) { throw new JsonException(string.Format("Type {0} can't act as an array", inst_type)); } if (!metadata.IsArray) { list = (IList)Activator.CreateInstance(inst_type); elementType = metadata.ElementType; } else { list = new ArrayList(); elementType = inst_type.GetElementType(); } Label_01CC: obj3 = ReadValue(elementType, reader); if (reader.Token != JsonToken.ArrayEnd) { list.Add(obj3); goto Label_01CC; } if (!metadata.IsArray) { return(list); } int count = list.Count; obj2 = Array.CreateInstance(elementType, count); for (int i = 0; i < count; i++) { ((Array)obj2).SetValue(list[i], i); } return(obj2); Label_023E: if (reader.Token != JsonToken.ObjectStart) { return(obj2); } AddObjectMetadata(inst_type); ObjectMetadata metadata2 = object_metadata[inst_type]; obj2 = Activator.CreateInstance(inst_type); while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { return(obj2); } string key = (string)reader.Value; if (metadata2.Properties.ContainsKey(key)) { PropertyMetadata metadata3 = metadata2.Properties[key]; if (metadata3.IsField) { ((FieldInfo)metadata3.Info).SetValue(obj2, ReadValue(metadata3.Type, reader)); } else { PropertyInfo info = (PropertyInfo)metadata3.Info; if (info.CanWrite) { info.SetValue(obj2, ReadValue(metadata3.Type, reader), null); } else { ReadValue(metadata3.Type, reader); } } } else { if (!metadata2.IsDictionary) { throw new JsonException(string.Format("The type {0} doesn't have the property '{1}'", inst_type, key)); } ((IDictionary)obj2).Add(key, ReadValue(metadata2.ElementType, reader)); } } }
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); } //Debug.Log(reader.Token + " " + reader.Value); 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) { if (json_type.Name == "String") { int re = 0; int.TryParse(reader.Value as string, out re); return(Enum.ToObject(inst_type, re)); } else if (json_type.Name == "Boolean") { return(Enum.ToObject(inst_type, ((bool)(reader.Value))?1:0)); } 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 })); } //////////////////////////////////// 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 == "Boolean") { if (reader.Value == "0") { return(false); } else { return(true); } } } 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))); } else if (inst_type.Name == "Boolean") { return(Convert.ToBoolean(reader.Value)); } NGUIDebug.Log((inst_type.Name == "Boolean") + " " + (json_type.Name == "String")); ////////////////////////////////// ADD OVER ///////////////////////////////// // No luck throw new JsonException(String.Format( "Can't assign value '{0}' (type {1}) to type {2}", reader.Value, json_type.Name, inst_type.Name)); } 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; } ////Debug.Log("JsonToken.ArrayStart " + instance.ToString()); //foreach (var info in list) //{ // Debug.Log("info = " + info); //} } 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) { //object obj = ReadValue(prop_data.Type, reader); //Debug.Log("yyy property = " + instance + " " + property + " " + p_info); p_info.SetValue( instance, ReadValue(prop_data.Type, reader), //obj,// 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); }
static object ReadValue(Type inst_type, JsonReader reader, bool readBegin = true) { if (readBegin) { reader.Read(); } if (reader.Token == JsonToken.ArrayEnd) { return(null); } if (reader.Token == JsonToken.Null || (reader.Token == JsonToken.String && String.IsNullOrEmpty((string)reader.Value) && !(inst_type == typeof(string)))) { if (!inst_type.IsClass && !inst_type.IsArray) { throw new JsonException(String.Format("Can't assign null to an instance of type {0}", inst_type)); } return(null); } if (inst_type.IsGenericType && inst_type.GetGenericTypeDefinition() == typeof(Nullable <>)) // isn't null -> has a value { return(Activator.CreateInstance(inst_type, ReadValue(inst_type.GetGenericArguments()[0], reader, false))); } if (reader.Token == JsonToken.Double || reader.Token == JsonToken.Int || reader.Token == JsonToken.Long || reader.Token == JsonToken.String || reader.Token == JsonToken.Boolean) { return(ConvertTo(inst_type, reader.Value, reader.Value.GetType())); } 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 List <object>(); 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; } var property = (string)reader.Value; PropertyMetadata prop_data; if (TryGetValueIgnCase(t_data.Properties, property, out prop_data)) { if (prop_data.IsField) { ((FieldInfo)prop_data.Info).SetValue(instance, ReadValue(prop_data.Type, reader)); } else { var p_info = (PropertyInfo)prop_data.Info; var v = ReadValue(prop_data.Type, reader); if (p_info.CanWrite) { p_info.SetValue(instance, ConvertTo(p_info.PropertyType, v), null); } } } 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)); } } } return(instance); }
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 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(); 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 NETSTANDARD1_5 if (vt.IsEnum()) { return(Enum.ToObject(vt, reader.Value)); } #else if (value_type.IsEnum) { return(Enum.ToObject(vt, reader.Value)); } #endif // 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(); } list.Clear(); 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); } while (true) { reader.Read(); if (reader.Token == JsonToken.ObjectEnd) { break; } object 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; } } var dict = (( IDictionary )instance); var rt = t_data.ElementType is ILRuntime.Reflection.ILRuntimeWrapperType ? ((ILRuntime.Reflection.ILRuntimeWrapperType)t_data.ElementType).RealType : t_data.ElementType; //让字典Key自适应类型 if (t_data.IsDictionary) { var dicTypes = instance.GetType().GetGenericArguments(); var converter = System.ComponentModel.TypeDescriptor.GetConverter(dicTypes[0]); if (converter != null) { property = converter.ConvertFromString(( string )property); //对于有自定义类当值的字典类型,需要通过CLRType才能获取到对应的类名 t_data.ElementType = dicTypes[1].FullName == "ILRuntime.Runtime.Intepreter.ILTypeInstance" ? ((ILRuntime.Reflection.ILRuntimeWrapperType)value_type).CLRType.GenericArguments[1].Value.ReflectionType : dicTypes[1]; } } var readValue = ReadValue(t_data.ElementType, reader); var checkedCLRType = rt.CheckCLRTypes(readValue); dict.Add(property, checkedCLRType); } } } return(instance); }
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); }
private static void AddArrayMetadata (Type type) { if (array_metadata.Contains(type)) return; ArrayMetadata data = new ArrayMetadata(); data.IsArray = type.IsArray; if (type.GetInterface ("System.Collections.IList") != null) data.IsList = true; foreach (PropertyInfo p_info in type.GetProperties()) { if (p_info.Name != "Item") continue; ParameterInfo[] parameters = p_info.GetIndexParameters(); if (parameters.Length != 1) continue; if (parameters[0].ParameterType == typeof (int)) data.ElementType = p_info.PropertyType; } lock (array_metadata_lock) { try { array_metadata.Add(type, data); } catch (ArgumentException) { return; } } }
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); } else { if (reader.Token != JsonToken.Double && reader.Token != JsonToken.Int && reader.Token != JsonToken.Long && reader.Token != JsonToken.String && reader.Token != JsonToken.Boolean) { object obj = null; if (reader.Token == JsonToken.ArrayStart) { JsonMapper.AddArrayMetadata(inst_type); ArrayMetadata arrayMetadata = JsonMapper.array_metadata[inst_type]; if (!arrayMetadata.IsArray && !arrayMetadata.IsList) { 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(); } for (;;) { 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; for (;;) { 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_27; } ((IDictionary)obj).Add(text, JsonMapper.ReadValue(objectMetadata.ElementType, reader)); } } return(obj); Block_27: throw new JsonException(string.Format("The type {0} doesn't have the property '{1}'", inst_type, text)); } return(obj); } Type type = reader.Value.GetType(); if (inst_type.IsAssignableFrom(type)) { return(reader.Value); } if (JsonMapper.custom_importers_table.ContainsKey(type) && JsonMapper.custom_importers_table[type].ContainsKey(inst_type)) { ImporterFunc importerFunc = JsonMapper.custom_importers_table[type][inst_type]; return(importerFunc(reader.Value)); } if (JsonMapper.base_importers_table.ContainsKey(type) && JsonMapper.base_importers_table[type].ContainsKey(inst_type)) { ImporterFunc importerFunc2 = JsonMapper.base_importers_table[type][inst_type]; return(importerFunc2(reader.Value)); } if (inst_type.IsEnum) { return(Enum.ToObject(inst_type, reader.Value)); } MethodInfo convOp = JsonMapper.GetConvOp(inst_type, type); if (convOp != null) { return(convOp.Invoke(null, new object[] { reader.Value })); } throw new JsonException(string.Format("Can't assign value '{0}' (type {1}) to type {2}", reader.Value, type, inst_type)); } }
public static T ReadValueEx <T>(JsonReader reader) { Type inst_type = typeof(T); while (reader.Read()) { if (reader.Token == JsonToken.ArrayEnd || reader.Token == JsonToken.Null) { return(default(T)); } if (reader.Token == JsonToken.ArrayStart || reader.Token == JsonToken.ObjectStart) { break; } } 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)); } } } if (instance == null) { return(default(T)); } return((T)instance); }