diff --git a/docs/Utf8Json.AspNetCoreMvcFormatter.nuspec b/docs/Utf8Json.AspNetCoreMvcFormatter.nuspec index 630fd46..8323496 100644 --- a/docs/Utf8Json.AspNetCoreMvcFormatter.nuspec +++ b/docs/Utf8Json.AspNetCoreMvcFormatter.nuspec @@ -2,7 +2,7 @@ Utf8Json.AspNetCoreMvcFormatter - 1.2.1 + 1.2.2 Utf8Json AspNetCoreMvcFormatter neuecc neuecc @@ -13,11 +13,11 @@ Json, Serialization, Formatter, Serializer, Unity, Xamarin, ASPNET - + - + diff --git a/docs/Utf8Json.ImmutableCollection.nuspec b/docs/Utf8Json.ImmutableCollection.nuspec index 555f829..1d9c0b8 100644 --- a/docs/Utf8Json.ImmutableCollection.nuspec +++ b/docs/Utf8Json.ImmutableCollection.nuspec @@ -2,7 +2,7 @@ Utf8Json.ImmutableCollection - 1.2.1 + 1.2.2 Utf8Json Extension Resolver for ImmutableCollection neuecc neuecc @@ -13,15 +13,15 @@ Json, Serialization, Formatter, Serializer, Unity, Xamarin - + - + - + diff --git a/docs/Utf8Json.UnityShims.nuspec b/docs/Utf8Json.UnityShims.nuspec index 60cea7d..4bc8df5 100644 --- a/docs/Utf8Json.UnityShims.nuspec +++ b/docs/Utf8Json.UnityShims.nuspec @@ -2,7 +2,7 @@ Utf8Json.UnityShims - 1.2.1 + 1.2.2 Utf8Json UnityShims neuecc neuecc @@ -13,15 +13,15 @@ Json, Serialization, Formatter, Serializer, Unity, Xamarin - + - + - + diff --git a/docs/Utf8Json.nuspec b/docs/Utf8Json.nuspec index d955fef..4d0da7c 100644 --- a/docs/Utf8Json.nuspec +++ b/docs/Utf8Json.nuspec @@ -2,7 +2,7 @@ Utf8Json - 1.2.1 + 1.2.2 Utf8Json neuecc neuecc diff --git a/docs/push.bat b/docs/push.bat index 82394ba..6dd2bed 100644 --- a/docs/push.bat +++ b/docs/push.bat @@ -1,4 +1,4 @@ -nuget push Utf8Json.1.2.1.nupkg -Source https://www.nuget.org/api/v2/package -nuget push Utf8Json.ImmutableCollection.1.2.1.nupkg -Source https://www.nuget.org/api/v2/package -nuget push Utf8Json.UnityShims.1.2.1.nupkg -Source https://www.nuget.org/api/v2/package -nuget push Utf8Json.AspNetCoreMvcFormatter.1.2.1.nupkg -Source https://www.nuget.org/api/v2/package \ No newline at end of file +nuget push Utf8Json.1.2.2.nupkg -Source https://www.nuget.org/api/v2/package +nuget push Utf8Json.ImmutableCollection.1.2.2.nupkg -Source https://www.nuget.org/api/v2/package +nuget push Utf8Json.UnityShims.1.2.2.nupkg -Source https://www.nuget.org/api/v2/package +nuget push Utf8Json.AspNetCoreMvcFormatter.1.2.2.nupkg -Source https://www.nuget.org/api/v2/package \ No newline at end of file diff --git a/src/Utf8Json.AspNetCoreMvcFormatter/_AssemblyInfo.cs b/src/Utf8Json.AspNetCoreMvcFormatter/_AssemblyInfo.cs index 1ee7a92..aeeffb3 100644 --- a/src/Utf8Json.AspNetCoreMvcFormatter/_AssemblyInfo.cs +++ b/src/Utf8Json.AspNetCoreMvcFormatter/_AssemblyInfo.cs @@ -12,5 +12,5 @@ [assembly: ComVisible(false)] [assembly: Guid("899f8b6c-c4c7-4e8b-9875-f61fdfb630bd")] -[assembly: AssemblyVersion("1.2.1")] -[assembly: AssemblyFileVersion("1.2.1")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.2")] +[assembly: AssemblyFileVersion("1.2.2")] \ No newline at end of file diff --git a/src/Utf8Json.CodeGenerator/App.config b/src/Utf8Json.CodeGenerator/App.config index 1f6c7f4..d7b93d6 100644 --- a/src/Utf8Json.CodeGenerator/App.config +++ b/src/Utf8Json.CodeGenerator/App.config @@ -7,7 +7,7 @@ - + diff --git a/src/Utf8Json.ImmutableCollection/_AssemblyInfo.cs b/src/Utf8Json.ImmutableCollection/_AssemblyInfo.cs index e367800..0f2ce13 100644 --- a/src/Utf8Json.ImmutableCollection/_AssemblyInfo.cs +++ b/src/Utf8Json.ImmutableCollection/_AssemblyInfo.cs @@ -12,5 +12,5 @@ [assembly: ComVisible(false)] [assembly: Guid("2e7ac239-3db1-4772-9f47-5f62abb56ed0")] -[assembly: AssemblyVersion("1.2.1")] -[assembly: AssemblyFileVersion("1.2.1")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.2")] +[assembly: AssemblyFileVersion("1.2.2")] \ No newline at end of file diff --git a/src/Utf8Json.UnityClient/Utf8Json.UnityClient.csproj b/src/Utf8Json.UnityClient/Utf8Json.UnityClient.csproj index f77bf46..cbea404 100644 --- a/src/Utf8Json.UnityClient/Utf8Json.UnityClient.csproj +++ b/src/Utf8Json.UnityClient/Utf8Json.UnityClient.csproj @@ -140,6 +140,7 @@ + diff --git a/src/Utf8Json.UnityShims/_AssemblyInfo.cs b/src/Utf8Json.UnityShims/_AssemblyInfo.cs index 58a580a..5bda405 100644 --- a/src/Utf8Json.UnityShims/_AssemblyInfo.cs +++ b/src/Utf8Json.UnityShims/_AssemblyInfo.cs @@ -12,5 +12,5 @@ [assembly: ComVisible(false)] [assembly: Guid("bf5d0a42-70b7-417d-af8c-2f7e073057e2")] -[assembly: AssemblyVersion("1.2.1")] -[assembly: AssemblyFileVersion("1.2.1")] \ No newline at end of file +[assembly: AssemblyVersion("1.2.2")] +[assembly: AssemblyFileVersion("1.2.2")] \ No newline at end of file diff --git a/src/Utf8Json/Formatters/DateTimeFormatter.cs b/src/Utf8Json/Formatters/DateTimeFormatter.cs index 9f05920..3ddb272 100644 --- a/src/Utf8Json/Formatters/DateTimeFormatter.cs +++ b/src/Utf8Json/Formatters/DateTimeFormatter.cs @@ -242,6 +242,7 @@ public DateTime Deserialize(ref JsonReader reader, IJsonFormatterResolver format var array = str.Array; var i = str.Offset; var len = str.Count; + var to = str.Offset + str.Count; // YYYY if (len == 4) @@ -288,41 +289,41 @@ public DateTime Deserialize(ref JsonReader reader, IJsonFormatterResolver format var second = (array[i++] - (byte)'0') * 10 + (array[i++] - (byte)'0'); int ticks = 0; - if (i < len && array[i] == '.') + if (i < to && array[i] == '.') { i++; // *7. - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1000000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 100000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 10000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 100; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 10; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1; i++; // others, lack of precision - while (i < len && NumberConverter.IsNumber(array[i])) + while (i < to && NumberConverter.IsNumber(array[i])) { i++; } @@ -330,13 +331,13 @@ public DateTime Deserialize(ref JsonReader reader, IJsonFormatterResolver format END_TICKS: var kind = DateTimeKind.Unspecified; - if (i <= len && array[i] == 'Z') + if (i < to && array[i] == 'Z') { kind = DateTimeKind.Utc; } - else if (i < len && array[i] == '-' || array[i] == '+') + else if (i < to && array[i] == '-' || array[i] == '+') { - if (!(i + 5 <= len)) goto ERROR; + if (!(i + 5 < to)) goto ERROR; kind = DateTimeKind.Local; var minus = array[i++] == '-'; @@ -591,6 +592,7 @@ public DateTimeOffset Deserialize(ref JsonReader reader, IJsonFormatterResolver var array = str.Array; var i = str.Offset; var len = str.Count; + var to = str.Offset + str.Count; // YYYY if (len == 4) @@ -637,41 +639,41 @@ public DateTimeOffset Deserialize(ref JsonReader reader, IJsonFormatterResolver var second = (array[i++] - (byte)'0') * 10 + (array[i++] - (byte)'0'); int ticks = 0; - if (i < len && array[i] == '.') + if (i < to && array[i] == '.') { i++; // *7. - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1000000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 100000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 10000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 100; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 10; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1; i++; // others, lack of precision - while (i < len && NumberConverter.IsNumber(array[i])) + while (i < to && NumberConverter.IsNumber(array[i])) { i++; } @@ -679,9 +681,9 @@ public DateTimeOffset Deserialize(ref JsonReader reader, IJsonFormatterResolver END_TICKS: - if (i < len && array[i] == '-' || array[i] == '+') + if (i < to && array[i] == '-' || array[i] == '+') { - if (!(i + 5 <= len)) goto ERROR; + if (!(i + 5 < to)) goto ERROR; var minus = array[i++] == '-'; @@ -853,6 +855,7 @@ public TimeSpan Deserialize(ref JsonReader reader, IJsonFormatterResolver format var array = str.Array; var i = str.Offset; var len = str.Count; + var to = str.Offset + str.Count; // check day exists bool hasDay = false; @@ -914,41 +917,41 @@ public TimeSpan Deserialize(ref JsonReader reader, IJsonFormatterResolver format var second = (array[i++] - (byte)'0') * 10 + (array[i++] - (byte)'0'); int ticks = 0; - if (i < len && array[i] == '.') + if (i < to && array[i] == '.') { i++; // *7. - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1000000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 100000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 10000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1000; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 100; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 10; i++; - if (!(i <= len) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; + if (!(i < to) || !NumberConverter.IsNumber(array[i])) goto END_TICKS; ticks += (array[i] - (byte)'0') * 1; i++; // others, lack of precision - while (i < len && NumberConverter.IsNumber(array[i])) + while (i < to && NumberConverter.IsNumber(array[i])) { i++; } diff --git a/src/Utf8Json/Formatters/StandardClassLibraryFormatters.cs b/src/Utf8Json/Formatters/StandardClassLibraryFormatters.cs index 03ef6ab..9c5aebe 100644 --- a/src/Utf8Json/Formatters/StandardClassLibraryFormatters.cs +++ b/src/Utf8Json/Formatters/StandardClassLibraryFormatters.cs @@ -579,7 +579,11 @@ public Lazy Deserialize(ref JsonReader reader, IJsonFormatterResolver formatt // deserialize immediately(no delay, because capture byte[] causes memory leak) var v = formatterResolver.GetFormatterWithVerify().Deserialize(ref reader, formatterResolver); +#if NETSTANDARD return new Lazy(v.AsFunc()); +#else + return new Lazy(() => v); +#endif } } @@ -639,7 +643,7 @@ public ValueTask Deserialize(ref JsonReader reader, IJsonFormatterResolver fo } #endif -} + } namespace Utf8Json.Formatters.Internal { diff --git a/src/Utf8Json/Internal/FuncExtensions.cs b/src/Utf8Json/Internal/FuncExtensions.cs index b48142b..9298123 100644 --- a/src/Utf8Json/Internal/FuncExtensions.cs +++ b/src/Utf8Json/Internal/FuncExtensions.cs @@ -1,18 +1,22 @@ -using System; +#if NETSTANDARD + +using System; namespace Utf8Json.Internal { + // Unity compiler can't understand this. + internal static class FuncExtensions { // hack of avoid closure allocation(() => value). public static Func AsFunc(this T value) { - return value.ReturnBox; + return new Func(value.ReturnBox); } public static Func AsFuncFast(this T value) where T : class { - return value.Return; + return new Func(value.Return); } static T Return(this T value) @@ -26,3 +30,6 @@ static T ReturnBox(this object value) } } } + + +#endif \ No newline at end of file diff --git a/src/Utf8Json/_AssemblyInfo.cs b/src/Utf8Json/_AssemblyInfo.cs index e7b5145..2c3165d 100644 --- a/src/Utf8Json/_AssemblyInfo.cs +++ b/src/Utf8Json/_AssemblyInfo.cs @@ -12,5 +12,5 @@ [assembly: ComVisible(false)] [assembly: Guid("929e3779-4c3a-42a3-bc72-3d77511e988f")] -[assembly: AssemblyVersion("1.2.1")] -[assembly: AssemblyFileVersion("1.2.1")] +[assembly: AssemblyVersion("1.2.2")] +[assembly: AssemblyFileVersion("1.2.2")] diff --git a/tests/Utf8Json.Tests/DateAndTime.cs b/tests/Utf8Json.Tests/DateAndTime.cs index 997ae33..273e46a 100644 --- a/tests/Utf8Json.Tests/DateAndTime.cs +++ b/tests/Utf8Json.Tests/DateAndTime.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using Utf8Json.Resolvers; using Xunit; namespace Utf8Json.Tests @@ -99,6 +100,53 @@ public void ShortFormat() JsonSerializer.Deserialize(JsonSerializer.Serialize("2017-12")).Is(new DateTimeOffset(2017, 12, 1, 0, 0, 0, TimeSpan.Zero)); JsonSerializer.Deserialize(JsonSerializer.Serialize("2017-12-30")).Is(new DateTimeOffset(2017, 12, 30, 0, 0, 0, TimeSpan.Zero)); } + + [Fact] + public void Offset() + { + DateTimeOffset now = new DateTime(DateTime.UtcNow.Ticks + TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time").BaseUtcOffset.Ticks, DateTimeKind.Local); + var binary = " " + JsonSerializer.ToJsonString(now); + JsonSerializer.Deserialize(binary).Is(now); + + foreach (var item in new[] { TimeSpan.MaxValue, TimeSpan.MinValue, TimeSpan.MaxValue.Add(TimeSpan.FromTicks(-1)), TimeSpan.MinValue.Add(TimeSpan.FromTicks(1)), TimeSpan.Zero }) + { + var ts = JsonSerializer.Deserialize(" " + JsonSerializer.ToJsonString(item)); + ts.Is(item); + } + + foreach (var item in new[] { DateTime.MaxValue, DateTime.MaxValue.AddTicks(-1), DateTime.MinValue.AddTicks(1) }) + { + var ts = JsonSerializer.Deserialize(" " + JsonSerializer.ToJsonString(item)); + ts.Is(item); + } + + foreach (var item in new[] { DateTimeOffset.MinValue.ToUniversalTime(), DateTimeOffset.MaxValue.ToUniversalTime() }) + { + var ts = JsonSerializer.Deserialize(" " + JsonSerializer.ToJsonString(item)); + ts.Is(item); + } + + foreach (var item in new[] { new DateTimeOffset(DateTime.MinValue.Ticks, new TimeSpan(-1, 0, 0)) }) + { + var ts = JsonSerializer.Deserialize(" " + JsonSerializer.ToJsonString(item)); + ts.Is(item); + } + } + + [Fact] + public void Issue20() + { + var input = "{\"Flag\":false,\"StatusDate\":\"1970-01-01T09:15:10+00:00\"}"; + var deserialized = (Test)Utf8Json.JsonSerializer.NonGeneric.Deserialize(typeof(Test), input, StandardResolver.ExcludeNull); + deserialized.Flag.IsFalse(); + deserialized.StatusDate.Is(new DateTimeOffset(1970, 1, 1, 9, 15, 10, TimeSpan.Zero)); + } + + public class Test + { + public bool Flag { get; set; } + public DateTimeOffset? StatusDate { get; set; } + } } }