From bec3edcf30a579c2994706f9fd9a6b5e1a85641b Mon Sep 17 00:00:00 2001 From: Preston Jennings Date: Wed, 19 Nov 2014 15:14:13 -0500 Subject: [PATCH] Modified handling of int and long data types. Now it is possible to cast ints to longs and vice-versa (assuming the data is within range). You can also do equality comparisons between the two. I've updated the test routine to no longer fail when comparing 10 and 10L. Rationale: When json data is read in, litJson decides on what data type to assign to the data. For integer numerics, litjson dynamically chooses between int and long data types based on the size of the number. If it fits in an int, the data type becomes an int. However this complicates the data handling routines for the user as they cannot predetermine what type to use. Code such as the following: long myvalue = (long) JsonData["some_number"]; would fail with an InvalidCastException when some_number was in the range of an int. It might be worthwhile in the future to handle integer numerics using a single data type (e.g. long). --- src/LitJson/JsonData.cs | 52 +++++++++++++++++++++++++++++++---------- test/JsonDataTest.cs | 4 +++- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/LitJson/JsonData.cs b/src/LitJson/JsonData.cs index 975308d1..32ecbd5a 100644 --- a/src/LitJson/JsonData.cs +++ b/src/LitJson/JsonData.cs @@ -427,20 +427,24 @@ public static explicit operator Double (JsonData data) public static explicit operator Int32 (JsonData data) { - if (data.type != JsonType.Int) + if (data.type != JsonType.Int && data.type != JsonType.Long) + { throw new InvalidCastException ( "Instance of JsonData doesn't hold an int"); + } - return data.inst_int; + // cast may truncate data... but that's up to the user to consider + return data.type == JsonType.Int ? data.inst_int : (int) data.inst_long; } public static explicit operator Int64 (JsonData data) { - if (data.type != JsonType.Long) + if (data.type != JsonType.Long && data.type != JsonType.Int) { throw new InvalidCastException ( - "Instance of JsonData doesn't hold an int"); + "Instance of JsonData doesn't hold a long"); + } - return data.inst_long; + return data.type == JsonType.Long ? data.inst_long : data.inst_int; } public static explicit operator String (JsonData data) @@ -538,20 +542,26 @@ double IJsonWrapper.GetDouble () int IJsonWrapper.GetInt () { - if (type != JsonType.Int) + if (type != JsonType.Int + && type != JsonType.Long) + { throw new InvalidOperationException ( "JsonData instance doesn't hold an int"); + } - return inst_int; + return type == JsonType.Int ? inst_int : (int) inst_long; } long IJsonWrapper.GetLong () { - if (type != JsonType.Long) + if (type != JsonType.Long + && type != JsonType.Int) + { throw new InvalidOperationException ( "JsonData instance doesn't hold a long"); + } - return inst_long; + return type == JsonType.Long ? inst_long : inst_int; } string IJsonWrapper.GetString () @@ -823,7 +833,13 @@ public bool Equals (JsonData x) return false; if (x.type != this.type) - return false; + { + // further check to see if this is a long to int comparison + if ((x.type != JsonType.Int && x.type != JsonType.Long) + || (this.type != JsonType.Int && this.type != JsonType.Long)) { + return false; + } + } switch (this.type) { case JsonType.None: @@ -838,11 +854,23 @@ public bool Equals (JsonData x) case JsonType.String: return this.inst_string.Equals (x.inst_string); - case JsonType.Int: + case JsonType.Int: { + if (x.IsLong) { + if (x.inst_long < Int32.MinValue || x.inst_long > Int32.MaxValue) + return false; + return this.inst_int.Equals((int) x.inst_long); + } return this.inst_int.Equals (x.inst_int); + } - case JsonType.Long: + case JsonType.Long: { + if (x.IsInt) { + if (this.inst_long < Int32.MinValue || this.inst_long > Int32.MaxValue) + return false; + return x.inst_int.Equals((int) this.inst_long); + } return this.inst_long.Equals (x.inst_long); + } case JsonType.Double: return this.inst_double.Equals (x.inst_double); diff --git a/test/JsonDataTest.cs b/test/JsonDataTest.cs index 95b6aadf..cfb38997 100644 --- a/test/JsonDataTest.cs +++ b/test/JsonDataTest.cs @@ -148,7 +148,9 @@ public void EqualsTest () Assert.IsTrue (a.Equals (b), "A4"); b = 10; - Assert.IsFalse (a.Equals (b), "A5"); + //Assert.IsFalse (a.Equals (b), "A5"); + // actually we expect ints and longs to compare true if they are within range + Assert.IsTrue (a.Equals (b), "A5"); b = 11L; Assert.IsFalse (a.Equals (b), "A6");