static DecodeMethod GetDecoderOrDefault(Type type) { DecodeMethod callback = GetDecoder(type); if (callback == null) { if (type.HasInterface(typeof(IDictionary))) { callback = GetDecoder(typeof(IDictionary)); } else if (type.HasInterface(typeof(IList))) { callback = GetDecoder(typeof(IList)); } //else if (type.HasInterface(typeof(IEnumerable))) // callback = GetDecoder(typeof(IEnumerable)); else if (type.IsArray) { callback = GetDecoder(typeof(Array)); } if (callback == null) { callback = defaultDecoder; } } return(callback); }
public ManualCodec(IEmittingCodec emittingCodec) : base(typeof(T), emittingCodec) { calculateSizeDelegate = (CalculateSizeDelegate)CalculateSizeMethod.CreateDelegate(typeof(CalculateSizeDelegate)); encodeDelegate = (EncodeDelegate)EncodeMethod.CreateDelegate(typeof(EncodeDelegate)); decodeDelegate = (DecodeDelegate)DecodeMethod.CreateDelegate(typeof(DecodeDelegate)); decodeFastDelegate = (DecodeDelegate)DecodeFastMethod.CreateDelegate(typeof(DecodeDelegate)); }
public ManualCodec(ICodecContainer codecContainer, IEmittingCodec emittingCodec) : base(typeof(T), emittingCodec) { this.codecContainer = codecContainer; calculateSizeDelegate = (CalculateSizeDelegate)CalculateSizeMethod.CreateDelegate(typeof(CalculateSizeDelegate)); encodeDelegate = (EncodeDelegate)EncodeMethod.CreateDelegate(typeof(EncodeDelegate)); decodeDelegate = (DecodeDelegate)DecodeMethod.CreateDelegate(typeof(DecodeDelegate)); decodeFastDelegate = (DecodeDelegate)DecodeFastMethod.CreateDelegate(typeof(DecodeDelegate)); }
static void AddDefaults() { SetDecoder(typeof(IDictionary), (type, jsonObj) => { if (jsonObj == null) { throw new ArgumentNullException("jsonObj"); } var obj = Activator.CreateInstance(type, true) as IDictionary; //Get the value type of a generic dictionary Type valueType = type.GetGenericArguments()[1]; foreach (var kv in jsonObj) { obj.Add(kv.Key, DecodeValue(kv.Value, valueType)); } return(obj); }); ///My List<> Decoder SetDecoder(typeof(IList), (type, jsonObj) => { if (jsonObj == null) { throw new ArgumentNullException("jsonObj"); } if (!jsonObj.IsArray) { throw new ArgumentException("jsonObj: Expected a rootArray!"); } IList newList = null; //Get the value type of the generic enumerable Type listElementType = type.GetGenericArguments()[0]; if (type != typeof(IList) && typeof(IList).IsAssignableFrom(type)) { newList = Activator.CreateInstance(type, true) as IList; } else { Type genericListType = typeof(List <>).MakeGenericType(listElementType); newList = Activator.CreateInstance(genericListType) as IList; } for (int i = 0; i < jsonObj.rootArray.Count; i++) { newList.Add(DecodeValue(jsonObj.rootArray[i], listElementType)); } return(newList); }); SetDecoder(typeof(Array), (type, jsonObj) => { if (jsonObj == null) { throw new ArgumentNullException("jsonObj"); } if (!jsonObj.IsArray) { throw new ArgumentException("jsonObj: Expected a rootArray!"); } Type arrayElementType = type.GetElementType(); //bool nullable = arrayElementType.IsNullable(); var newArray = Array.CreateInstance(arrayElementType, jsonObj.rootArray.Count); for (int i = 0; i < jsonObj.rootArray.Count; i++) { var value = DecodeValue(jsonObj.rootArray[i], arrayElementType); //if (value != null || nullable) newArray.SetValue(value, i); newArray.SetValue(value, i); } return(newArray); }); defaultDecoder = ((type, jsonObj) => { if (jsonObj == null) { throw new ArgumentNullException("jsonObj"); } object obj = null; if (jsonObj[JsonEncoder.TypeNameString] != null) { obj = CreateObjectInstance(TypeFromStringMethod(jsonObj[JsonEncoder.TypeNameString].ToString())); if (obj == null) { throw new JSONDecodeException(string.Format("Unable to create object of type '{0}'!", jsonObj[JsonEncoder.TypeNameString].ToString())); } } else { obj = CreateObjectInstance(type); if (obj == null) { throw new JSONDecodeException($"Unable to create object of type '{type.Name}'!"); } } obj.EnumerateFields(JsonEncoder.DEFAULT_JSON_BINDING_FLAGS, (targetObj, field, jsonName) => { //Look for the field name in the json object's data var parameter = jsonObj[jsonName]; if (jsonObj.KeyExists(jsonName)) { try { field.SetValue(targetObj, DecodeValue(parameter, field.FieldType)); } catch (FieldAccessException fae) { throw new JSONDecodeException($"Unable to access field {field.Name} of type {field.FieldType.FriendlyName()}\n{fae.Message}", fae); } catch (TargetException te) { throw new JSONDecodeException($"The target object is null for the field {field.Name}!\n{te.Message}", te); } catch (Exception e) { throw new JSONDecodeException($"Unable to decode json name '{jsonName}' of type '{field.FieldType.FriendlyName()}'\n{e.Message}", e); } } //else //{ // //TODO: An error or warning?? //} }); return(obj); }); }
static object DecodeValue(object value, Type toType) { if ((value == null && (toType.IsClass || toType.IsInterface)) || (value.ToString() == "null" && toType != typeof(string))) { return(null); } if (value is JsonObject) { var childObj = value as JsonObject; if (toType.HasInterface(typeof(IDictionary))) { var decoder = GetDecoder(typeof(IDictionary)); return(decoder(toType, childObj)); } else { var decoder = GetDecoder(toType); if (decoder != null) { return(decoder(toType, childObj)); } else { return(Decode(childObj, toType)); } } } else if (convertableTypes.Contains(toType)) { return(ConvertValue(value, toType)); } else if (toType.IsEnum) { //parse an enum from a string if (value is string) { return(Enum.Parse(toType, value.ToString())); } else { //To parse an enum from a number return(Enum.ToObject(toType, value)); } } else if (toType == typeof(DateTime)) { DateTime dateTime; if (DateTime.TryParse(value.ToString(), out dateTime)) { return(dateTime); } else { throw new Exception("DateTime value incorrect format: " + value.ToString()); } } //Lists, Dictionaries, Arrays... else if (value is List <object> ) { var childObj = value as List <object>; DecodeMethod decoder = null; if (toType.IsGeneric(typeof(List <>))) { decoder = GetDecoder(typeof(IList)); } else if (toType.IsArray) { decoder = GetDecoder(typeof(Array)); } else { decoder = GetDecoderOrDefault(toType); } return(decoder(toType, new JsonObject(childObj))); } else if (toType.IsAssignableFrom(value.GetType())) { return(value); } else { throw new JSONDecodeException($"Unable to decode type: '{toType.FriendlyName()}' from {value}"); } }
static DecodeMethod GetDecoder(Type type) { DecodeMethod callback = null; decoders.TryGetValue(type, out callback); return(callback); }
public static void SetDecoder(Type type, DecodeMethod decodeFunc) { decoders[type] = decodeFunc; }