implement box avoidance (#2639)

Co-authored-by: Marc Gravell <marcgravell@microsoft.com>
Co-authored-by: James Newton-King <james@newtonking.com>
This commit is contained in:
Marc Gravell
2022-05-15 22:08:18 +08:00
committed by GitHub
co-authored by Marc Gravell James Newton-King
parent 197c6db94a
commit 13717cfc45
10 changed files with 302 additions and 57 deletions
@@ -23,7 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
#if (NET45 || NET50)
#if (NET45 || NET5_0_OR_GREATER)
#if DNXCORE50
using Xunit;
using Test = Xunit.FactAttribute;
@@ -23,7 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
#if (NET45 || NET50)
#if (NET45 || NET5_0_OR_GREATER)
#if DNXCORE50
using Xunit;
using Test = Xunit.FactAttribute;
@@ -23,7 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
#if (NET45 || NET50)
#if (NET45 || NET5_0_OR_GREATER)
#if DNXCORE50
using Xunit;
using Test = Xunit.FactAttribute;
@@ -23,7 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
#if (NET45 || NET50)
#if (NET45 || NET5_0_OR_GREATER)
#if DNXCORE50
using Xunit;
using Test = Xunit.FactAttribute;
@@ -0,0 +1,129 @@
#region License
// Copyright (c) 2022 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
using Newtonsoft.Json.Linq;
using System.Globalization;
using Newtonsoft.Json.Tests.Documentation.Samples.Linq;
#if DNXCORE50
using Xunit;
using Test = Xunit.FactAttribute;
using Assert = Newtonsoft.Json.Tests.XUnitAssert;
#else
using NUnit.Framework;
#endif
namespace Newtonsoft.Json.Tests.Issues
{
[TestFixture]
public class Issue2638
{
[Test]
public void DeserilizeUsesSharedBooleans()
{
Test(true);
Test(false);
static void Test(bool value)
{
var obj = (JObject)JToken.Parse(@"{""x"": XXX, ""y"": XXX}".Replace("XXX", value ? "true" : "false"));
var x = ((JValue)obj["x"]).Value;
var y = ((JValue)obj["y"]).Value;
Assert.AreEqual(value, (bool)x);
Assert.AreEqual(value, (bool)y);
Assert.AreSame(x, y);
}
}
[Test]
public void DeserilizeUsesSharedDoubleZeros()
{
Test(0, true);
Test(double.NaN, true);
Test(double.NegativeInfinity, true);
Test(double.PositiveInfinity, true);
Test(1, false);
Test(42.42, false);
static void Test(double value, bool expectSame)
{
var obj = (JObject)JToken.Parse(@"{""x"": XXX, ""y"": XXX}".Replace("XXX", value.ToString("0.0###", CultureInfo.InvariantCulture)));
var x = ((JValue)obj["x"]).Value;
var y = ((JValue)obj["y"]).Value;
Assert.AreEqual(value, (double)x);
Assert.AreEqual(value, (double)y);
if (expectSame)
{
Assert.AreSame(x, y);
}
else
{
Assert.AreNotSame(x, y);
}
var unboxed = (double)x;
Assert.AreEqual(double.IsNaN(value), double.IsNaN(unboxed));
Assert.AreEqual(double.IsPositiveInfinity(value), double.IsPositiveInfinity(unboxed));
Assert.AreEqual(double.IsNegativeInfinity(value), double.IsNegativeInfinity(unboxed));
}
}
[Test]
public void DeserilizeUsesSharedSmallInt64()
{
Test(-2, false);
Test(-1, true);
Test(0, true);
Test(1, true);
Test(2, true);
Test(3, true);
Test(4, true);
Test(5, true);
Test(6, true);
Test(7, true);
Test(8, true);
Test(9, false);
static void Test(long value, bool expectSame)
{
var obj = (JObject)JToken.Parse(@"{""x"": XXX, ""y"": XXX}".Replace("XXX", value.ToString(CultureInfo.InvariantCulture)));
var x = ((JValue)obj["x"]).Value;
var y = ((JValue)obj["y"]).Value;
Assert.AreEqual(value, (long)x);
Assert.AreEqual(value, (long)y);
if (expectSame)
{
Assert.AreSame(x, y);
}
else
{
Assert.AreNotSame(x, y);
}
}
}
}
}
@@ -13,7 +13,7 @@
<RootNamespace>Newtonsoft.Json.Tests</RootNamespace>
<IsPackable>false</IsPackable>
<!-- Workaround for https://github.com/nunit/nunit3-vs-adapter/issues/296 -->
<DebugType Condition="'$(TargetFramework)' != '' AND '$(TargetFramework)' != 'netcoreapp2.1' AND '$(TargetFramework)' != 'netcoreapp3.1' AND '$(TargetFramework)' != 'net5.0'">Full</DebugType>
<DebugType Condition="'$(TargetFramework)' != '' AND '$(TargetFramework)' != 'netcoreapp2.1' AND '$(TargetFramework)' != 'netcoreapp3.1' AND '$(TargetFramework)' != 'net6.0'">Full</DebugType>
<!-- Disabled because SourceLink isn't referenced to calculate paths -->
<DeterministicSourcePaths>false</DeterministicSourcePaths>
<!-- It's ok if a test target has exited support. Disable NETSSDK1138 warning -->
+20 -20
View File
@@ -841,7 +841,7 @@ namespace Newtonsoft.Json
{
throw CreateUnexpectedCharacterException(_chars[_charPos]);
}
SetToken(JsonToken.Boolean, isTrue);
SetToken(JsonToken.Boolean, BoxedPrimitives.Get(isTrue));
return isTrue;
case '/':
ParseComment(false);
@@ -2030,7 +2030,7 @@ namespace Newtonsoft.Json
if (singleDigit)
{
// digit char values start at 48
numberValue = firstChar - 48;
numberValue = BoxedPrimitives.Get(firstChar - 48);
}
else if (nonBase10)
{
@@ -2040,7 +2040,7 @@ namespace Newtonsoft.Json
{
int integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt32(number, 16) : Convert.ToInt32(number, 8);
numberValue = integer;
numberValue = BoxedPrimitives.Get(integer);
}
catch (Exception ex)
{
@@ -2052,7 +2052,7 @@ namespace Newtonsoft.Json
ParseResult parseResult = ConvertUtils.Int32TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out int value);
if (parseResult == ParseResult.Success)
{
numberValue = value;
numberValue = BoxedPrimitives.Get(value);
}
else if (parseResult == ParseResult.Overflow)
{
@@ -2072,7 +2072,7 @@ namespace Newtonsoft.Json
if (singleDigit)
{
// digit char values start at 48
numberValue = (decimal)firstChar - 48;
numberValue = BoxedPrimitives.Get((decimal)firstChar - 48);
}
else if (nonBase10)
{
@@ -2083,7 +2083,7 @@ namespace Newtonsoft.Json
// decimal.Parse doesn't support parsing hexadecimal values
long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
numberValue = Convert.ToDecimal(integer);
numberValue = BoxedPrimitives.Get(Convert.ToDecimal(integer));
}
catch (Exception ex)
{
@@ -2095,7 +2095,7 @@ namespace Newtonsoft.Json
ParseResult parseResult = ConvertUtils.DecimalTryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out decimal value);
if (parseResult == ParseResult.Success)
{
numberValue = value;
numberValue = BoxedPrimitives.Get(value);
}
else
{
@@ -2111,7 +2111,7 @@ namespace Newtonsoft.Json
if (singleDigit)
{
// digit char values start at 48
numberValue = (double)firstChar - 48;
numberValue = BoxedPrimitives.Get((double)firstChar - 48);
}
else if (nonBase10)
{
@@ -2122,7 +2122,7 @@ namespace Newtonsoft.Json
// double.Parse doesn't support parsing hexadecimal values
long integer = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
numberValue = Convert.ToDouble(integer);
numberValue = BoxedPrimitives.Get(Convert.ToDouble(integer));
}
catch (Exception ex)
{
@@ -2135,7 +2135,7 @@ namespace Newtonsoft.Json
if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
{
numberValue = value;
numberValue = BoxedPrimitives.Get(value);
}
else
{
@@ -2152,7 +2152,7 @@ namespace Newtonsoft.Json
if (singleDigit)
{
// digit char values start at 48
numberValue = (long)firstChar - 48;
numberValue = BoxedPrimitives.Get((long)firstChar - 48);
numberType = JsonToken.Integer;
}
else if (nonBase10)
@@ -2161,7 +2161,7 @@ namespace Newtonsoft.Json
try
{
numberValue = number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8);
numberValue = BoxedPrimitives.Get(number.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? Convert.ToInt64(number, 16) : Convert.ToInt64(number, 8));
}
catch (Exception ex)
{
@@ -2175,7 +2175,7 @@ namespace Newtonsoft.Json
ParseResult parseResult = ConvertUtils.Int64TryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out long value);
if (parseResult == ParseResult.Success)
{
numberValue = value;
numberValue = BoxedPrimitives.Get(value);
numberType = JsonToken.Integer;
}
else if (parseResult == ParseResult.Overflow)
@@ -2201,7 +2201,7 @@ namespace Newtonsoft.Json
parseResult = ConvertUtils.DecimalTryParse(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length, out decimal d);
if (parseResult == ParseResult.Success)
{
numberValue = d;
numberValue = BoxedPrimitives.Get(d);
}
else
{
@@ -2214,7 +2214,7 @@ namespace Newtonsoft.Json
if (double.TryParse(number, NumberStyles.Float, CultureInfo.InvariantCulture, out double d))
{
numberValue = d;
numberValue = BoxedPrimitives.Get(d);
}
else
{
@@ -2455,7 +2455,7 @@ namespace Newtonsoft.Json
// or the text ends
if (MatchValueWithTrailingSeparator(JsonConvert.True))
{
SetToken(JsonToken.Boolean, true);
SetToken(JsonToken.Boolean, BoxedPrimitives.BooleanTrue);
}
else
{
@@ -2491,7 +2491,7 @@ namespace Newtonsoft.Json
{
if (MatchValueWithTrailingSeparator(JsonConvert.False))
{
SetToken(JsonToken.Boolean, false);
SetToken(JsonToken.Boolean, BoxedPrimitives.BooleanFalse);
}
else
{
@@ -2514,7 +2514,7 @@ namespace Newtonsoft.Json
case ReadType.ReadAsDouble:
if (_floatParseHandling == FloatParseHandling.Double)
{
SetToken(JsonToken.Float, double.NegativeInfinity);
SetToken(JsonToken.Float, BoxedPrimitives.DoubleNegativeInfinity);
return double.NegativeInfinity;
}
break;
@@ -2543,7 +2543,7 @@ namespace Newtonsoft.Json
case ReadType.ReadAsDouble:
if (_floatParseHandling == FloatParseHandling.Double)
{
SetToken(JsonToken.Float, double.PositiveInfinity);
SetToken(JsonToken.Float, BoxedPrimitives.DoublePositiveInfinity);
return double.PositiveInfinity;
}
break;
@@ -2573,7 +2573,7 @@ namespace Newtonsoft.Json
case ReadType.ReadAsDouble:
if (_floatParseHandling == FloatParseHandling.Double)
{
SetToken(JsonToken.Float, double.NaN);
SetToken(JsonToken.Float, BoxedPrimitives.DoubleNaN);
return double.NaN;
}
break;
+28 -28
View File
@@ -187,12 +187,12 @@ namespace Newtonsoft.Json.Linq
base.WritePropertyName(name);
}
private void AddValue(object? value, JsonToken token)
private void AddRawValue(object? value, JTokenType type, JsonToken token)
{
AddValue(new JValue(value), token);
AddJValue(new JValue(value, type), token);
}
internal void AddValue(JValue? value, JsonToken token)
internal void AddJValue(JValue? value, JsonToken token)
{
if (_parent != null)
{
@@ -228,7 +228,7 @@ namespace Newtonsoft.Json.Linq
if (value is BigInteger)
{
InternalWriteValue(JsonToken.Integer);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
else
#endif
@@ -243,7 +243,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteNull()
{
base.WriteNull();
AddValue(null, JsonToken.Null);
AddJValue(JValue.CreateNull(), JsonToken.Null);
}
/// <summary>
@@ -252,7 +252,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteUndefined()
{
base.WriteUndefined();
AddValue(null, JsonToken.Undefined);
AddJValue(JValue.CreateUndefined(), JsonToken.Undefined);
}
/// <summary>
@@ -262,7 +262,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteRaw(string? json)
{
base.WriteRaw(json);
AddValue(new JRaw(json), JsonToken.Raw);
AddJValue(new JRaw(json), JsonToken.Raw);
}
/// <summary>
@@ -272,7 +272,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteComment(string? text)
{
base.WriteComment(text);
AddValue(JValue.CreateComment(text), JsonToken.Comment);
AddJValue(JValue.CreateComment(text), JsonToken.Comment);
}
/// <summary>
@@ -282,7 +282,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(string? value)
{
base.WriteValue(value);
AddValue(value, JsonToken.String);
AddJValue(new JValue(value), JsonToken.String);
}
/// <summary>
@@ -292,7 +292,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(int value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
/// <summary>
@@ -303,7 +303,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(uint value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
/// <summary>
@@ -313,7 +313,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(long value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddJValue(new JValue(value), JsonToken.Integer);
}
/// <summary>
@@ -324,7 +324,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(ulong value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddJValue(new JValue(value), JsonToken.Integer);
}
/// <summary>
@@ -334,7 +334,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(float value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Float);
AddJValue(new JValue(value), JsonToken.Float);
}
/// <summary>
@@ -344,7 +344,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(double value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Float);
AddJValue(new JValue(value), JsonToken.Float);
}
/// <summary>
@@ -354,7 +354,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(bool value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Boolean);
AddJValue(new JValue(value), JsonToken.Boolean);
}
/// <summary>
@@ -364,7 +364,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(short value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
/// <summary>
@@ -375,7 +375,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(ushort value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
/// <summary>
@@ -391,7 +391,7 @@ namespace Newtonsoft.Json.Linq
#else
s = value.ToString();
#endif
AddValue(s, JsonToken.String);
AddJValue(new JValue(s), JsonToken.String);
}
/// <summary>
@@ -401,7 +401,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(byte value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
/// <summary>
@@ -412,7 +412,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(sbyte value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Integer);
AddRawValue(value, JTokenType.Integer, JsonToken.Integer);
}
/// <summary>
@@ -422,7 +422,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(decimal value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Float);
AddJValue(new JValue(value), JsonToken.Float);
}
/// <summary>
@@ -433,7 +433,7 @@ namespace Newtonsoft.Json.Linq
{
base.WriteValue(value);
value = DateTimeUtils.EnsureDateTime(value, DateTimeZoneHandling);
AddValue(value, JsonToken.Date);
AddJValue(new JValue(value), JsonToken.Date);
}
#if HAVE_DATE_TIME_OFFSET
@@ -444,7 +444,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(DateTimeOffset value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Date);
AddJValue(new JValue(value), JsonToken.Date);
}
#endif
@@ -455,7 +455,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(byte[]? value)
{
base.WriteValue(value);
AddValue(value, JsonToken.Bytes);
AddJValue(new JValue(value, JTokenType.Bytes), JsonToken.Bytes);
}
/// <summary>
@@ -465,7 +465,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(TimeSpan value)
{
base.WriteValue(value);
AddValue(value, JsonToken.String);
AddJValue(new JValue(value), JsonToken.String);
}
/// <summary>
@@ -475,7 +475,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(Guid value)
{
base.WriteValue(value);
AddValue(value, JsonToken.String);
AddJValue(new JValue(value), JsonToken.String);
}
/// <summary>
@@ -485,7 +485,7 @@ namespace Newtonsoft.Json.Linq
public override void WriteValue(Uri? value)
{
base.WriteValue(value);
AddValue(value, JsonToken.String);
AddJValue(new JValue(value), JsonToken.String);
}
#endregion
+4 -4
View File
@@ -72,7 +72,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <param name="value">The value.</param>
public JValue(long value)
: this(value, JTokenType.Integer)
: this(BoxedPrimitives.Get(value), JTokenType.Integer)
{
}
@@ -81,7 +81,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <param name="value">The value.</param>
public JValue(decimal value)
: this(value, JTokenType.Float)
: this(BoxedPrimitives.Get(value), JTokenType.Float)
{
}
@@ -109,7 +109,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <param name="value">The value.</param>
public JValue(double value)
: this(value, JTokenType.Float)
: this(BoxedPrimitives.Get(value), JTokenType.Float)
{
}
@@ -147,7 +147,7 @@ namespace Newtonsoft.Json.Linq
/// </summary>
/// <param name="value">The value.</param>
public JValue(bool value)
: this(value, JTokenType.Boolean)
: this(BoxedPrimitives.Get(value), JTokenType.Boolean)
{
}
@@ -0,0 +1,116 @@
#region License
// Copyright (c) 2022 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.Utilities
{
internal static class BoxedPrimitives
{
internal static object Get(bool value) => value ? BooleanTrue : BooleanFalse;
internal static readonly object BooleanTrue = true;
internal static readonly object BooleanFalse = false;
internal static object Get(int value) => value switch
{
-1 => Int32_M1,
0 => Int32_0,
1 => Int32_1,
2 => Int32_2,
3 => Int32_3,
4 => Int32_4,
5 => Int32_5,
6 => Int32_6,
7 => Int32_7,
8 => Int32_8,
_ => value,
};
// integers tend to be weighted towards a handful of low numbers; we could argue
// for days over the "correct" range to have special handling, but I'm arbitrarily
// mirroring the same decision as the IL opcodes, which has M1 thru 8
internal static readonly object Int32_M1 = -1;
internal static readonly object Int32_0 = 0;
internal static readonly object Int32_1 = 1;
internal static readonly object Int32_2 = 2;
internal static readonly object Int32_3 = 3;
internal static readonly object Int32_4 = 4;
internal static readonly object Int32_5 = 5;
internal static readonly object Int32_6 = 6;
internal static readonly object Int32_7 = 7;
internal static readonly object Int32_8 = 8;
internal static object Get(long value) => value switch
{
-1 => Int64_M1,
0 => Int64_0,
1 => Int64_1,
2 => Int64_2,
3 => Int64_3,
4 => Int64_4,
5 => Int64_5,
6 => Int64_6,
7 => Int64_7,
8 => Int64_8,
_ => value,
};
internal static readonly object Int64_M1 = -1L;
internal static readonly object Int64_0 = 0L;
internal static readonly object Int64_1 = 1L;
internal static readonly object Int64_2 = 2L;
internal static readonly object Int64_3 = 3L;
internal static readonly object Int64_4 = 4L;
internal static readonly object Int64_5 = 5L;
internal static readonly object Int64_6 = 6L;
internal static readonly object Int64_7 = 7L;
internal static readonly object Int64_8 = 8L;
internal static object Get(decimal value) => value == decimal.Zero ? DecimalZero : value;
private static readonly object DecimalZero = decimal.Zero;
internal static object Get(double value)
{
if (value == 0.0d)
{
return DoubleZero;
}
if (double.IsInfinity(value))
{
return double.IsPositiveInfinity(value) ? DoublePositiveInfinity : DoubleNegativeInfinity;
}
if (double.IsNaN(value))
{
return DoubleNaN;
}
return value;
}
internal static readonly object DoubleNaN = double.NaN;
internal static readonly object DoublePositiveInfinity = double.PositiveInfinity;
internal static readonly object DoubleNegativeInfinity = double.NegativeInfinity;
internal static readonly object DoubleZero = (double)0;
}
}