예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
0
        object CreateArray(JsonArray data, ReflectionCache arrayType)
        {
            var   l   = data.Count;
            var   ec  = arrayType.ArgumentReflections[0];
            Array col = Array.CreateInstance(ec.Type, l);
            var   r   = arrayType.ItemDeserializer;

            if (r != null)
            {
                for (int i = 0; i < l; i++)
                {
                    var ob = data[i];
                    if (ob == null)
                    {
                        continue;
                    }
                    col.SetValue(r(this, ob, ec), i);
                }
                return(col);
            }

            // TODO: candidate of code clean-up
            // create an array of objects
            for (int i = 0; i < l; i++)
            {
                var ob = data[i];
                if (ob == null)
                {
                    continue;
                }
                if (ob is IDictionary)
                {
                    col.SetValue(CreateObject((JsonDict)ob, ec, null), i);
                }
                // support jagged array
                else if (ob is ICollection)
                {
                    col.SetValue(CreateArray((JsonArray)ob, ec), i);
                }
                else
                {
                    col.SetValue(ChangeType(ob, ec.Type), i);
                }
            }

            return(col);
        }
예제 #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 CreateMultiDimensionalArray(JsonArray data, ReflectionCache arrayType)
        {
            ReflectionCache ec = arrayType.ArgumentReflections[0];
            Type            et = ec.Type;
            var             ar = arrayType.Type.GetArrayRank();
            var             ub = new int[ar];
            var             d  = data;

            // get upper bounds
            for (int i = 0; i < ar; i++)
            {
                var l = d.Count;
                ub[i] = l;
                if (i == ar - 1)
                {
                    break;
                }
                JsonArray a = null;
                for (int j = 0; j < l; j++)
                {
                    a = d[j] as JsonArray;
                    if (d != null)
                    {
                        d = a;
                        break;
                    }
                }
                if (a == null)
                {
                    throw new JsonSerializationException("The rank of the multi-dimensional array does not match.");
                }
            }
            var   mdi = new int[ar];
            Array col = Array.CreateInstance(ec.Type, ub);
            var   m   = arrayType.ItemDeserializer;
            var   ri  = 0;

            SetMultiDimensionalArrayValue(data, ec, ub, mdi, col, m, ri);
            return(col);
        }
예제 #6
0
        /// <summary>
        /// Creates a JSON representation for an object with parameter and serialization manager override on this call.
        /// </summary>
        /// <param name="obj">The object to be serialized.</param>
        /// <param name="param">The <see cref="JSONParameters"/> to control serialization.</param>
        /// <param name="manager">The <see cref="SerializationManager"/> to control advanced JSON serialization.</param>
        /// <returns>The serialized JSON string.</returns>
        public static string ToJSON(object obj, JSONParameters param, SerializationManager manager)
        {
            //param.FixValues();

            if (obj == null)
            {
                return("null");
            }

            if (param == null)
            {
                throw new ArgumentNullException("param");
            }
            if (manager == null)
            {
                throw new ArgumentNullException("manager");
            }

            ReflectionCache c = manager.GetReflectionCache(obj.GetType());

            return(new JsonSerializer(param, manager).ConvertToJSON(obj, c));
        }
예제 #7
0
        internal ReflectionCache GetReflectionCache(Type type)
        {
            ReflectionCache c;

            if (_reflections.TryGetValue(type, out c))
            {
                return(c);
            }

            c = _reflections[type] = new ReflectionCache(type);
            if (c.ArgumentReflections != null)
            {
                var ar = c.ArgumentReflections;
                var at = c.ArgumentTypes;
                for (int i = ar.Length - 1; i >= 0; i--)
                {
                    ar[i] = GetReflectionCache(at[i]);
                }
            }
            ControlTypeSerializationSettings(type, c);
            return(c);
        }
예제 #8
0
        internal static object RevertChar(JsonDeserializer deserializer, object value, ReflectionCache type)
        {
            var s = value as string;

            return(s.Length > 0 ? s[0] : '\0');
        }
예제 #9
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);
        }
예제 #10
0
 internal static object RevertByteArray(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(Convert.FromBase64String((string)value));
 }
예제 #11
0
 internal static object RevertCustom(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer._manager.CreateCustom((string)value, type.Type));
 }
예제 #12
0
 internal static object RevertUInt64(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(value is double?(ulong)(double)value : (ulong)(long)value);
 }
예제 #13
0
        internal string ConvertToJSON(object obj, ReflectionCache cache)
        {
            if (cache.CommonType == ComplexType.Dictionary || cache.CommonType == ComplexType.List) {
                _useGlobalTypes = false;
            }

            var cv = cache.Converter;
            if (cv != null) {
                var ji = new JsonItem (String.Empty, obj, false);
                cv.SerializationConvert (ji);
                if (ReferenceEquals (obj, ji._Value) == false) {
                    obj = ji._Value;
                }
                cache = _manager.GetReflectionCache (obj.GetType ());
            }
            var m = cache.SerializeMethod;
            if (m != null) {
                if (cache.CollectionName != null) {
                    WriteObject (obj);
                }
                else {
                    m (this, obj);
                }
            }
            else {
                WriteValue (obj);
            }

            if (_useGlobalTypes && _globalTypes != null && _globalTypes.Count > 0) {
                var sb = new StringBuilder ();
                sb.Append ("\"" + JsonDict.ExtTypes + "\":{");
                var pendingSeparator = false;
                foreach (var kv in _globalTypes) {
                    sb.Append (pendingSeparator ? ",\"" : "\"");
                    sb.Append (kv.Key);
                    sb.Append ("\":\"");
                    sb.Append (ValueConverter.Int32ToString (kv.Value));
                    sb.Append ('\"');
                    pendingSeparator = true;
                }
                sb.Append ("},");
                _output.Insert (_before, sb.ToString ());
            }
            return _output.ToString ();
        }
예제 #14
0
 internal static object RevertHashTable(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.RootHashTable((JsonArray)value));
 }
예제 #15
0
 internal static object RevertSingle(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(value is double?(float)(double)value : (float)(long)value);
 }
예제 #16
0
 internal static object RevertList(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.CreateList((JsonArray)value, type, null));
 }
예제 #17
0
 internal static object RevertDataTable(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.CreateDataTable((JsonDict)value));
 }
예제 #18
0
 internal static object RevertMultiDimensionalArray(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.CreateMultiDimensionalArray((JsonArray)value, type));
 }
예제 #19
0
        internal static object RevertUndefined(JsonDeserializer deserializer, object value, ReflectionCache type)
        {
            if (value == null)
            {
                return(null);
            }
            var d = value as JsonDict;

            if (d != null)
            {
                return(deserializer.CreateObject(d, type, null));
            }
            var a = value as JsonArray;

            if (a != null)
            {
                return(deserializer.CreateList(a, type, null));
            }
            return(value);
        }
예제 #20
0
 internal static object RevertDateTime(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(CreateDateTime(deserializer, value));
 }
예제 #21
0
 internal static object RevertDecimal(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(value is double?(decimal)(double)value : (decimal)(long)value);
 }
예제 #22
0
 internal object Deserialize(JsonDeserializer deserializer, object value, ReflectionCache targetType)
 {
     var d = value as JsonDict;
     var o = DeserializeMethod (deserializer, d[CollectionName], targetType);
     return deserializer.CreateObject (d, targetType, o);
 }
예제 #23
0
        public object ToObject(string json, Type type)
        {
            object o = new JsonParser(json).Decode();

            if (o == null)
            {
                return(null);
            }

            ReflectionCache c = null;

            if (type != null)
            {
                c = _manager.GetReflectionCache(type);
                var cv = c.Converter;
                if (cv != null)
                {
                    var ji = new JsonItem(String.Empty, o, false);
                    ConvertObject(cv, ji, type);
                    if (ReferenceEquals(ji._Value, o) == false)
                    {
                        return(ji._Value);
                    }
                    if (c.CommonType == ComplexType.Dictionary ||
                        c.CommonType == ComplexType.List)
                    {
                        _usingglobals = false;
                    }
                }
                else if (c.DeserializeMethod != null)
                {
                    return(c.DeserializeMethod(this, o, c));
                }
            }
            else
            {
                _usingglobals = _params.UsingGlobalTypes;
            }

            var d = o as JsonDict;

            if (d != null)
            {
                if (type != null)
                {
#if !SILVERLIGHT
                    if (c.JsonDataType == JsonDataType.DataSet)
                    {
                        return(CreateDataSet(d));
                    }

                    if (c.JsonDataType == JsonDataType.DataTable)
                    {
                        return(CreateDataTable(d));
                    }
#endif
                    if (c.CommonType == ComplexType.Dictionary)                     // deserialize a dictionary
                    {
                        return(RootDictionary(o, c));
                    }
                }
                return(CreateObject(d, c, null));
            }
            var a = o as JsonArray;
            if (a != null)
            {
                if (type != null)
                {
                    if (c.CommonType == ComplexType.Dictionary)                     // k/v format
                    {
                        return(RootDictionary(o, c));
                    }

                    if (c.CommonType == ComplexType.List)                     // deserialize to generic list
                    {
                        return(RootList(o, c));
                    }

                    if (c.JsonDataType == JsonDataType.Hashtable)
                    {
                        return(RootHashTable(a));
                    }

                    if (c.CommonType == ComplexType.Array)
                    {
                        return(CreateArray(a, c));
                    }
                }
                return(a.ToArray());
            }

            if (type != null && o.GetType().Equals(type) == false)
            {
                return(ChangeType(o, type));
            }

            return(o);
        }
예제 #24
0
 internal static object RevertNameValueCollection(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(CreateNameValueCollection((JsonDict)value));
 }
예제 #25
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);
        }
예제 #26
0
 internal static object RevertStringKeyDictionary(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.CreateStringKeyDictionary((JsonDict)value, type));
 }
예제 #27
0
 internal static object RevertPrimitive(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(value);
 }
예제 #28
0
 internal static object RevertEnum(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.CreateEnum(value, type.Type));
 }
예제 #29
0
 internal static object RevertDictionary(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(deserializer.RootDictionary(value, type));
 }
예제 #30
0
 internal static object RevertGuid(JsonDeserializer deserializer, object value, ReflectionCache type)
 {
     return(CreateGuid(value));
 }