Esempio n. 1
0
 /// <summary>
 /// Converts the original value before serialization. If the serialized value is not the type of <typeparamref name="TOriginal"/>, the <paramref name="item"/> will be returned.
 /// </summary>
 /// <param name="item">The item to be deserialized.</param>
 public void SerializationConvert(JsonItem item)
 {
     if (item.Value is TOriginal)
     {
         item.Value = Convert(item.Name, (TOriginal)item.Value);
     }
 }
Esempio n. 2
0
 /// <summary>
 /// Reverts the serialized value to <typeparamref name="TOriginal"/>. If the serialized value is not the type of <typeparamref name="TSerialized"/>, nothing will be changed.
 /// </summary>
 /// <param name="item">The item to be deserialized.</param>
 public void DeserializationConvert(JsonItem item)
 {
     if (item.Value is TSerialized)
     {
         item.Value = Revert(item.Name, (TSerialized)item.Value);
     }
 }
Esempio n. 3
0
 bool IJsonInterceptor.OnDeserializing(object data, JsonItem item)
 {
     if (data is T)
     {
         return(OnDeserializing((T)data, item));
     }
     return(false);
 }
Esempio n. 4
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());
        }
Esempio n. 5
0
        void ConvertObject(IJsonConverter converter, JsonItem ji, Type sourceType)
        {
            var rt = converter.GetReversiveType(ji);
            var xv = ji._Value;

            if (xv != null && rt != null && sourceType.Equals(xv.GetType()) == false)
            {
                var c  = _manager.GetReflectionCache(rt);
                var jt = Reflection.GetJsonDataType(rt);
                if (jt != JsonDataType.Undefined)
                {
                    xv = c.DeserializeMethod(this, xv, c);
                }
                else if (xv is JsonDict)
                {
                    xv = CreateObject((JsonDict)xv, c, null);
                }
            }
            ji._Value = xv;
            converter.DeserializationConvert(ji);
        }
Esempio n. 6
0
        void ConvertProperty(object o, JsonMemberSetter pi, JsonItem ji)
        {
            var pc = pi.Converter ?? pi.Member.MemberTypeReflection.Converter;
            var rt = pc.GetReversiveType(ji);
            var xv = ji._Value;

            if (xv != null && rt != null && pi.Member.MemberType.Equals(xv.GetType()) == false)
            {
                var c  = _manager.GetReflectionCache(rt);
                var jt = Reflection.GetJsonDataType(rt);
                if (jt != JsonDataType.Undefined)
                {
                    xv = c.DeserializeMethod(this, xv, c);
                }
                else if (xv is JsonDict)
                {
                    xv = CreateObject((JsonDict)xv, c, pi.Member.Getter(o));
                }
            }
            ji._Value = xv;
            pc.DeserializationConvert(ji);
        }
Esempio n. 7
0
        static bool ConvertItems(JsonMemberSetter pi, JsonItem ji)
        {
            var vl        = ji._Value as IList;
            var l         = vl.Count;
            var converted = false;
            var ai        = new JsonItem(ji._Name, null, false);

            for (int i = 0; i < l; i++)
            {
                var vi = vl[i];
                ai._Value = vi;
                pi.ItemConverter.DeserializationConvert(ai);
                if (ReferenceEquals(vi, ai._Value) == false)
                {
                    vl[i]     = ai._Value;
                    converted = true;
                }
            }
            if (converted)
            {
                if (pi.Member.JsonDataType == JsonDataType.Array)
                {
                    ji._Value = Array.CreateInstance(pi.Member.ElementType, l);
                    vl.CopyTo((Array)ji._Value, 0);
                }
                else if (pi.Member.JsonDataType == JsonDataType.List)
                {
                    ji._Value = pi.Member.MemberTypeReflection.Instantiate();
                    var gl = ji._Value as IList;
                    for (int i = 0; i < l; i++)
                    {
                        gl.Add(vl[i]);
                    }
                }
            }

            return(converted);
        }
Esempio n. 8
0
 /// <summary>
 /// Returns the expected type for <paramref name="item"/>. The default implementation returns <typeparamref name="TSerialized"/>.
 /// </summary>
 /// <param name="item">The item to be deserialized.</param>
 /// <returns>The type of <typeparamref name="TSerialized"/>.</returns>
 public virtual Type GetReversiveType(JsonItem item)
 {
     return(_SerializedType);
 }
Esempio n. 9
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);
        }
Esempio n. 10
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);
        }
Esempio n. 11
0
        // HACK: This is a very long function, individual parts in regions are made inline for better performance
        void WriteObject(object obj)
        {
            #region Detect Circular Reference
            var ci = 0;
            if (_cirobj.TryGetValue(obj, out ci) == false)
            {
                _cirobj.Add(obj, _cirobj.Count + 1);
            }
            else
            {
                if (_currentDepth > 0 && _useExtensions && _params.InlineCircularReferences == false)
                {
                    //_circular = true;
                    _output.Append("{\"" + JsonDict.ExtRefIndex + "\":");
                    _output.Append(ValueConverter.Int32ToString(ci));
                    _output.Append("}");
                    return;
                }
            }
            #endregion
            var def = _manager.GetReflectionCache(obj.GetType());
            var si  = def.Interceptor;
            if (si != null && si.OnSerializing(obj) == false)
            {
                return;
            }
            #region Locate Extension Insertion Position
            if (_useGlobalTypes == false)
            {
                _output.Append('{');
            }
            else
            {
                if (_before == 0)
                {
                    _output.Append('{');
                    _before = _output.Length;
                }
                else
                {
                    _output.Append('{');
                }
            }
            #endregion

            _currentDepth++;
            if (_currentDepth > _maxDepth)
            {
                throw new JsonSerializationException("Serializer encountered maximum depth of " + _maxDepth);
            }

            //var map = new Dictionary<string, string> ();
            var append = false;
            #region Write Type Reference
            if (_useExtensions)
            {
                if (_useGlobalTypes == false)
                {
                    WritePairFast(JsonDict.ExtType, def.AssemblyName);
                }
                else
                {
                    var dt = 0;
                    var ct = def.AssemblyName;
                    if (_globalTypes.TryGetValue(ct, out dt) == false)
                    {
                        dt = _globalTypes.Count + 1;
                        _globalTypes.Add(ct, dt);
                    }
                    WritePairFast(JsonDict.ExtType, ValueConverter.Int32ToString(dt));
                }
                append = true;
            }
            #endregion

            var g = def.Getters;
            var c = g.Length;
            for (int ii = 0; ii < c; ii++)
            {
                var p = g[ii];
                var m = p.Member;
                #region Skip Members Not For Serialization
                if (p.Serializable == TriState.False)
                {
                    continue;
                }
                if (p.Serializable == TriState.Default)
                {
                    if (m.IsStatic && _params.SerializeStaticMembers == false ||
                        m.IsReadOnly && m.MemberTypeReflection.AppendItem == null &&
                        (m.IsProperty && _showReadOnlyProperties == false || m.IsProperty == false && _showReadOnlyFields == false))
                    {
                        continue;
                    }
                }
                #endregion
                var ji = new JsonItem(m.MemberName, m.Getter(obj), true);
                if (si != null && si.OnSerializing(obj, ji) == false)
                {
                    continue;
                }
                var cv = p.Converter ?? m.MemberTypeReflection.Converter;
                if (cv != null)
                {
                    cv.SerializationConvert(ji);
                }
                #region Convert Items
                if (p.ItemConverter != null)
                {
                    var ev = ji._Value as IEnumerable;
                    if (ev != null)
                    {
                        var ai = new JsonItem(ji.Name, null, false);
                        var ol = new List <object> ();
                        foreach (var item in ev)
                        {
                            ai.Value = item;
                            p.ItemConverter.SerializationConvert(ai);
                            ol.Add(ai.Value);
                        }
                        ji._Value = ol;
                    }
                }
                #endregion
                #region Determine Serialized Field Name
                if (p.SpecificName)
                {
                    if (ji._Value == null || p.TypedNames == null || p.TypedNames.TryGetValue(ji._Value.GetType(), out ji._Name) == false)
                    {
                        ji._Name = p.SerializedName;
                    }
                }
                else
                {
                    ji._Name = p.SerializedName;
                }
                #endregion
                #region Skip Null, Default Value or Empty Collection
                if (_params.SerializeNullValues == false && (ji._Value == null || ji._Value is DBNull))
                {
                    continue;
                }
                if (p.HasNonSerializedValue && Array.IndexOf(p.NonSerializedValues, ji._Value) != -1)
                {
                    // ignore fields with default value
                    continue;
                }
                if (m.IsCollection && _params.SerializeEmptyCollections == false)
                {
                    var vc = ji._Value as ICollection;
                    if (vc != null && vc.Count == 0)
                    {
                        continue;
                    }
                }
                #endregion
                if (append)
                {
                    _output.Append(',');
                }

                #region Write Name
                if (p.SpecificName)
                {
                    WriteStringFast(ji._Name);
                    _output.Append(':');
                }
                else
                {
                    _naming.WriteName(_output, ji._Name);
                }
                #endregion
                #region Write Value
                if (m.SerializeMethod != null && cv == null)
                {
                    var v = ji._Value;
                    if (v == null || v is DBNull)
                    {
                        _output.Append("null");
                    }
                    else if (m.MemberTypeReflection.CollectionName != null)
                    {
                        WriteObject(v);
                    }
                    else
                    {
                        m.SerializeMethod(this, v);
                    }
                }
                else
                {
                    WriteValue(ji._Value);
                }
                #endregion

                append = true;
            }
            #region Write Inherited Collection
            if (def.CollectionName != null && def.SerializeMethod != null)
            {
                if (append)
                {
                    _output.Append(',');
                }
                WriteStringFast(def.CollectionName);
                _output.Append(':');
                def.SerializeMethod(this, obj);
                append = true;
            }
            #endregion
            #region Write Extra Values
            if (si != null)
            {
                var ev = si.SerializeExtraValues(obj);
                if (ev != null)
                {
                    foreach (var item in ev)
                    {
                        if (append)
                        {
                            _output.Append(',');
                        }
                        WritePair(item._Name, item._Value);
                        append = true;
                    }
                }
                si.OnSerialized(obj);
            }
            #endregion
            _currentDepth--;
            _output.Append('}');
        }
Esempio n. 12
0
 /// <summary>
 /// This method is called before deserializing a field or a property. If the method returns false, the member will not be deserialized.
 /// </summary>
 /// <param name="data">The container object.</param>
 /// <param name="item">The item to be deserialized.</param>
 /// <returns>Whether the member should be deserialized.</returns>
 public virtual bool OnDeserializing(T data, JsonItem item)
 {
     return(true);
 }