From 762d4fedf41a70a194bef2755937ce75c6a88eb6 Mon Sep 17 00:00:00 2001 From: Jonathan Gilbert Date: Wed, 7 Sep 2016 17:18:54 -0500 Subject: [PATCH] Reworked the ParseNumber method in RestSharp/SimpleJson.cs to avoid repeatedly building a System.String of the number substring. Reworked the integer parsing path in RestSharp/SimpleJson.cs to try decimal and double parsers if long fails. This allows numbers such as long.MaxValue + 1M to be parsed (yielding a decimal instead of a long). Numbers too large for System.Decimal become System.Double (at, of course, a loss of precision). Added test Can_Deserialize_Very_Large_Integers to RestSharp.Tests/JsonTests.cs. --- RestSharp.Tests/JsonTests.cs | 8 ++++++++ RestSharp/SimpleJson.cs | 24 +++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/RestSharp.Tests/JsonTests.cs b/RestSharp.Tests/JsonTests.cs index c276246e9..1cabd72ad 100644 --- a/RestSharp.Tests/JsonTests.cs +++ b/RestSharp.Tests/JsonTests.cs @@ -825,6 +825,14 @@ public void Can_Deserialize_Dictionary_with_Null() Assert.IsNull(dictionary["Null"]); } + [Test] + public void Can_Deserialize_Very_Large_Integers() + { + decimal veryLargeInteger = long.MaxValue + 1M; + decimal deserializedValue = new JsonDeserializer().Deserialize(new RestResponse { Content = veryLargeInteger.ToString() }); + Assert.AreEqual(veryLargeInteger, deserializedValue); + } + private static string CreateJsonWithUnderscores() { JsonObject doc = new JsonObject(); diff --git a/RestSharp/SimpleJson.cs b/RestSharp/SimpleJson.cs index 674ae2ee6..d8af8fe06 100644 --- a/RestSharp/SimpleJson.cs +++ b/RestSharp/SimpleJson.cs @@ -903,19 +903,29 @@ static object ParseNumber(char[] json, ref int index, ref bool success) EatWhitespace(json, ref index); int lastIndex = GetLastIndexOfNumber(json, index); int charLength = (lastIndex - index) + 1; - object returnNumber; - string str = new string(json, index, charLength); - if (str.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || str.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) + object returnNumber = null; + string numberAsString = new string(json, index, charLength); + if ((numberAsString.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1) + || (numberAsString.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1)) { double number; - success = double.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); + success = double.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out number); returnNumber = number; } else { - long number; - success = long.TryParse(new string(json, index, charLength), NumberStyles.Any, CultureInfo.InvariantCulture, out number); - returnNumber = number; + long longNumber; + decimal decimalNumber; + double doubleNumber; + + if (long.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out longNumber)) + returnNumber = longNumber; + else if (decimal.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out decimalNumber)) + returnNumber = decimalNumber; + else if (double.TryParse(numberAsString, NumberStyles.Any, CultureInfo.InvariantCulture, out doubleNumber)) + returnNumber = doubleNumber; + + success = (returnNumber != null); } index = lastIndex + 1; return returnNumber;