コード例 #1
0
        object RootDictionary(object parse, ReflectionCache type)
        {
            var             g = type.ArgumentReflections;
            ReflectionCache c1 = g[0], c2 = g[1];
            var             mk = c1.DeserializeMethod;
            var             m  = c2.DeserializeMethod;
            var             d  = parse as JsonDict;

            if (d != null)
            {
                IDictionary o = (IDictionary)type.Instantiate();

                foreach (var kv in d)
                {
                    o.Add(mk(this, kv.Key, c1), m(this, kv.Value, c2));
                }

                return(o);
            }
            var a = parse as JsonArray;

            if (a != null)
            {
                return(CreateDictionary(a, type));
            }

            return(null);
        }
コード例 #2
0
        object CreateStringKeyDictionary(JsonDict reader, ReflectionCache pt)
        {
            var col = (IDictionary)pt.Instantiate();
            // NOTE: argument 0 is not used
            ReflectionCache ec = pt.ArgumentReflections != null ? pt.ArgumentReflections[1] : null;
            var             m  = ec != null ? ec.DeserializeMethod : RevertUndefined;

            foreach (KeyValuePair <string, object> values in reader)
            {
                col.Add(values.Key, m(this, values.Value, ec));
            }
            return(col);
        }
コード例 #3
0
        object RootList(object parse, ReflectionCache type)
        {
            var   ec = type.ArgumentReflections[0];
            var   m  = ec.DeserializeMethod;
            IList o  = (IList)type.Instantiate();

            foreach (var k in (IList)parse)
            {
                _usingglobals = false;
                object v = m(this, k, ec);
                o.Add(v);
            }
            return(o);
        }
コード例 #4
0
        object CreateDictionary(JsonArray reader, ReflectionCache pt)
        {
            IDictionary     col = (IDictionary)pt.Instantiate();
            ReflectionCache c1 = null, c2 = null;

            if (pt.ArgumentReflections != null)
            {
                c1 = pt.ArgumentReflections[0];
                c2 = pt.ArgumentReflections[1];
            }
            var mk = c1.DeserializeMethod;
            var mv = c2.DeserializeMethod;

            foreach (JsonDict values in reader)
            {
                col.Add(mk(this, values["k"], c1), mv(this, values["v"], c2));
            }

            return(col);
        }
コード例 #5
0
        object CreateList(JsonArray data, ReflectionCache listType, object input)
        {
            var    ec  = listType.ArgumentReflections != null ? listType.ArgumentReflections[0] : null;
            var    r   = listType.ItemDeserializer;
            object l   = input ?? listType.Instantiate();
            IList  col = l as IList;

            if (col != null)
            {
                if (r != null)
                {
                    foreach (var item in data)
                    {
                        // TODO: determine whether item type is nullable
                        col.Add(item != null ? r(this, item, ec) : null);
                    }
                    return(col);
                }
            }
            var a = listType.AppendItem;

            if (a != null)
            {
                if (l == null)
                {
                    throw new JsonSerializationException("The collection member typed \"" + listType.AssemblyName + "\" was null and could not be instantiated");
                }
                foreach (var item in data)
                {
                    a(l, r(this, item, ec));
                }
                return(l);
            }
            // TODO: candidate of code clean-up.
            Type et = listType.ArgumentTypes != null ? listType.ArgumentTypes[0] : null;

            // create an array of objects
            foreach (var o in data)
            {
                if (o is IDictionary)
                {
                    col.Add(CreateObject((JsonDict)o, ec, null));
                }

                else if (o is JsonArray)
                {
                    if (et.IsGenericType)
                    {
                        col.Add(o);                         //).ToArray());
                    }
                    else
                    {
                        col.Add(((JsonArray)o).ToArray());
                    }
                }
                else
                {
                    col.Add(ChangeType(o, et));
                }
            }
            return(col);
        }
コード例 #6
0
        /// <summary>
        /// Deserializes an object.
        /// </summary>
        /// <param name="data">The data to be deserialized.</param>
        /// <param name="type">The reflection cache of the type.</param>
        /// <param name="input">The data container. If this value is not null, deserialized members will be written to it. If null, new object will be created.</param>
        /// <returns>The deserialized object.</returns>
        /// <exception cref="JsonSerializationException">Cannot determine type from <paramref name="data"/>.</exception>
        internal object CreateObject(JsonDict data, ReflectionCache type, object input)
        {
            if (data.RefIndex > 0)
            {
                object v = null;
                _cirrev.TryGetValue(data.RefIndex, out v);
                return(v);
            }

            if (data.Types != null && data.Types.Count > 0)
            {
                _usingglobals = true;
                globaltypes   = new Dictionary <string, object> ();
                foreach (var kv in data.Types)
                {
                    globaltypes.Add((string)kv.Value, kv.Key);
                }
            }

            var  tn    = data.Type;
            bool found = (tn != null && tn.Length > 0);

#if !SILVERLIGHT
            if (found == false && type != null && typeof(object).Equals(type.Type))
            {
                return(data);
            }
#endif
            if (found)
            {
                if (_usingglobals)
                {
                    object tname = "";
                    if (globaltypes != null && globaltypes.TryGetValue(data.Type, out tname))
                    {
                        tn = (string)tname;
                    }
                }
                type = _manager.GetReflectionCache(Reflection.Instance.GetTypeFromCache(tn));
            }

            if (type == null)
            {
                throw new JsonSerializationException("Cannot determine type");
            }

            object o = input;
            if (o == null)
            {
                o = _params.ParametricConstructorOverride
                                        ? System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type.Type)
                                        : type.Instantiate();
            }
            int circount = 0;
            // dictionary lookup makes it impossible to use objects with a custom GetHashCode based on (unchanging) properties:
            if (_circobj.TryGetValue(o, out circount) == false)
            {
                circount = _circobj.Count + 1;
                _circobj.Add(o, circount);
                _cirrev.Add(circount, o);
            }

            var si = type.Interceptor;
            if (si != null)
            {
                si.OnDeserializing(o);
            }
            Dictionary <string, JsonMemberSetter> props = type.Setters;
            //TODO: Candidate to removal of unknown use of map
            //if (data.Map != null) {
            //	ProcessMap (o, props, data.Map);
            //}
            foreach (var kv in data)
            {
                var n = kv.Key;
                var v = kv.Value;
                JsonMemberSetter pi;
                if (props.TryGetValue(n, out pi) == false || pi.CanWrite == false && pi.Member.JsonDataType != JsonDataType.List)
                {
                    continue;
                }
                MemberCache m         = pi.Member;
                var         ji        = new JsonItem(n, v, false);
                bool        converted = false;
                // TODO: Convert items for types implements IEnumerable and Add(?) method
                if (v is IList && pi.ItemConverter != null)
                {
                    converted = ConvertItems(pi, ji);
                }
                if (pi.Converter != null || m.MemberTypeReflection.Converter != null)
                {
                    ConvertProperty(o, pi, ji);
                }

                object oset = null;
                // use the converted value
                if (converted || ReferenceEquals(ji._Value, v) == false)
                {
                    if (pi.CanWrite == false && m.JsonDataType == JsonDataType.List)
                    {
                        ji._Value = CreateList((JsonArray)ji._Value, m.MemberTypeReflection, m.Getter(o));
                    }
                    if (ji._Value != null || m.IsClass || m.IsNullable)
                    {
                        oset = ji._Value;
                        goto SET_VALUE;
                    }
                    continue;
                }
                // process null value
                if (ji._Value == null)
                {
                    var i = new JsonItem(n, null, false);
                    if (si != null && si.OnDeserializing(o, i) == false)
                    {
                        continue;
                    }
                    if (i.Value != null || m.IsClass || m.IsNullable)
                    {
                        o = m.Setter(o, i.Value);
                    }
                    continue;
                }
                v = ji._Value;
                // set member value
                switch (m.JsonDataType)
                {
                case JsonDataType.Undefined: goto default;

                case JsonDataType.Int: oset = (int)(long)v; break;

                case JsonDataType.String:
                case JsonDataType.Bool:
                case JsonDataType.Long: oset = v; break;

                case JsonDataType.Double: oset = v is long?(double)(long)v : (double)v; break;

                case JsonDataType.Single: oset = v is long?(float)(long)v : (float)(double)v; break;

                case JsonDataType.DateTime: oset = CreateDateTime(this, v); break;

                case JsonDataType.Guid: oset = CreateGuid(v); break;

                case JsonDataType.ByteArray: oset = Convert.FromBase64String((string)v); break;

                case JsonDataType.List:
                    if (m.MemberTypeReflection.CollectionName != null)
                    {
                        goto default;
                    }
                    oset = CreateList((JsonArray)v, m.MemberTypeReflection, pi.CanWrite && (m.IsClass || m.IsStruct) ? null : m.Getter(o));
                    break;

                case JsonDataType.Object: oset = v; break;

                default:
                    if (m.DeserializeMethod != null)
                    {
                        oset = m.MemberTypeReflection.DeserializeMethod(this, ji._Value, m.MemberTypeReflection);
                        goto SET_VALUE;
                    }
                    if ((m.IsClass || m.IsStruct) && v is JsonDict)
                    {
                        oset = CreateObject((JsonDict)v, m.MemberTypeReflection, m.Getter(o));
                    }

                    else if (v is JsonArray)
                    {
                        oset = CreateArray((JsonArray)v, _manager.GetReflectionCache(typeof(object[])));
                    }

                    else if (m.IsValueType)
                    {
                        oset = ChangeType(v, m.ChangeType);
                    }

                    else
                    {
                        oset = v;
                    }

                    break;
                }
SET_VALUE:
                ji.Value = oset;
                if (si != null)
                {
                    if (si.OnDeserializing(o, ji) == false)
                    {
                        continue;
                    }
                }
                if (m.Setter != null)
                {
                    o = m.Setter(o, ji.Value);
                }
            }
            if (si != null)
            {
                si.OnDeserialized(o);
            }
            return(o);
        }