public JsonMemberSetter(MemberCache member)
 {
     MemberName = member.MemberName;
     Member     = member;
     CanWrite   = member.IsReadOnly == false;
 }
        /// <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);
        }
 public JsonMemberGetter(MemberCache cache)
 {
     Member         = cache;
     MemberName     = cache.MemberName;
     SerializedName = cache.MemberName;
 }
 public MemberCache(Type type, string name, MemberCache baseInfo)
     : this(baseInfo.MemberInfo, type, name)
 {
     Getter = baseInfo.Getter;
     Setter = baseInfo.Setter;
     IsProperty = baseInfo.IsProperty;
     IsStatic = baseInfo.IsStatic;
     IsReadOnly = baseInfo.IsReadOnly;
 }
 public JsonMemberSetter(MemberCache member)
 {
     MemberName = member.MemberName;
     Member = member;
     CanWrite = member.IsReadOnly == false;
 }
 public JsonMemberGetter(MemberCache cache)
 {
     Member = cache;
     MemberName = cache.MemberName;
     SerializedName = cache.MemberName;
 }
 public JsonPropertyInfo(MemberCache member)
 {
     MemberName = member.MemberName;
     Member = member;
     CanWrite = member.IsReadOnly == false;
 }
 public Getters(MemberCache cache)
 {
     Member = cache;
     MemberName = cache.MemberName;
     SerializedName = cache.MemberName;
 }