-Change FloatFormatHandling.Zero to DefaultValue

-Documentation
This commit is contained in:
James Newton-King
2013-02-09 23:17:05 +13:00
parent 95dd0c0ba4
commit 01c3d48ecf
20 changed files with 307 additions and 28 deletions
+1 -1
View File
@@ -154,7 +154,7 @@ function GetConstants($constants, $includeSigned)
{
$signed = switch($includeSigned) { $true { ";SIGNED" } default { "" } }
return "/p:DefineConstants=`"TRACE;$constants$signed`""
return "/p:DefineConstants=`"CODE_ANALYSIS;TRACE;$constants$signed`""
}
function GetVersion($majorVersion)
@@ -433,7 +433,7 @@ namespace Newtonsoft.Json.Tests
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.Zero;
jsonWriter.FloatFormatHandling = FloatFormatHandling.DefaultValue;
jsonWriter.WriteStartArray();
jsonWriter.WriteValue(double.NaN);
@@ -442,6 +442,12 @@ namespace Newtonsoft.Json.Tests
jsonWriter.WriteValue(float.NaN);
jsonWriter.WriteValue(float.PositiveInfinity);
jsonWriter.WriteValue(float.NegativeInfinity);
jsonWriter.WriteValue((double?)double.NaN);
jsonWriter.WriteValue((double?)double.PositiveInfinity);
jsonWriter.WriteValue((double?)double.NegativeInfinity);
jsonWriter.WriteValue((float?)float.NaN);
jsonWriter.WriteValue((float?)float.PositiveInfinity);
jsonWriter.WriteValue((float?)float.NegativeInfinity);
jsonWriter.WriteEndArray();
jsonWriter.Flush();
@@ -453,7 +459,13 @@ namespace Newtonsoft.Json.Tests
0.0,
0.0,
0.0,
0.0
0.0,
null,
null,
null,
null,
null,
null
]";
string result = sb.ToString();
@@ -76,5 +76,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.11.15802")]
[assembly: AssemblyFileVersion("4.5.11.15809")]
#endif
@@ -7124,6 +7124,43 @@ Parameter name: value",
Assert.AreEqual("07/19/2012 14:30:00 +09:30", dateTimeOffset.ToString(CultureInfo.InvariantCulture));
}
public class NullableFloats
{
public object Object { get; set; }
public float Float { get; set; }
public double Double { get; set; }
public float? NullableFloat { get; set; }
public double? NullableDouble { get; set; }
public object ObjectNull { get; set; }
}
[Test]
public void NullableFloatingPoint()
{
NullableFloats floats = new NullableFloats
{
Object = double.NaN,
ObjectNull = null,
Float = float.NaN,
NullableDouble = double.NaN,
NullableFloat = null
};
string json = JsonConvert.SerializeObject(floats, Formatting.Indented, new JsonSerializerSettings
{
FloatFormatHandling = FloatFormatHandling.DefaultValue
});
Assert.AreEqual(@"{
""Object"": 0.0,
""Float"": 0.0,
""Double"": 0.0,
""NullableFloat"": null,
""NullableDouble"": null,
""ObjectNull"": null
}", json);
}
[Test]
public void DateFormatString()
{
@@ -131,11 +131,6 @@ namespace Newtonsoft.Json.Converters
throw JsonSerializationException.Create(reader, "Unexpected token when parsing enum. Expected String or Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
/// <summary>
/// A cached representation of the Enum string representation to respect per Enum field name.
/// </summary>
/// <param name="t">The type of the Enum.</param>
/// <returns>A map of enum field name to either the field name, or the configured enum member name (<see cref="EnumMemberAttribute"/>).</returns>
private BidirectionalDictionary<string, string> GetEnumNameMap(Type t)
{
BidirectionalDictionary<string, string> map;
+41 -2
View File
@@ -1,9 +1,48 @@
namespace Newtonsoft.Json
#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
namespace Newtonsoft.Json
{
/// <summary>
/// Specifies float format handling options when writing special floating point values, e.g. <see cref="F:System.Double.NaN"/>,
/// <see cref="F:System.Double.PositiveInfinity"/> and <see cref="F:System.Double.NegativeInfinity"/> with <see cref="JsonWriter"/>.
/// </summary>
public enum FloatFormatHandling
{
/// <summary>
/// Write special floating point values as strings in JSON, e.g. "NaN", "Infinity", "-Infinity".
/// </summary>
String,
/// <summary>
/// Write special floating point values as symbols in JSON, e.g. NaN, Infinity, -Infinity.
/// Note that this will produce non-valid JSON.
/// </summary>
Symbol,
Zero
/// <summary>
/// Write special floating point values as the property's default value in JSON, e.g. 0.0 for a <see cref="System.Double"/> property, null for a <see cref="System.Nullable{Double}"/> property.
/// </summary>
DefaultValue
}
}
+7 -7
View File
@@ -446,18 +446,18 @@ namespace Newtonsoft.Json
return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
}
internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar)
internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
{
return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar);
return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
}
private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar)
private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
{
if (floatFormatHandling == FloatFormatHandling.Symbol || !(double.IsInfinity(value) || double.IsNaN(value)))
return text;
if (floatFormatHandling == FloatFormatHandling.Zero)
return "0.0";
if (floatFormatHandling == FloatFormatHandling.DefaultValue)
return (!nullable) ? "0.0" : Null;
return quoteChar + text + quoteChar;
}
@@ -472,9 +472,9 @@ namespace Newtonsoft.Json
return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
}
internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar)
internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
{
return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar);
return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
}
private static string EnsureDecimalPlace(double value, string text)
+11
View File
@@ -346,18 +346,29 @@ namespace Newtonsoft.Json
set { _dateParseHandling = value; }
}
/// <summary>
/// Get or set how special floating point values, e.g. <see cref="F:System.Double.NaN"/>,
/// <see cref="F:System.Double.PositiveInfinity"/> and <see cref="F:System.Double.NegativeInfinity"/>,
/// are written as JSON.
/// </summary>
public virtual FloatFormatHandling FloatFormatHandling
{
get { return _floatFormatHandling ?? JsonSerializerSettings.DefaultFloatFormatHandling; }
set { _floatFormatHandling = value; }
}
/// <summary>
/// Get or set how strings are escaped when writing JSON text.
/// </summary>
public virtual StringEscapeHandling StringEscapeHandling
{
get { return _stringEscapeHandling ?? JsonSerializerSettings.DefaultStringEscapeHandling; }
set { _stringEscapeHandling = value; }
}
/// <summary>
/// Get or set how <see cref="DateTime"/> and <see cref="DateTimeOffset"/> values are formatting when writing JSON text.
/// </summary>
public virtual string DateFormatString
{
get { return _dateFormatString ?? JsonSerializerSettings.DefaultDateFormatString; }
@@ -168,6 +168,9 @@ namespace Newtonsoft.Json
/// <value>The context.</value>
public StreamingContext Context { get; set; }
/// <summary>
/// Get or set how <see cref="DateTime"/> and <see cref="DateTimeOffset"/> values are formatting when writing JSON text.
/// </summary>
public string DateFormatString
{
get { return _dateFormatString ?? DefaultDateFormatString; }
@@ -230,12 +233,20 @@ namespace Newtonsoft.Json
set { _dateParseHandling = value; }
}
/// <summary>
/// Get or set how special floating point values, e.g. <see cref="F:System.Double.NaN"/>,
/// <see cref="F:System.Double.PositiveInfinity"/> and <see cref="F:System.Double.NegativeInfinity"/>,
/// are written as JSON.
/// </summary>
public FloatFormatHandling FloatFormatHandling
{
get { return _floatFormatHandling ?? DefaultFloatFormatHandling; }
set { _floatFormatHandling = value; }
}
/// <summary>
/// Get or set how strings are escaped when writing JSON text.
/// </summary>
public StringEscapeHandling StringEscapeHandling
{
get { return _stringEscapeHandling ?? DefaultStringEscapeHandling; }
+36 -2
View File
@@ -357,7 +357,24 @@ namespace Newtonsoft.Json
public override void WriteValue(float value)
{
InternalWriteValue(JsonToken.Float);
WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar), JsonToken.Float);
WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, false), JsonToken.Float);
}
/// <summary>
/// Writes a <see cref="Nullable{Single}"/> value.
/// </summary>
/// <param name="value">The <see cref="Nullable{Single}"/> value to write.</param>
public override void WriteValue(float? value)
{
if (value == null)
{
WriteNull();
}
else
{
InternalWriteValue(JsonToken.Float);
WriteValueInternal(JsonConvert.ToString(value.Value, FloatFormatHandling, QuoteChar, true), JsonToken.Float);
}
}
/// <summary>
@@ -367,7 +384,24 @@ namespace Newtonsoft.Json
public override void WriteValue(double value)
{
InternalWriteValue(JsonToken.Float);
WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar), JsonToken.Float);
WriteValueInternal(JsonConvert.ToString(value, FloatFormatHandling, QuoteChar, false), JsonToken.Float);
}
/// <summary>
/// Writes a <see cref="Nullable{Double}"/> value.
/// </summary>
/// <param name="value">The <see cref="Nullable{Double}"/> value to write.</param>
public override void WriteValue(double? value)
{
if (value == null)
{
WriteNull();
}
else
{
InternalWriteValue(JsonToken.Float);
WriteValueInternal(JsonConvert.ToString(value.Value, FloatFormatHandling, QuoteChar, true), JsonToken.Float);
}
}
/// <summary>
+116
View File
@@ -250,18 +250,29 @@ namespace Newtonsoft.Json
set { _stringEscapeHandling = value; }
}
/// <summary>
/// Get or set how special floating point values, e.g. <see cref="F:System.Double.NaN"/>,
/// <see cref="F:System.Double.PositiveInfinity"/> and <see cref="F:System.Double.NegativeInfinity"/>,
/// are written to JSON text.
/// </summary>
public FloatFormatHandling FloatFormatHandling
{
get { return _floatFormatHandling; }
set { _floatFormatHandling = value; }
}
/// <summary>
/// Get or set how <see cref="DateTime"/> and <see cref="DateTimeOffset"/> values are formatting when writing JSON text.
/// </summary>
public string DateFormatString
{
get { return _dateFormatString; }
set { _dateFormatString = value; }
}
/// <summary>
/// Gets or sets the culture used when writing JSON. Defaults to <see cref="CultureInfo.InvariantCulture"/>.
/// </summary>
public CultureInfo Culture
{
get { return _culture ?? CultureInfo.InvariantCulture; }
@@ -1301,6 +1312,111 @@ namespace Newtonsoft.Json
throw JsonWriterException.Create(this, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
}
/// <summary>
/// Writes a <see cref="Object"/> value.
/// An error will raised if the value cannot be written as a single JSON token.
/// </summary>
/// <param name="value">The <see cref="Object"/> value to write.</param>
/// <param name="nullable">A flag indicating whether the value is nullable.</param>
public virtual void WriteValue(object value, bool nullable)
{
if (!nullable)
WriteValue(value);
if (value == null)
{
WriteNull();
return;
}
else if (ConvertUtils.IsConvertible(value))
{
IConvertible convertible = ConvertUtils.ToConvertible(value);
switch (convertible.GetTypeCode())
{
case TypeCode.String:
WriteValue(convertible.ToString(CultureInfo.InvariantCulture));
return;
case TypeCode.Char:
WriteValue((char?)convertible.ToChar(CultureInfo.InvariantCulture));
return;
case TypeCode.Boolean:
WriteValue((bool?)convertible.ToBoolean(CultureInfo.InvariantCulture));
return;
case TypeCode.SByte:
WriteValue((sbyte?)convertible.ToSByte(CultureInfo.InvariantCulture));
return;
case TypeCode.Int16:
WriteValue((short?)convertible.ToInt16(CultureInfo.InvariantCulture));
return;
case TypeCode.UInt16:
WriteValue((ushort?)convertible.ToUInt16(CultureInfo.InvariantCulture));
return;
case TypeCode.Int32:
WriteValue((int?)convertible.ToInt32(CultureInfo.InvariantCulture));
return;
case TypeCode.Byte:
WriteValue((byte?)convertible.ToByte(CultureInfo.InvariantCulture));
return;
case TypeCode.UInt32:
WriteValue((uint?)convertible.ToUInt32(CultureInfo.InvariantCulture));
return;
case TypeCode.Int64:
WriteValue((long?)convertible.ToInt64(CultureInfo.InvariantCulture));
return;
case TypeCode.UInt64:
WriteValue((ulong?)convertible.ToUInt64(CultureInfo.InvariantCulture));
return;
case TypeCode.Single:
WriteValue((float?)convertible.ToSingle(CultureInfo.InvariantCulture));
return;
case TypeCode.Double:
WriteValue((double?)convertible.ToDouble(CultureInfo.InvariantCulture));
return;
case TypeCode.DateTime:
WriteValue((DateTime?)convertible.ToDateTime(CultureInfo.InvariantCulture));
return;
case TypeCode.Decimal:
WriteValue((decimal?)convertible.ToDecimal(CultureInfo.InvariantCulture));
return;
#if !(NETFX_CORE || PORTABLE)
case TypeCode.DBNull:
WriteNull();
return;
#endif
}
}
#if !PocketPC && !NET20
else if (value is DateTimeOffset)
{
WriteValue((DateTimeOffset?)value);
return;
}
#endif
else if (value is byte[])
{
WriteValue((byte[])value);
return;
}
else if (value is Guid)
{
WriteValue((Guid?)value);
return;
}
else if (value is Uri)
{
WriteValue((Uri)value);
return;
}
else if (value is TimeSpan)
{
WriteValue((TimeSpan?)value);
return;
}
throw JsonWriterException.Create(this, "Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()), null);
}
#endregion
/// <summary>
@@ -65,7 +65,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Net20\Newtonsoft.Json.xml</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -66,8 +66,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Net35\Newtonsoft.Json.xml</DocumentationFile>
<CodeAnalysisRuleSet>..\..\..\..\trunk\Src\Newtonsoft.Json\Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>false</RunCodeAnalysis>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -21,6 +21,8 @@
<DefineConstants>TRACE;DEBUG;PORTABLE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -30,6 +32,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Portable\Newtonsoft.Json.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -67,7 +67,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>Bin\Release\Silverlight\Newtonsoft.Json.xml</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Runtime.Serialization" />
@@ -31,6 +31,8 @@
<WarningLevel>4</WarningLevel>
<DocumentationFile>
</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -42,6 +44,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>Bin\Release\WindowsPhone\Newtonsoft.Json.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Runtime.Serialization" />
+2 -1
View File
@@ -66,8 +66,9 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Net40\Newtonsoft.Json.xml</DocumentationFile>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>Newtonsoft.Json.ruleset</CodeAnalysisRuleSet>
<UseVSHostingProcess>true</UseVSHostingProcess>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -90,7 +90,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.11.15802")]
[assembly: AssemblyFileVersion("4.5.11.15809")]
#endif
[assembly: CLSCompliant(true)]
@@ -24,6 +24,7 @@
#endregion
using System;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
{
@@ -32,6 +33,8 @@ namespace Newtonsoft.Json.Serialization
/// </summary>
public class JsonPrimitiveContract : JsonContract
{
internal bool Nullable { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="JsonPrimitiveContract"/> class.
/// </summary>
@@ -40,6 +43,8 @@ namespace Newtonsoft.Json.Serialization
: base(underlyingType)
{
ContractType = JsonContractType.Primitive;
Nullable = ReflectionUtils.IsNullable(underlyingType);
}
}
}
@@ -88,13 +88,21 @@ namespace Newtonsoft.Json.Serialization
writer.WriteStartObject();
WriteTypeProperty(writer, contract.CreatedType);
writer.WritePropertyName(JsonTypeReflector.ValuePropertyName);
writer.WriteValue(value);
if (contract.IsNullable)
writer.WriteValue(value, true);
else
writer.WriteValue(value);
writer.WriteEndObject();
return;
}
}
writer.WriteValue(value);
if (contract.IsNullable)
writer.WriteValue(value, true);
else
writer.WriteValue(value);
}
private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)