Cache the escaped property names (dotnet/corefx#37909)
authorSteve Harter <steveharter@users.noreply.github.com>
Thu, 30 May 2019 13:41:20 +0000 (06:41 -0700)
committerAdam Sitnik <adam.sitnik@gmail.com>
Thu, 30 May 2019 13:41:20 +0000 (15:41 +0200)
* Cache the escaped property names

* don't pass JsonEncodedText by reference

Commit migrated from https://github.com/dotnet/corefx/commit/7a76510746112df1d4d4b97609df2fc9bd47d30a

27 files changed:
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterBoolean.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterByte.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterChar.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTime.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDateTimeOffset.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDecimal.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterDouble.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterEnum.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterGuid.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt16.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt32.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterInt64.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterJsonElement.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterObject.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSByte.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterSingle.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterString.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt16.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt32.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/JsonValueConverterUInt64.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNotNullable.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoNullable.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleDictionary.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleObject.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Policies/JsonValueConverter.cs
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs

index 9526f67..a0e816e 100644 (file)
@@ -25,9 +25,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteBooleanValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, bool value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, bool value, Utf8JsonWriter writer)
         {
-            writer.WriteBoolean(escapedPropertyName, value);
+            writer.WriteBoolean(propertyName, value);
         }
     }
 }
index 174a87b..6ea1850 100644 (file)
@@ -27,9 +27,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, byte value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, byte value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 475a6bd..787253a 100644 (file)
@@ -32,9 +32,9 @@ namespace System.Text.Json.Serialization.Converters
                 );
         }
 
-        public override void Write(Span<byte> escapedPropertyName, char value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, char value, Utf8JsonWriter writer)
         {
-            writer.WriteString(escapedPropertyName,
+            writer.WriteString(propertyName,
 #if BUILDING_INBOX_LIBRARY
                 MemoryMarshal.CreateSpan(ref value, 1)
 #else
index 9abbfa7..904c298 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteStringValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, DateTime value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, DateTime value, Utf8JsonWriter writer)
         {
-            writer.WriteString(escapedPropertyName, value);
+            writer.WriteString(propertyName, value);
         }
     }
 }
index 0567bfb..eb31e55 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteStringValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, DateTimeOffset value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, DateTimeOffset value, Utf8JsonWriter writer)
         {
-            writer.WriteString(escapedPropertyName, value);
+            writer.WriteString(propertyName, value);
         }
     }
 }
index ed90587..d4993d1 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, decimal value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, decimal value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 5d23696..b69ae07 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, double value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, double value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 3778957..653ff7b 100644 (file)
@@ -77,23 +77,23 @@ namespace System.Text.Json.Serialization.Converters
             }
         }
 
-        public override void Write(Span<byte> escapedPropertyName, TValue value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, TValue value, Utf8JsonWriter writer)
         {
             if (TreatAsString)
             {
-                writer.WriteString(escapedPropertyName, value.ToString());
+                writer.WriteString(propertyName, value.ToString());
             }
             else if (s_isUint64)
             {
                 // Use the ulong converter to prevent conversion into a signed\long value.
                 ulong ulongValue = Convert.ToUInt64(value);
-                writer.WriteNumber(escapedPropertyName, ulongValue);
+                writer.WriteNumber(propertyName, ulongValue);
             }
             else
             {
                 // long can hold the signed\unsigned values of other integer types.
                 long longValue = Convert.ToInt64(value);
-                writer.WriteNumber(escapedPropertyName, longValue);
+                writer.WriteNumber(propertyName, longValue);
             }
         }
     }
index c249e36..5479ced 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteStringValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, Guid value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, Guid value, Utf8JsonWriter writer)
         {
-            writer.WriteString(escapedPropertyName, value);
+            writer.WriteString(propertyName, value);
         }
     }
 }
index 16fe1d5..acd965d 100644 (file)
@@ -27,9 +27,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, short value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, short value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index de21818..aa9932f 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, int value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, int value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index b9d18dd..5b5d621 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, long value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, long value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index ca750ae..423f463 100644 (file)
@@ -28,9 +28,9 @@ namespace System.Text.Json.Serialization.Converters
             value.WriteAsValue(writer);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, JsonElement value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, JsonElement value, Utf8JsonWriter writer)
         {
-            value.WriteAsProperty(escapedPropertyName, writer);
+            value.WriteAsProperty(propertyName.ToString(), writer);
         }
     }
 }
index 3a099d7..ccd8125 100644 (file)
@@ -28,7 +28,7 @@ namespace System.Text.Json.Serialization.Converters
             throw new InvalidOperationException();
         }
 
-        public override void Write(Span<byte> escapedPropertyName, object value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, object value, Utf8JsonWriter writer)
         {
             throw new InvalidOperationException();
         }
index 786a740..25a7cfe 100644 (file)
@@ -27,9 +27,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, sbyte value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, sbyte value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 32093e3..a2fefee 100644 (file)
@@ -27,9 +27,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, float value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, float value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index f5120cf..0c84b91 100644 (file)
@@ -25,9 +25,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteStringValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, string value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, string value, Utf8JsonWriter writer)
         {
-            writer.WriteString(escapedPropertyName, value);
+            writer.WriteString(propertyName, value);
         }
     }
 }
index cb232e6..54799f9 100644 (file)
@@ -27,9 +27,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, ushort value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, ushort value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 94e7dfc..ee5553c 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, uint value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, uint value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 7a52f4b..d5f8174 100644 (file)
@@ -24,9 +24,9 @@ namespace System.Text.Json.Serialization.Converters
             writer.WriteNumberValue(value);
         }
 
-        public override void Write(Span<byte> escapedPropertyName, ulong value, Utf8JsonWriter writer)
+        public override void Write(JsonEncodedText propertyName, ulong value, Utf8JsonWriter writer)
         {
-            writer.WriteNumber(escapedPropertyName, value);
+            writer.WriteNumber(propertyName, value);
         }
     }
 }
index 07936ee..bf778fe 100644 (file)
@@ -38,7 +38,7 @@ namespace System.Text.Json.Serialization
         public string NameUsedToCompareAsString { get; private set; }
 
         // The escaped name passed to the writer.
-        public byte[] EscapedName { get; private set; }
+        public JsonEncodedText? EscapedName { get; private set; }
 
         public bool HasGetter { get; set; }
         public bool HasSetter { get; set; }
@@ -171,36 +171,7 @@ namespace System.Text.Json.Serialization
             }
 
             // Cache the escaped name.
-#if true
-            // temporary behavior until the writer can accept escaped string.
-            EscapedName = Name;
-#else
-            int valueIdx = JsonWriterHelper.NeedsEscaping(_name);
-            if (valueIdx == -1)
-            {
-                _escapedName = _name;
-            }
-            else
-            {
-                byte[] pooledName = null;
-                int length = JsonWriterHelper.GetMaxEscapedLength(_name.Length, valueIdx);
-
-                Span<byte> escapedName = length <= JsonConstants.StackallocThreshold ?
-                    stackalloc byte[length] :
-                    (pooledName = ArrayPool<byte>.Shared.Rent(length));
-
-                JsonWriterHelper.EscapeString(_name, escapedName, 0, out int written);
-
-                _escapedName = escapedName.Slice(0, written).ToArray();
-
-                if (pooledName != null)
-                {
-                    // We clear the array because it is "user data" (although a property name).
-                    new Span<byte>(pooledName, 0, written).Clear();
-                    ArrayPool<byte>.Shared.Return(pooledName);
-                }
-            }
-#endif
+            EscapedName = JsonEncodedText.Encode(Name);
         }
 
         private void DetermineSerializationCapabilities()
index 6fdeb2d..da90283 100644 (file)
@@ -78,18 +78,18 @@ namespace System.Text.Json.Serialization
 
             if (value == null)
             {
-                Debug.Assert(EscapedName != null);
+                Debug.Assert(EscapedName.HasValue);
 
                 if (!IgnoreNullValues)
                 {
-                    writer.WriteNull(EscapedName);
+                    writer.WriteNull(EscapedName.Value);
                 }
             }
             else if (ValueConverter != null)
             {
-                if (EscapedName != null)
+                if (EscapedName.HasValue)
                 {
-                    ValueConverter.Write(EscapedName, value, writer);
+                    ValueConverter.Write(EscapedName.Value, value, writer);
                 }
                 else
                 {
index b52a828..f3a65e7 100644 (file)
@@ -77,18 +77,18 @@ namespace System.Text.Json.Serialization
 
                 if (value == null)
                 {
-                    Debug.Assert(EscapedName != null);
+                    Debug.Assert(EscapedName.HasValue);
 
                     if (!IgnoreNullValues)
                     {
-                        writer.WriteNull(EscapedName);
+                        writer.WriteNull(EscapedName.Value);
                     }
                 }
                 else if (ValueConverter != null)
                 {
-                    if (EscapedName != null)
+                    if (EscapedName.HasValue)
                     {
-                        ValueConverter.Write(EscapedName, value.GetValueOrDefault(), writer);
+                        ValueConverter.Write(EscapedName.Value, value.GetValueOrDefault(), writer);
                     }
                     else
                     {
index ccbccd5..468aee8 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -124,37 +125,8 @@ namespace System.Text.Json.Serialization
             }
             else
             {
-                byte[] utf8Key = Encoding.UTF8.GetBytes(key);
-#if true
-                // temporary behavior until the writer can accept escaped string.
-                converter.Write(utf8Key, value, writer);
-#else
-                int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Key);
-                if (valueIdx == -1)
-                {
-                    converter.Write(utf8Key, value, writer);
-                }
-                else
-                {
-                    byte[] pooledKey = null;
-                    int length = JsonWriterHelper.GetMaxEscapedLength(utf8Key.Length, valueIdx);
-
-                    Span<byte> escapedKey = length <= JsonConstants.StackallocThreshold ?
-                        stackalloc byte[length] :
-                        (pooledKey = ArrayPool<byte>.Shared.Rent(length));
-
-                    JsonWriterHelper.EscapeString(utf8Key, escapedKey, valueIdx, out int written);
-
-                    converter.Write(escapedKey.Slice(0, written), value, writer);
-
-                    if (pooledKey != null)
-                    {
-                        // We clear the array because it is "user data" (although a property name).
-                        new Span<byte>(pooledKey, 0, written).Clear();
-                        ArrayPool<byte>.Shared.Return(pooledKey);
-                    }
-                }
-#endif
+                JsonEncodedText escapedKey = JsonEncodedText.Encode(key);
+                converter.Write(escapedKey, value, writer);
             }
         }
 
index 80275ee..3dc24aa 100644 (file)
@@ -126,7 +126,7 @@ namespace System.Text.Json.Serialization
             {
                 if (!jsonPropertyInfo.IgnoreNullValues)
                 {
-                    writer.WriteNull(jsonPropertyInfo.EscapedName);
+                    writer.WriteNull(jsonPropertyInfo.EscapedName.Value);
                 }
 
                 state.Current.NextProperty();
index 3598e34..6a0cf5d 100644 (file)
@@ -8,6 +8,6 @@ namespace System.Text.Json.Serialization.Policies
     {
         public abstract bool TryRead(Type valueType, ref Utf8JsonReader reader, out TValue value);
         public abstract void Write(TValue value, Utf8JsonWriter writer);
-        public abstract void Write(Span<byte> escapedPropertyName, TValue value, Utf8JsonWriter writer);
+        public abstract void Write(JsonEncodedText propertyName, TValue value, Utf8JsonWriter writer);
     }
 }
index 660bb44..f77bf4c 100644 (file)
@@ -46,29 +46,14 @@ namespace System.Text.Json.Serialization
 
         public void WriteObjectOrArrayStart(ClassType classType, Utf8JsonWriter writer, bool writeNull = false)
         {
-            if (JsonPropertyInfo?.EscapedName != null)
+            if (JsonPropertyInfo?.EscapedName.HasValue == true)
             {
-                WriteObjectOrArrayStart(classType, JsonPropertyInfo?.EscapedName, writer, writeNull);
+                WriteObjectOrArrayStart(classType, JsonPropertyInfo.EscapedName.Value, writer, writeNull);
             }
             else if (KeyName != null)
             {
-                byte[] pooledKey = null;
-                byte[] utf8Key = Encoding.UTF8.GetBytes(KeyName);
-                int length = JsonWriterHelper.GetMaxEscapedLength(utf8Key.Length, 0);
-
-                Span<byte> escapedKey = length <= JsonConstants.StackallocThreshold ?
-                    stackalloc byte[length] :
-                    (pooledKey = ArrayPool<byte>.Shared.Rent(length));
-
-                JsonWriterHelper.EscapeString(utf8Key, escapedKey, 0, out int written);
-                Span<byte> propertyName = escapedKey.Slice(0, written);
-
+                JsonEncodedText propertyName = JsonEncodedText.Encode(KeyName);
                 WriteObjectOrArrayStart(classType, propertyName, writer, writeNull);
-
-                if (pooledKey != null)
-                {
-                    ArrayPool<byte>.Shared.Return(pooledKey);
-                }
             }
             else
             {
@@ -88,7 +73,7 @@ namespace System.Text.Json.Serialization
             }
         }
 
-        private void WriteObjectOrArrayStart(ClassType classType, ReadOnlySpan<byte> propertyName, Utf8JsonWriter writer, bool writeNull)
+        private void WriteObjectOrArrayStart(ClassType classType, JsonEncodedText propertyName, Utf8JsonWriter writer, bool writeNull)
         {
             if (writeNull)
             {