/** Adds a converter to use to serialize otherwise non-serializable types.
		 * Good if you do not have the source and it throws error when trying to serialize it.
		 * For example the Unity3D Vector3 can be serialized using a special converter
		 */
		public virtual void AddTypeConverter (JsonConverter converter) {
			converters.Add (converter);
		}
Esempio n. 2
0
 public virtual void AddTypeConverter(JsonConverter converter)
 {
     converters.Add(converter);
 }
Esempio n. 3
0
        protected virtual void Write(object value, bool isProperty)
        {
            if (isProperty && this.settings.PrettyPrint)
            {
                this.Writer.Write(' ');
            }
            if (value == null)
            {
                this.Writer.Write(JsonReader.LiteralNull);
                return;
            }
            if (value is IJsonSerializable)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(string.Format("The maxiumum depth of {0} was exceeded. Check for cycles in object graph.", this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    ((IJsonSerializable)value).WriteJson(this);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }
            if (value is Enum)
            {
                this.Write((Enum)value);
                return;
            }
            Type          type      = value.GetType();
            JsonConverter converter = this.Settings.GetConverter(type);

            if (converter != null)
            {
                converter.Write(this, type, value);
                return;
            }
            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Empty:
            case TypeCode.DBNull:
                this.Writer.Write(JsonReader.LiteralNull);
                return;

            case TypeCode.Boolean:
                this.Write((bool)value);
                return;

            case TypeCode.Char:
                this.Write((char)value);
                return;

            case TypeCode.SByte:
                this.Write((sbyte)value);
                return;

            case TypeCode.Byte:
                this.Write((byte)value);
                return;

            case TypeCode.Int16:
                this.Write((short)value);
                return;

            case TypeCode.UInt16:
                this.Write((ushort)value);
                return;

            case TypeCode.Int32:
                this.Write((int)value);
                return;

            case TypeCode.UInt32:
                this.Write((uint)value);
                return;

            case TypeCode.Int64:
                this.Write((long)value);
                return;

            case TypeCode.UInt64:
                this.Write((ulong)value);
                return;

            case TypeCode.Single:
                this.Write((float)value);
                return;

            case TypeCode.Double:
                this.Write((double)value);
                return;

            case TypeCode.Decimal:
                this.Write((decimal)value);
                return;

            case TypeCode.DateTime:
                this.Write((DateTime)value);
                return;

            case TypeCode.String:
                this.Write((string)value);
                return;
            }
            if (value is Guid)
            {
                this.Write((Guid)value);
                return;
            }
            if (value is Uri)
            {
                this.Write((Uri)value);
                return;
            }
            if (value is TimeSpan)
            {
                this.Write((TimeSpan)value);
                return;
            }
            if (value is Version)
            {
                this.Write((Version)value);
                return;
            }
            if (value is IDictionary)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(string.Format("The maxiumum depth of {0} was exceeded. Check for cycles in object graph.", this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    this.WriteObject((IDictionary)value);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }
            if (type.GetInterface(JsonReader.TypeGenericIDictionary) != null)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(string.Format("The maxiumum depth of {0} was exceeded. Check for cycles in object graph.", this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    this.WriteDictionary((IEnumerable)value);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }
            if (value is IEnumerable)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(string.Format("The maxiumum depth of {0} was exceeded. Check for cycles in object graph.", this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    this.WriteArray((IEnumerable)value);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }
            try
            {
                if (isProperty)
                {
                    this.depth++;
                    if (this.depth > this.settings.MaxDepth)
                    {
                        throw new JsonSerializationException(string.Format("The maxiumum depth of {0} was exceeded. Check for cycles in object graph.", this.settings.MaxDepth));
                    }
                    this.WriteLine();
                }
                this.WriteObject(value, type, false);
            }
            finally
            {
                if (isProperty)
                {
                    this.depth--;
                }
            }
        }
Esempio n. 4
0
        protected virtual void Write(object value, bool isProperty)
        {
            if (isProperty && this.settings.PrettyPrint)
            {
                this.Writer.Write(' ');
            }

            if (value == null)
            {
                this.Writer.Write(JsonReader.LiteralNull);
                return;
            }

            if (value is IJsonSerializable)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(String.Format(JsonWriter.ErrorMaxDepth, this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    ((IJsonSerializable)value).WriteJson(this);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }

            // must test enumerations before value types
            if (value is Enum)
            {
                this.Write((Enum)value);
                return;
            }

            // Type.GetTypeCode() allows us to more efficiently switch type
            // plus cannot use 'is' for ValueTypes
            Type type = value.GetType();

            JsonConverter converter = this.Settings.GetConverter(type);

            if (converter != null)
            {
                converter.Write(this, type, value);
                return;
            }

#if NETFX_CORE
            switch (type.GetTypeCode())
#else
            switch (Type.GetTypeCode(type))
#endif
            {
            case TypeCode.Boolean:
            {
                this.Write((Boolean)value);
                return;
            }

            case TypeCode.Byte:
            {
                this.Write((Byte)value);
                return;
            }

            case TypeCode.Char:
            {
                this.Write((Char)value);
                return;
            }

            case TypeCode.DateTime:
            {
                this.Write((DateTime)value);
                return;
            }

            case TypeCode.DBNull:
            case TypeCode.Empty:
            {
                this.Writer.Write(JsonReader.LiteralNull);
                return;
            }

            case TypeCode.Decimal:
            {
                // From MSDN:
                // Conversions from Char, SByte, Int16, Int32, Int64, Byte, UInt16, UInt32, and UInt64
                // to Decimal are widening conversions that never lose information or throw exceptions.
                // Conversions from Single or Double to Decimal throw an OverflowException
                // if the result of the conversion is not representable as a Decimal.
                this.Write((Decimal)value);
                return;
            }

            case TypeCode.Double:
            {
                this.Write((Double)value);
                return;
            }

            case TypeCode.Int16:
            {
                this.Write((Int16)value);
                return;
            }

            case TypeCode.Int32:
            {
                this.Write((Int32)value);
                return;
            }

            case TypeCode.Int64:
            {
                this.Write((Int64)value);
                return;
            }

            case TypeCode.SByte:
            {
                this.Write((SByte)value);
                return;
            }

            case TypeCode.Single:
            {
                this.Write((Single)value);
                return;
            }

            case TypeCode.String:
            {
                this.Write((String)value);
                return;
            }

            case TypeCode.UInt16:
            {
                this.Write((UInt16)value);
                return;
            }

            case TypeCode.UInt32:
            {
                this.Write((UInt32)value);
                return;
            }

            case TypeCode.UInt64:
            {
                this.Write((UInt64)value);
                return;
            }

            default:
            case TypeCode.Object:
            {
                // all others must be explicitly tested
                break;
            }
            }

            if (value is Guid)
            {
                this.Write((Guid)value);
                return;
            }

            if (value is Uri)
            {
                this.Write((Uri)value);
                return;
            }

            if (value is TimeSpan)
            {
                this.Write((TimeSpan)value);
                return;
            }

            if (value is Version)
            {
                this.Write((Version)value);
                return;
            }

            // IDictionary test must happen BEFORE IEnumerable test
            // since IDictionary implements IEnumerable
            if (value is IDictionary)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(String.Format(JsonWriter.ErrorMaxDepth, this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    this.WriteObject((IDictionary)value);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }

            if (type.GetInterface(JsonReader.TypeGenericIDictionary, false) != null)
            {
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(String.Format(JsonWriter.ErrorMaxDepth, this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }

                    this.WriteDictionary((IEnumerable)value);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }

            // IDictionary test must happen BEFORE IEnumerable test
            // since IDictionary implements IEnumerable
            if (value is IEnumerable)
            {
#if !UNITY3D
                if (value is XmlNode)
                {
                    this.Write((System.Xml.XmlNode)value);
                    return;
                }
#endif
                try
                {
                    if (isProperty)
                    {
                        this.depth++;
                        if (this.depth > this.settings.MaxDepth)
                        {
                            throw new JsonSerializationException(String.Format(JsonWriter.ErrorMaxDepth, this.settings.MaxDepth));
                        }
                        this.WriteLine();
                    }
                    this.WriteArray((IEnumerable)value);
                }
                finally
                {
                    if (isProperty)
                    {
                        this.depth--;
                    }
                }
                return;
            }

            // structs and classes
            try
            {
                if (isProperty)
                {
                    this.depth++;
                    if (this.depth > this.settings.MaxDepth)
                    {
                        throw new JsonSerializationException(String.Format(JsonWriter.ErrorMaxDepth, this.settings.MaxDepth));
                    }
                    this.WriteLine();
                }
                this.WriteObject(value, type);
            }
            finally
            {
                if (isProperty)
                {
                    this.depth--;
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Convert from JSON string to Object graph of specific Type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>

        /*public T Deserialize<T>(int start)
         * {
         *      this.index = start;
         *
         *      // should this run through a preliminary test here?
         *      return (T)this.Read(typeof(T), false);
         * }*/

        private object Read(Type expectedType, bool typeIsHint)
        {
            if (expectedType == typeof(Object))
            {
                expectedType = null;
            }

            JsonToken token = this.Tokenize();

            if (expectedType != null && !expectedType.IsPrimitive)
            {
                JsonConverter converter = this.Settings.GetConverter(expectedType);
                if (converter != null)
                {
                    object val;
                    try {
                        val = Read(typeof(Dictionary <string, object>), false);
                        Dictionary <string, object> dict = val as Dictionary <string, object>;
                        if (dict == null)
                        {
                            return(null);
                        }
                        object obj = converter.Read(this, expectedType, dict);
                        return(obj);
                    } catch (JsonTypeCoercionException e) {
                        Console.WriteLine("Could not cast to dictionary for converter processing. Ignoring field.\n" + e);
                    }
                    return(null);
                }
            }

            switch (token)
            {
            case JsonToken.ObjectStart:
            {
                return(this.ReadObject(typeIsHint ? null : expectedType));
            }

            case JsonToken.ArrayStart:
            {
                return(this.ReadArray(typeIsHint ? null : expectedType));
            }

            case JsonToken.String:
            {
                return(this.ReadString(typeIsHint ? null : expectedType));
            }

            case JsonToken.Number:
            {
                return(this.ReadNumber(typeIsHint ? null : expectedType));
            }

            case JsonToken.False:
            {
                this.index += JsonReader.LiteralFalse.Length;
                return(false);
            }

            case JsonToken.True:
            {
                this.index += JsonReader.LiteralTrue.Length;
                return(true);
            }

            case JsonToken.Null:
            {
                this.index += JsonReader.LiteralNull.Length;
                return(null);
            }

            case JsonToken.NaN:
            {
                this.index += JsonReader.LiteralNotANumber.Length;
                return(Double.NaN);
            }

            case JsonToken.PositiveInfinity:
            {
                this.index += JsonReader.LiteralPositiveInfinity.Length;
                return(Double.PositiveInfinity);
            }

            case JsonToken.NegativeInfinity:
            {
                this.index += JsonReader.LiteralNegativeInfinity.Length;
                return(Double.NegativeInfinity);
            }

            case JsonToken.Undefined:
            {
                this.index += JsonReader.LiteralUndefined.Length;
                return(null);
            }

            case JsonToken.End:
            default:
            {
                return(null);
            }
            }
        }