/** 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);
		}
예제 #2
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;
            }

            switch (Type.GetTypeCode(type))
            {
            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) != 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--;
                }
            }
        }
예제 #3
0
 public virtual void AddTypeConverter(JsonConverter converter)
 {
     converters.Add(converter);
     converter.CurrentReader = CurrentReader;
 }
예제 #4
0
 /** 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);
 }