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);
        }
Exemple #2
0
 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));
 }
Exemple #3
0
 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;
 }