private static Dictionary <TKey, TValue> _DecodeEnumDictionary <TKey, TValue>(DeserializationContext context)
            where TKey : notnull
        {
            var serializer     = context.RootSerializer;
            var encodeDefaults = serializer.Options.EncodeDefaultValues;

            serializer.Options.EncodeDefaultValues = true;
            var enumFormat = serializer.Options.EnumSerializationFormat;

            serializer.Options.EnumSerializationFormat = EnumSerializationFormat.AsName;

            var output = new Dictionary <TKey, TValue>();
            var i      = 0;

            foreach (var kvp in context.LocalValue.Object)
            {
                var transformed = serializer.Options.DeserializationNameTransform(kvp.Key);
                context.Push(typeof(TKey), i.ToString(), transformed);
                context.Push(typeof(TKey), "Key", transformed);
                var key = (TKey)serializer.Deserialize(context) !;
                context.Pop();
                context.Pop();

                context.Push(typeof(TValue), kvp.Key, kvp.Value);
                output.Add(key, (TValue)serializer.Deserialize(context) !);
                context.Pop();
                i++;
            }

            serializer.Options.EnumSerializationFormat = enumFormat;
            serializer.Options.EncodeDefaultValues     = encodeDefaults;

            return(output);
        }
예제 #2
0
        private static Dictionary <SerializationInfo, object?> _DeserializeValues(DeserializationContext context,
                                                                                  IEnumerable <SerializationInfo> members,
                                                                                  bool ignoreCase)
        {
            var dict = new Dictionary <SerializationInfo, object?>();

            foreach (var memberInfo in members)
            {
                var name      = memberInfo.SerializationName;
                var transform = memberInfo.ShouldTransform
                                        ? context.RootSerializer.Options.DeserializationNameTransform
                                        : s => s;

                var visited = new HashSet <string>(ignoreCase ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal);
                if (_TryGetKeyValue(context.LocalValue, name, ignoreCase, transform, out var value) &&
                    visited.Add(name))
                {
                    Type type;
                    if (memberInfo.MemberInfo is PropertyInfo info)
                    {
                        type = info.PropertyType;
                    }
                    else
                    {
                        type = ((FieldInfo)memberInfo.MemberInfo).FieldType;
                    }
                    context.Push(type, memberInfo.SerializationName, value);
                    var valueObj = context.RootSerializer.Deserialize(context);
                    context.Pop();
                    dict.Add(memberInfo, valueObj);
                }
            }

            return(dict);
        }
        private static Dictionary <TKey, TValue> _Decode <TKey, TValue>(DeserializationContext context)
            where TKey : notnull
        {
            var json = context.LocalValue;

            if (typeof(TKey) == typeof(string))
            {
                return(json.Object.ToDictionary(kvp => (TKey)(object)kvp.Key,
                                                kvp =>
                {
                    context.Push(typeof(TValue), kvp.Key.ToString(), kvp.Value);
                    var value = (TValue)context.RootSerializer.Deserialize(context) !;
                    context.Pop();
                    return value;
                }));
            }

            if (typeof(Enum).GetTypeInfo().IsAssignableFrom(typeof(TKey).GetTypeInfo()))
            {
                return(_DecodeEnumDictionary <TKey, TValue>(context));
            }

            return(json.Array.Select((jv, i) => new { Value = jv, Index = i })
                   .ToDictionary(jv =>
            {
                var key = jv.Value.Object["Key"];
                context.Push(typeof(TKey), jv.Index.ToString(), key);
                context.Push(typeof(TKey), "Key", key);
                var obj = (TKey)context.RootSerializer.Deserialize(context) !;
                context.Pop();
                context.Pop();
                return obj;
            },
                                 jv =>
            {
                var value = jv.Value.Object["Value"];
                context.Push(typeof(TValue), jv.Index.ToString(), value);
                context.Push(typeof(TValue), "Value", value);
                var obj = (TValue)context.RootSerializer.Deserialize(context) !;
                context.Pop();
                context.Pop();
                return obj;
            }));
        }
예제 #4
0
        private static Queue <T> _Decode <T>(DeserializationContext context)
        {
            var queue = new Queue <T>();

            for (int i = 0; i < context.LocalValue.Array.Count; i++)
            {
                context.Push(typeof(T), i.ToString(), context.LocalValue.Array[i]);
                queue.Enqueue((T)context.RootSerializer.Deserialize(context) !);
                context.Pop();
            }
            return(queue);
        }
        private static Stack <T> _Decode <T>(DeserializationContext context)
        {
            var array  = context.LocalValue.Array;
            var values = new T[array.Count];

            for (int i = 0; i < values.Length; i++)
            {
                context.Push(typeof(T), i.ToString(), array[i]);
                values[i] = (T)context.RootSerializer.Deserialize(context) !;
                context.Pop();
            }
            return(new Stack <T>(values));
        }
예제 #6
0
        private static List <T> _Decode <T>(DeserializationContext context)
        {
            var array = context.LocalValue.Array;
            var list  = new List <T>(array.Count);

            for (int i = 0; i < array.Count; i++)
            {
                context.Push(typeof(T), i.ToString(), array[i]);
                list.Add((T)context.RootSerializer.Deserialize(context) !);
                context.Pop();
            }
            return(list);
        }
예제 #7
0
        private static object _Decode(DeserializationContext context)
        {
            switch (context.LocalValue.Type)
            {
            case JsonValueType.Number:
                return(context.LocalValue.Number);

            case JsonValueType.String:
                return(context.LocalValue.String);

            case JsonValueType.Boolean:
                return(context.LocalValue.Boolean);

            case JsonValueType.Array:
                return(context.LocalValue.Array.Select((value, i) =>
                {
                    context.Push(typeof(object), i.ToString(), value);
                    var json = context.RootSerializer.Deserialize(context);
                    context.Pop();
                    return json;
                }).ToList());

            case JsonValueType.Object:
                var result = new ExpandoObject() as IDictionary <string, object?>;
                foreach (var kvp in context.LocalValue.Object)
                {
                    context.Push(typeof(object), kvp.Key, kvp.Value);
                    result[kvp.Key] = context.RootSerializer.Deserialize(context);
                    context.Pop();
                }
                return(result);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #8
0
        private static T?_Decode <T>(DeserializationContext context)
            where T : struct
        {
            if (context.LocalValue == JsonValue.Null)
            {
                return(null);
            }

            // this is a special case for the pointer in that we don't want to add a segment,
            // but we have to push something so that it can be popped.
            context.Push(typeof(T), null !, context.LocalValue);
            var value = (T)context.RootSerializer.Deserialize(context) !;

            context.Pop();

            return(value);
        }