Add support for escaped characters in JsonString (for {Try}GetDateTime{Offset}) ...
authorEugene Samoylov <eugenesmlv@gmail.com>
Mon, 9 Dec 2019 07:56:59 +0000 (12:56 +0500)
committerAhson Khan <ahson_ahmedk@yahoo.com>
Mon, 9 Dec 2019 07:56:59 +0000 (23:56 -0800)
* Add support for escaped characters in JsonString (for {Try}GetDateTime{Offset})

* Fix the review issues

* Fix a mistake after resolving a merge conflict

* Change `var` to explicit type

src/libraries/System.Text.Json/src/System/Text/Json/JsonHelpers.Date.cs
src/libraries/System.Text.Json/src/System/Text/Json/Node/JsonString.cs
src/libraries/System.Text.Json/tests/JsonStringTests.cs

index 978640c..af0d996 100644 (file)
@@ -58,7 +58,23 @@ namespace System.Text.Json
 
             int length = JsonReaderHelper.GetUtf8FromText(source, bytes);
 
-            return TryParseAsISO(bytes.Slice(0, length), out value);
+            bytes = bytes.Slice(0, length);
+
+            if (bytes.IndexOf(JsonConstants.BackSlash) != -1)
+            {
+                return JsonReaderHelper.TryGetEscapedDateTime(bytes, out value);
+            }
+
+            Debug.Assert(bytes.IndexOf(JsonConstants.BackSlash) == -1);
+
+            if (TryParseAsISO(bytes, out DateTime tmp))
+            {
+                value = tmp;
+                return true;
+            }
+
+            value = default;
+            return false;
         }
 
         public static bool TryParseAsISO(ReadOnlySpan<char> source, out DateTimeOffset value)
@@ -77,7 +93,23 @@ namespace System.Text.Json
 
             int length = JsonReaderHelper.GetUtf8FromText(source, bytes);
 
-            return TryParseAsISO(bytes.Slice(0, length), out value);
+            bytes = bytes.Slice(0, length);
+
+            if (bytes.IndexOf(JsonConstants.BackSlash) != -1)
+            {
+                return JsonReaderHelper.TryGetEscapedDateTimeOffset(bytes, out value);
+            }
+
+            Debug.Assert(bytes.IndexOf(JsonConstants.BackSlash) == -1);
+
+            if (TryParseAsISO(bytes, out DateTimeOffset tmp))
+            {
+                value = tmp;
+                return true;
+            }
+
+            value = default;
+            return false;
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
index a896a82..3b34dbb 100644 (file)
@@ -109,7 +109,7 @@ namespace System.Text.Json
         ///   A return value indicates whether the conversion succeeded.
         /// </summary>
         /// <param name="value">
-        ///   When this method returns, contains the see cref="DateTime"/> value equivalent of the text contained in this instance,
+        ///   When this method returns, contains the <see cref="DateTime"/> value equivalent of the text contained in this instance,
         ///   if the conversion succeeded, or zero if the conversion failed.
         /// </param>
         /// <returns>
index 0342ded..eb664e6 100644 (file)
@@ -111,6 +111,25 @@ namespace System.Text.Json.Tests
         }
 
         [Theory]
+        [MemberData(nameof(JsonDateTimeTestData.ValidISO8601Tests), MemberType = typeof(JsonDateTimeTestData))]
+        public static void TestDateTimeAndDateTimeOffsetWithEscapedChars(string testStr, string iso8601Str)
+        {
+            string trimmedTestStr = testStr.Trim('"');
+
+            var jsonString = new JsonString(trimmedTestStr);
+            var dateTime = DateTime.Parse(iso8601Str);
+            var dateTimeOffset = DateTimeOffset.Parse(iso8601Str);
+
+            Assert.Equal(dateTime, jsonString.GetDateTime());
+            Assert.True(jsonString.TryGetDateTime(out DateTime dateTime2));
+            Assert.Equal(dateTime, dateTime2);
+
+            Assert.Equal(dateTimeOffset, jsonString.GetDateTimeOffset());
+            Assert.True(jsonString.TryGetDateTimeOffset(out DateTimeOffset dateTimeOffset2));
+            Assert.Equal(dateTimeOffset, dateTimeOffset2);
+        }
+
+        [Theory]
         [MemberData(nameof(JsonDateTimeTestData.InvalidISO8601Tests), MemberType = typeof(JsonDateTimeTestData))]
         public static void TestInvalidDateTime(string testStr)
         {