diff --git a/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
index dc70c575..cad2481f 100644
--- a/Src/Newtonsoft.Json/Converters/RegexConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
@@ -91,7 +91,7 @@ namespace Newtonsoft.Json.Converters
writer.WritePropertyName("Pattern");
writer.WriteValue(regex.ToString());
writer.WritePropertyName("Options");
- writer.WriteValue(regex.Options);
+ writer.WriteValue((int)regex.Options);
writer.WriteEndObject();
}
diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs
index 38a309e1..b4258909 100644
--- a/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/Src/Newtonsoft.Json/JsonWriter.cs
@@ -1234,6 +1234,18 @@ namespace Newtonsoft.Json
{
InternalWriteValue(JsonToken.Integer);
}
+
+ ///
+ /// Writes a value.
+ ///
+ /// The value to write.
+ public virtual void WriteValue(BigInteger? value)
+ {
+ if (value == null)
+ WriteNull();
+ else
+ WriteValue(value.Value);
+ }
#endif
///
@@ -1403,7 +1415,10 @@ namespace Newtonsoft.Json
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
else if (value is BigInteger)
{
- WriteValue((BigInteger)value);
+ if (nullable)
+ WriteValue((BigInteger?)value);
+ else
+ WriteValue((BigInteger)value);
return;
}
#endif
diff --git a/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs b/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
index f3ff93b5..23bdbc9d 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonPrimitiveContract.cs
@@ -24,6 +24,10 @@
#endregion
using System;
+using System.Collections.Generic;
+#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
+using System.Numerics;
+#endif
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
@@ -33,7 +37,58 @@ namespace Newtonsoft.Json.Serialization
///
public class JsonPrimitiveContract : JsonContract
{
- internal bool Nullable { get; set; }
+ private static readonly Dictionary TypeCodeMap =
+ new Dictionary
+ {
+ { typeof(char), PrimitiveTypeCode.Char },
+ { typeof(char?), PrimitiveTypeCode.CharNullable },
+ { typeof(bool), PrimitiveTypeCode.Boolean },
+ { typeof(bool?), PrimitiveTypeCode.BooleanNullable },
+ { typeof(sbyte), PrimitiveTypeCode.SByte },
+ { typeof(sbyte?), PrimitiveTypeCode.SByteNullable },
+ { typeof(short), PrimitiveTypeCode.Int16 },
+ { typeof(short?), PrimitiveTypeCode.Int16Nullable },
+ { typeof(ushort), PrimitiveTypeCode.UInt16 },
+ { typeof(ushort?), PrimitiveTypeCode.UInt16Nullable },
+ { typeof(int), PrimitiveTypeCode.Int32 },
+ { typeof(int?), PrimitiveTypeCode.Int32Nullable },
+ { typeof(byte), PrimitiveTypeCode.Byte },
+ { typeof(byte?), PrimitiveTypeCode.ByteNullable },
+ { typeof(uint), PrimitiveTypeCode.UInt32 },
+ { typeof(uint?), PrimitiveTypeCode.UInt32Nullable },
+ { typeof(long), PrimitiveTypeCode.Int64 },
+ { typeof(long?), PrimitiveTypeCode.Int64Nullable },
+ { typeof(ulong), PrimitiveTypeCode.UInt64 },
+ { typeof(ulong?), PrimitiveTypeCode.UInt64Nullable },
+ { typeof(float), PrimitiveTypeCode.Single },
+ { typeof(float?), PrimitiveTypeCode.SingleNullable },
+ { typeof(double), PrimitiveTypeCode.Double },
+ { typeof(double?), PrimitiveTypeCode.DoubleNullable },
+ { typeof(DateTime), PrimitiveTypeCode.DateTime },
+ { typeof(DateTime?), PrimitiveTypeCode.DateTimeNullable },
+#if !NET20
+ { typeof(DateTimeOffset), PrimitiveTypeCode.DateTimeOffset },
+ { typeof(DateTimeOffset?), PrimitiveTypeCode.DateTimeOffsetNullable },
+#endif
+ { typeof(decimal), PrimitiveTypeCode.Decimal },
+ { typeof(decimal?), PrimitiveTypeCode.DecimalNullable },
+ { typeof(Guid), PrimitiveTypeCode.Guid },
+ { typeof(Guid?), PrimitiveTypeCode.GuidNullable },
+ { typeof(TimeSpan), PrimitiveTypeCode.TimeSpan },
+ { typeof(TimeSpan?), PrimitiveTypeCode.TimeSpanNullable },
+#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
+ { typeof(BigInteger), PrimitiveTypeCode.BigInteger },
+ { typeof(BigInteger?), PrimitiveTypeCode.BigIntegerNullable },
+#endif
+ { typeof(Uri), PrimitiveTypeCode.Uri },
+ { typeof(string), PrimitiveTypeCode.String },
+ { typeof(byte[]), PrimitiveTypeCode.Bytes },
+#if !(PORTABLE || NETFX_CORE)
+ { typeof(DBNull), PrimitiveTypeCode.DBNull }
+#endif
+ };
+
+ internal PrimitiveTypeCode TypeCode { get; set; }
///
/// Initializes a new instance of the class.
@@ -44,7 +99,256 @@ namespace Newtonsoft.Json.Serialization
{
ContractType = JsonContractType.Primitive;
- Nullable = ReflectionUtils.IsNullable(underlyingType);
+ // get the underlying enum value
+ Type t;
+ if (ReflectionUtils.IsNullableType(underlyingType))
+ t = Nullable.GetUnderlyingType(underlyingType).IsEnum() ? ReflectionUtils.MakeGenericType(typeof(Nullable<>), Enum.GetUnderlyingType(Nullable.GetUnderlyingType(underlyingType))) : underlyingType;
+ else
+ t = underlyingType.IsEnum() ? Enum.GetUnderlyingType(underlyingType) : underlyingType;
+
+ PrimitiveTypeCode typeCode;
+ TypeCodeMap.TryGetValue(t, out typeCode);
+ TypeCode = typeCode;
+ }
+
+ internal void WriteValue(JsonWriter writer, object value)
+ {
+ switch (TypeCode)
+ {
+ case PrimitiveTypeCode.Char:
+ writer.WriteValue((char)value);
+ break;
+ case PrimitiveTypeCode.CharNullable:
+ if (value != null)
+ writer.WriteValue((char)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Boolean:
+ writer.WriteValue((bool)value);
+ break;
+ case PrimitiveTypeCode.BooleanNullable:
+ if (value != null)
+ writer.WriteValue((bool)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.SByte:
+ writer.WriteValue((sbyte)value);
+ break;
+ case PrimitiveTypeCode.SByteNullable:
+ if (value != null)
+ writer.WriteValue((sbyte)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Int16:
+ writer.WriteValue((short)value);
+ break;
+ case PrimitiveTypeCode.Int16Nullable:
+ if (value != null)
+ writer.WriteValue((short)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.UInt16:
+ writer.WriteValue((ushort)value);
+ break;
+ case PrimitiveTypeCode.UInt16Nullable:
+ if (value != null)
+ writer.WriteValue((ushort)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Int32:
+ writer.WriteValue((int)value);
+ break;
+ case PrimitiveTypeCode.Int32Nullable:
+ if (value != null)
+ writer.WriteValue((int)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Byte:
+ writer.WriteValue((byte)value);
+ break;
+ case PrimitiveTypeCode.ByteNullable:
+ if (value != null)
+ writer.WriteValue((byte)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.UInt32:
+ writer.WriteValue((uint)value);
+ break;
+ case PrimitiveTypeCode.UInt32Nullable:
+ if (value != null)
+ writer.WriteValue((uint)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Int64:
+ writer.WriteValue((long)value);
+ break;
+ case PrimitiveTypeCode.Int64Nullable:
+ if (value != null)
+ writer.WriteValue((long)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.UInt64:
+ writer.WriteValue((ulong)value);
+ break;
+ case PrimitiveTypeCode.UInt64Nullable:
+ if (value != null)
+ writer.WriteValue((ulong)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Single:
+ writer.WriteValue((float)value);
+ break;
+ case PrimitiveTypeCode.SingleNullable:
+ // use nullable WriteValue to handle NaN, Infinity with FloatFormatHandling
+ if (value != null)
+ writer.WriteValue((float?)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Double:
+ writer.WriteValue((double)value);
+ break;
+ case PrimitiveTypeCode.DoubleNullable:
+ // use nullable WriteValue to handle NaN, Infinity with FloatFormatHandling
+ if (value != null)
+ writer.WriteValue((double?)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.DateTime:
+ writer.WriteValue((DateTime)value);
+ break;
+ case PrimitiveTypeCode.DateTimeNullable:
+ if (value != null)
+ writer.WriteValue((DateTime)value);
+ else
+ writer.WriteNull();
+ break;
+#if !NET20
+ case PrimitiveTypeCode.DateTimeOffset:
+ writer.WriteValue((DateTimeOffset)value);
+ break;
+ case PrimitiveTypeCode.DateTimeOffsetNullable:
+ if (value != null)
+ writer.WriteValue((DateTimeOffset)value);
+ else
+ writer.WriteNull();
+ break;
+#endif
+ case PrimitiveTypeCode.Decimal:
+ writer.WriteValue((decimal)value);
+ break;
+ case PrimitiveTypeCode.DecimalNullable:
+ if (value != null)
+ writer.WriteValue((decimal)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.Guid:
+ writer.WriteValue((Guid)value);
+ break;
+ case PrimitiveTypeCode.GuidNullable:
+ if (value != null)
+ writer.WriteValue((Guid)value);
+ else
+ writer.WriteNull();
+ break;
+ case PrimitiveTypeCode.TimeSpan:
+ writer.WriteValue((TimeSpan)value);
+ break;
+ case PrimitiveTypeCode.TimeSpanNullable:
+ if (value != null)
+ writer.WriteValue((TimeSpan)value);
+ else
+ writer.WriteNull();
+ break;
+#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
+ case PrimitiveTypeCode.BigInteger:
+ writer.WriteValue((BigInteger)value);
+ break;
+ case PrimitiveTypeCode.BigIntegerNullable:
+ if (value != null)
+ writer.WriteValue((BigInteger)value);
+ else
+ writer.WriteNull();
+ break;
+#endif
+ case PrimitiveTypeCode.Uri:
+ writer.WriteValue((Uri)value);
+ break;
+ case PrimitiveTypeCode.String:
+ writer.WriteValue((string)value);
+ break;
+ case PrimitiveTypeCode.Bytes:
+ writer.WriteValue((byte[])value);
+ break;
+#if !(PORTABLE || NETFX_CORE)
+ case PrimitiveTypeCode.DBNull:
+ writer.WriteNull();
+ break;
+#endif
+ default:
+ throw new ArgumentOutOfRangeException("Could not write type: " + UnderlyingType);
+ }
}
}
+
+ internal enum PrimitiveTypeCode
+ {
+ Unknown,
+ Char,
+ CharNullable,
+ Boolean,
+ BooleanNullable,
+ SByte,
+ SByteNullable,
+ Int16,
+ Int16Nullable,
+ UInt16,
+ UInt16Nullable,
+ Int32,
+ Int32Nullable,
+ Byte,
+ ByteNullable,
+ UInt32,
+ UInt32Nullable,
+ Int64,
+ Int64Nullable,
+ UInt64,
+ UInt64Nullable,
+ Single,
+ SingleNullable,
+ Double,
+ DoubleNullable,
+ DateTime,
+ DateTimeNullable,
+#if !NET20
+ DateTimeOffset,
+ DateTimeOffsetNullable,
+#endif
+ Decimal,
+ DecimalNullable,
+ Guid,
+ GuidNullable,
+ TimeSpan,
+ TimeSpanNullable,
+#if !(PORTABLE || NET35 || NET20 || WINDOWS_PHONE || SILVERLIGHT)
+ BigInteger,
+ BigIntegerNullable,
+#endif
+ Uri,
+ String,
+ Bytes,
+ DBNull
+ }
}
\ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index 02b9d0c9..05b833f0 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -94,20 +94,14 @@ namespace Newtonsoft.Json.Serialization
WriteTypeProperty(writer, contract.CreatedType);
writer.WritePropertyName(JsonTypeReflector.ValuePropertyName);
- if (contract.IsNullable)
- writer.WriteValue(value, true);
- else
- writer.WriteValue(value);
+ contract.WriteValue(writer, value);
writer.WriteEndObject();
return;
}
}
- if (contract.IsNullable)
- writer.WriteValue(value, true);
- else
- writer.WriteValue(value);
+ contract.WriteValue(writer, value);
}
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)