From 20b0d3104d9ddbc088aee416a8b4d1632aec4ab3 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Tue, 16 Jul 2019 09:29:20 -0700 Subject: [PATCH] Add Encoder option to writer and serializer (dotnet/corefx#39524) Commit migrated from https://github.com/dotnet/corefx/commit/bc10b53838bc84ac2b626e16eee1338183ee55c8 --- .../System.Text.Json/ref/System.Text.Json.cs | 23 +- .../Json/Serialization/JsonSerializerOptions.cs | 20 ++ .../Text/Json/Writer/JsonWriterHelper.Escaping.cs | 237 +++++++++++++++------ .../System/Text/Json/Writer/JsonWriterOptions.cs | 7 + .../Writer/Utf8JsonWriter.WriteProperties.Bytes.cs | 16 +- .../Utf8JsonWriter.WriteProperties.DateTime.cs | 16 +- ...tf8JsonWriter.WriteProperties.DateTimeOffset.cs | 16 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 16 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 16 +- .../Writer/Utf8JsonWriter.WriteProperties.Float.cs | 16 +- ...f8JsonWriter.WriteProperties.FormattedNumber.cs | 12 +- .../Writer/Utf8JsonWriter.WriteProperties.Guid.cs | 16 +- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 16 +- .../Utf8JsonWriter.WriteProperties.SignedNumber.cs | 16 +- .../Utf8JsonWriter.WriteProperties.String.cs | 78 +++---- ...tf8JsonWriter.WriteProperties.UnsignedNumber.cs | 16 +- .../Writer/Utf8JsonWriter.WriteValues.Bytes.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Comment.cs | 4 +- .../Writer/Utf8JsonWriter.WriteValues.DateTime.cs | 2 +- .../Utf8JsonWriter.WriteValues.DateTimeOffset.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Decimal.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Double.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Float.cs | 2 +- .../Utf8JsonWriter.WriteValues.FormattedNumber.cs | 2 +- .../Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Helpers.cs | 4 +- .../Writer/Utf8JsonWriter.WriteValues.Literal.cs | 2 +- .../Utf8JsonWriter.WriteValues.SignedNumber.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.String.cs | 12 +- .../Utf8JsonWriter.WriteValues.UnsignedNumber.cs | 2 +- .../src/System/Text/Json/Writer/Utf8JsonWriter.cs | 48 +++-- .../tests/JsonElementWriteTests.cs | 2 +- .../tests/Serialization/OptionsTests.cs | 86 ++++++++ .../System.Text.Json/tests/Utf8JsonWriterTests.cs | 172 +++++++++++---- 35 files changed, 602 insertions(+), 293 deletions(-) diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index b4120e2..36a42ce 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -164,8 +164,8 @@ namespace System.Text.Json public bool NameEquals(System.ReadOnlySpan utf8Text) { throw null; } public bool NameEquals(System.ReadOnlySpan text) { throw null; } public bool NameEquals(string text) { throw null; } - public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { } public override string ToString() { throw null; } + public void WriteTo(System.Text.Json.Utf8JsonWriter writer) { } } public partial struct JsonReaderOptions { @@ -185,20 +185,20 @@ namespace System.Text.Json { public static object Deserialize(System.ReadOnlySpan utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } public static object Deserialize(string json, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions options = null) { throw null; } + public static object Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.ValueTask DeserializeAsync(System.IO.Stream utf8Json, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static object Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Type returnType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } + public static TValue Deserialize(System.ReadOnlySpan utf8Json, System.Text.Json.JsonSerializerOptions options = null) { throw null; } + public static TValue Deserialize(string json, System.Text.Json.JsonSerializerOptions options = null) { throw null; } public static TValue Deserialize(ref System.Text.Json.Utf8JsonReader reader, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static string Serialize(object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static byte[] SerializeToUtf8Bytes(object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions options = null) { throw null; } - public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static string Serialize(object value, System.Type type, System.Text.Json.JsonSerializerOptions options = null) { throw null; } + public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object value, System.Type type, System.Text.Json.JsonSerializerOptions options = null) { } + public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, object value, System.Type type, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task SerializeAsync(System.IO.Stream utf8Json, TValue value, System.Text.Json.JsonSerializerOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - public static void Serialize(System.Text.Json.Utf8JsonWriter writer, object value, System.Type inputType, System.Text.Json.JsonSerializerOptions options = null) { } + public static byte[] SerializeToUtf8Bytes(object value, System.Type type, System.Text.Json.JsonSerializerOptions options = null) { throw null; } + public static byte[] SerializeToUtf8Bytes(TValue value, System.Text.Json.JsonSerializerOptions options = null) { throw null; } public static void Serialize(System.Text.Json.Utf8JsonWriter writer, TValue value, System.Text.Json.JsonSerializerOptions options = null) { } + public static string Serialize(TValue value, System.Text.Json.JsonSerializerOptions options = null) { throw null; } } public sealed partial class JsonSerializerOptions { @@ -207,6 +207,7 @@ namespace System.Text.Json public System.Collections.Generic.IList Converters { get { throw null; } } public int DefaultBufferSize { get { throw null; } set { } } public System.Text.Json.JsonNamingPolicy DictionaryKeyPolicy { get { throw null; } set { } } + public System.Text.Encodings.Web.JavaScriptEncoder Encoder { get { throw null; } set { } } public bool IgnoreNullValues { get { throw null; } set { } } public bool IgnoreReadOnlyProperties { get { throw null; } set { } } public int MaxDepth { get { throw null; } set { } } @@ -244,7 +245,9 @@ namespace System.Text.Json } public partial struct JsonWriterOptions { + private object _dummy; private int _dummyPrimitive; + public System.Text.Encodings.Web.JavaScriptEncoder Encoder { readonly get { throw null; } set { } } public bool Indented { get { throw null; } set { } } public bool SkipValidation { get { throw null; } set { } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index fa679aa..d213e55 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Concurrent; using System.Diagnostics; using System.Text.Json.Serialization; +using System.Text.Encodings.Web; namespace System.Text.Json { @@ -25,6 +26,7 @@ namespace System.Text.Json private JsonNamingPolicy _dictionayKeyPolicy; private JsonNamingPolicy _jsonPropertyNamingPolicy; private JsonCommentHandling _readCommentHandling; + private JavaScriptEncoder _encoder; private int _defaultBufferSize = BufferSizeDefault; private int _maxDepth; private bool _allowTrailingCommas; @@ -93,6 +95,23 @@ namespace System.Text.Json } /// + /// The encoder to use when escaping strings, or to use the default encoder. + /// + public JavaScriptEncoder Encoder + { + get + { + return _encoder; + } + set + { + VerifyMutable(); + + _encoder = value; + } + } + + /// /// Specifies the policy used to convert a key's name to another format, such as camel-casing. /// /// @@ -324,6 +343,7 @@ namespace System.Text.Json { return new JsonWriterOptions { + Encoder = Encoder, Indented = WriteIndented, #if !DEBUG SkipValidation = true diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 891fcf6..4986bf0 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -6,7 +6,9 @@ using System.Buffers; using System.Buffers.Text; using System.Diagnostics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text.Encodings.Web; +using System.Text.Unicode; namespace System.Text.Json { @@ -40,13 +42,19 @@ namespace System.Text.Json return AllowList[value] == 0; } + private static bool NeedsEscapingNoBoundsCheck(char value) + { + Debug.Assert(value <= LastAsciiCharacter); + return AllowList[value] == 0; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedsEscaping(byte value) => value > LastAsciiCharacter || AllowList[value] == 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedsEscaping(char value) => value > LastAsciiCharacter || AllowList[value] == 0; - public static int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder encoder = null) + public static int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder encoder) { if (encoder != null) { @@ -68,8 +76,13 @@ namespace System.Text.Json return idx; } - public static int NeedsEscaping(ReadOnlySpan value) + public static int NeedsEscaping(ReadOnlySpan value, JavaScriptEncoder encoder) { + if (encoder != null) + { + return encoder.FindFirstCharacterToEncodeUtf8(MemoryMarshal.Cast(value)); + } + int idx; for (idx = 0; idx < value.Length; idx++) { @@ -92,6 +105,24 @@ namespace System.Text.Json return firstIndexToEscape + JsonConstants.MaxExpansionFactorWhileEscaping * (textLength - firstIndexToEscape); } + private static void EscapeString(ReadOnlySpan value, Span destination, JavaScriptEncoder encoder, ref int written) + { + Debug.Assert(encoder != null); + + OperationStatus result = encoder.EncodeUtf8(value, destination, out int encoderBytesConsumed, out int encoderBytesWritten); + + Debug.Assert(result != OperationStatus.DestinationTooSmall); + Debug.Assert(result != OperationStatus.NeedMoreData); + Debug.Assert(encoderBytesConsumed == value.Length); + + if (result != OperationStatus.Done) + { + ThrowHelper.ThrowArgumentException_InvalidUTF8(value.Slice(encoderBytesWritten)); + } + + written += encoderBytesWritten; + } + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, JavaScriptEncoder encoder, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -102,19 +133,9 @@ namespace System.Text.Json if (encoder != null) { - OperationStatus result = encoder.EncodeUtf8( - value.Slice(consumed), destination.Slice(written), out int encoderBytesConsumed, out int encoderBytesWritten); - - Debug.Assert(result != OperationStatus.DestinationTooSmall); - Debug.Assert(result != OperationStatus.NeedMoreData); - Debug.Assert(encoderBytesConsumed == value.Length - consumed); - - if (result != OperationStatus.Done) - { - ThrowHelper.ThrowArgumentException_InvalidUTF8(value.Slice(encoderBytesWritten)); - } - - written += encoderBytesWritten; + destination = destination.Slice(indexOfFirstByteToEscape); + value = value.Slice(indexOfFirstByteToEscape); + EscapeString(value, destination, encoder, ref written); } else { @@ -139,21 +160,11 @@ namespace System.Text.Json } else { - // Fall back to default encoder - OperationStatus result = JavaScriptEncoder.Default.EncodeUtf8( - value.Slice(consumed), destination.Slice(written), out int encoderBytesConsumed, out int encoderBytesWritten); - - Debug.Assert(result != OperationStatus.DestinationTooSmall); - Debug.Assert(result != OperationStatus.NeedMoreData); - Debug.Assert(encoderBytesConsumed == value.Length - consumed); - - if (result != OperationStatus.Done) - { - ThrowHelper.ThrowArgumentException_InvalidUTF8(value.Slice(encoderBytesConsumed)); - } - - consumed += encoderBytesConsumed; - written += encoderBytesWritten; + // Fall back to default encoder. + destination = destination.Slice(written); + value = value.Slice(consumed); + EscapeString(value, destination, JavaScriptEncoder.Default, ref written); + break; } } } @@ -203,6 +214,8 @@ namespace System.Text.Json private static bool IsAsciiValue(byte value) => value <= LastAsciiCharacter; + private static bool IsAsciiValue(char value) => value <= LastAsciiCharacter; + /// /// Returns if is a UTF-8 continuation byte. /// A UTF-8 continuation byte is a byte whose value is in the range 0x80-0xBF, inclusive. @@ -410,49 +423,148 @@ namespace System.Text.Json return SequenceValidity.Incomplete; } - public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, out int written) + private static void EscapeString(ReadOnlySpan value, Span destination, JavaScriptEncoder encoder, ref int written) { - Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); + // todo: issue #39523: add an Encode(ReadOnlySpan) decode API to System.Text.Encodings.Web.TextEncoding to avoid utf16->utf8->utf16 conversion. - value.Slice(0, indexOfFirstByteToEscape).CopyTo(destination); - written = indexOfFirstByteToEscape; - int consumed = indexOfFirstByteToEscape; + Debug.Assert(encoder != null); - while (consumed < value.Length) + // Convert char to byte. + byte[] utf8DestinationArray = null; + Span utf8Destination; + int length = checked((value.Length) * JsonConstants.MaxExpansionFactorWhileTranscoding); + if (length > JsonConstants.StackallocThreshold) { - char val = value[consumed]; - if (NeedsEscaping(val)) + utf8DestinationArray = ArrayPool.Shared.Rent(length); + utf8Destination = utf8DestinationArray; + } + else + { + unsafe { - EscapeNextChars(value, val, destination, ref consumed, ref written); + byte* ptr = stackalloc byte[JsonConstants.StackallocThreshold]; + utf8Destination = new Span(ptr, JsonConstants.StackallocThreshold); } - else + } + + ReadOnlySpan utf16Value = MemoryMarshal.AsBytes(value); + OperationStatus toUtf8Status = ToUtf8(utf16Value, utf8Destination, out int bytesConsumed, out int bytesWritten); + + Debug.Assert(toUtf8Status != OperationStatus.DestinationTooSmall); + Debug.Assert(toUtf8Status != OperationStatus.NeedMoreData); + + if (toUtf8Status != OperationStatus.Done) + { + if (utf8DestinationArray != null) { - destination[written++] = val; + utf8Destination.Slice(0, bytesWritten).Clear(); + ArrayPool.Shared.Return(utf8DestinationArray); } - consumed++; + + ThrowHelper.ThrowArgumentException_InvalidUTF8(utf16Value.Slice(bytesWritten)); } - } - private static void EscapeNextChars(ReadOnlySpan value, int firstChar, Span destination, ref int consumed, ref int written) - { - int nextChar = -1; - if (JsonHelpers.IsInRangeInclusive(firstChar, JsonConstants.HighSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) + Debug.Assert(toUtf8Status == OperationStatus.Done); + Debug.Assert(bytesConsumed == utf16Value.Length); + + // Escape the bytes. + byte[] utf8ConvertedDestinationArray = null; + Span utf8ConvertedDestination; + length = checked(bytesWritten * JsonConstants.MaxExpansionFactorWhileEscaping); + if (length > JsonConstants.StackallocThreshold) + { + utf8ConvertedDestinationArray = ArrayPool.Shared.Rent(length); + utf8ConvertedDestination = utf8ConvertedDestinationArray; + } + else { - consumed++; - if (value.Length <= consumed || firstChar >= JsonConstants.LowSurrogateStartValue) + unsafe { - ThrowHelper.ThrowArgumentException_InvalidUTF16(firstChar); + byte* ptr = stackalloc byte[JsonConstants.StackallocThreshold]; + utf8ConvertedDestination = new Span(ptr, JsonConstants.StackallocThreshold); } + } + + EscapeString(utf8Destination.Slice(0, bytesWritten), utf8ConvertedDestination, indexOfFirstByteToEscape: 0, encoder, out int convertedBytesWritten); - nextChar = value[consumed]; - if (!JsonHelpers.IsInRangeInclusive(nextChar, JsonConstants.LowSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) + if (utf8DestinationArray != null) + { + utf8Destination.Slice(0, bytesWritten).Clear(); + ArrayPool.Shared.Return(utf8DestinationArray); + } + + // Convert byte to char. +#if BUILDING_INBOX_LIBRARY + OperationStatus toUtf16Status = Utf8.ToUtf16(utf8ConvertedDestination.Slice(0, convertedBytesWritten), destination, out int bytesRead, out int charsWritten); + Debug.Assert(toUtf16Status == OperationStatus.Done); + Debug.Assert(bytesRead == convertedBytesWritten); +#else + string utf16 = JsonReaderHelper.GetTextFromUtf8(utf8ConvertedDestination.Slice(0, convertedBytesWritten)); + utf16.AsSpan().CopyTo(destination); + int charsWritten = utf16.Length; +#endif + written += charsWritten; + + if (utf8ConvertedDestinationArray != null) + { + utf8ConvertedDestination.Slice(0, written).Clear(); + ArrayPool.Shared.Return(utf8ConvertedDestinationArray); + } + } + + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, JavaScriptEncoder encoder, out int written) + { + Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); + + value.Slice(0, indexOfFirstByteToEscape).CopyTo(destination); + written = indexOfFirstByteToEscape; + int consumed = indexOfFirstByteToEscape; + + if (encoder != null) + { + destination = destination.Slice(indexOfFirstByteToEscape); + value = value.Slice(indexOfFirstByteToEscape); + EscapeString(value, destination, encoder, ref written); + } + else + { + // For performance when no encoder is specified, perform escaping here for Ascii and on the + // first occurrence of a non-Ascii character, then call into the default encoder. + while (consumed < value.Length) { - ThrowHelper.ThrowArgumentException_InvalidUTF16(nextChar); + char val = value[consumed]; + if (IsAsciiValue(val)) + { + if (NeedsEscapingNoBoundsCheck(val)) + { + EscapeNextChars(val, destination, ref written); + consumed++; + } + else + { + destination[written] = val; + written++; + consumed++; + } + } + else + { + // Fall back to default encoder. + destination = destination.Slice(written); + value = value.Slice(consumed); + EscapeString(value, destination, JavaScriptEncoder.Default, ref written); + break; + } } } + } + + private static void EscapeNextChars(char value, Span destination, ref int written) + { + Debug.Assert(IsAsciiValue(value)); destination[written++] = '\\'; - switch (firstChar) + switch ((byte)value) { case JsonConstants.Quote: // Optimize for the common quote case. @@ -483,24 +595,13 @@ namespace System.Text.Json default: destination[written++] = 'u'; #if BUILDING_INBOX_LIBRARY - firstChar.TryFormat(destination.Slice(written), out int charsWritten, HexFormatString); + int intChar = value; + intChar.TryFormat(destination.Slice(written), out int charsWritten, HexFormatString); Debug.Assert(charsWritten == 4); written += charsWritten; #else - written = WriteHex(firstChar, destination, written); -#endif - if (nextChar != -1) - { - destination[written++] = '\\'; - destination[written++] = 'u'; -#if BUILDING_INBOX_LIBRARY - nextChar.TryFormat(destination.Slice(written), out charsWritten, HexFormatString); - Debug.Assert(charsWritten == 4); - written += charsWritten; -#else - written = WriteHex(nextChar, destination, written); + written = WriteHex(value, destination, written); #endif - } break; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 2642899..26ca1df 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -2,6 +2,8 @@ // 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.Text.Encodings.Web; + namespace System.Text.Json { /// @@ -15,6 +17,11 @@ namespace System.Text.Json private int _optionsMask; /// + /// The encoder to use when escaping strings, or to use the default encoder. + /// + public JavaScriptEncoder Encoder { get; set; } + + /// /// Defines whether the should pretty print the JSON which includes: /// indenting nested JSON tokens, adding new lines, and adding white space between property names and values. /// By default, the JSON is written without any extra white space. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs index d8dcec9..369d2b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs @@ -106,7 +106,7 @@ namespace System.Text.Json private void WriteBase64Escape(ReadOnlySpan propertyName, ReadOnlySpan bytes) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -122,7 +122,7 @@ namespace System.Text.Json private void WriteBase64Escape(ReadOnlySpan utf8PropertyName, ReadOnlySpan bytes) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -149,7 +149,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteBase64ByOptions(escapedPropertyName.Slice(0, written), bytes); @@ -172,7 +172,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteBase64ByOptions(escapedPropertyName.Slice(0, written), bytes); @@ -185,7 +185,7 @@ namespace System.Text.Json private void WriteBase64ByOptions(ReadOnlySpan propertyName, ReadOnlySpan bytes) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteBase64Indented(propertyName, bytes); } @@ -198,7 +198,7 @@ namespace System.Text.Json private void WriteBase64ByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan bytes) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteBase64Indented(utf8PropertyName, bytes); } @@ -304,7 +304,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -354,7 +354,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 8879cd9..fff19bb 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -108,7 +108,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan propertyName, DateTime value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -124,7 +124,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan utf8PropertyName, DateTime value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -151,7 +151,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -174,7 +174,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -187,7 +187,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(propertyName, value); } @@ -200,7 +200,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, DateTime value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(utf8PropertyName, value); } @@ -309,7 +309,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -361,7 +361,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 6bc2f1b..6462d89 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -108,7 +108,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan propertyName, DateTimeOffset value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -124,7 +124,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan utf8PropertyName, DateTimeOffset value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -151,7 +151,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -174,7 +174,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -187,7 +187,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffset value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(propertyName, value); } @@ -200,7 +200,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, DateTimeOffset value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(utf8PropertyName, value); } @@ -309,7 +309,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -361,7 +361,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 4e3203b..0b8722e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -108,7 +108,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan propertyName, decimal value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -124,7 +124,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, decimal value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -151,7 +151,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -174,7 +174,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -187,7 +187,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(propertyName, value); } @@ -200,7 +200,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, decimal value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(utf8PropertyName, value); } @@ -295,7 +295,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -340,7 +340,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 1b2078c..cd06e83 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -112,7 +112,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan propertyName, double value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -128,7 +128,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, double value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -155,7 +155,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -178,7 +178,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -191,7 +191,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(propertyName, value); } @@ -204,7 +204,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, double value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(utf8PropertyName, value); } @@ -299,7 +299,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -344,7 +344,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 704b398..217d09a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -112,7 +112,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan propertyName, float value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -128,7 +128,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, float value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -155,7 +155,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -178,7 +178,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -191,7 +191,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(propertyName, value); } @@ -204,7 +204,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, float value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(utf8PropertyName, value); } @@ -299,7 +299,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -344,7 +344,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs index ddbf1db..9ed7bf5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.FormattedNumber.cs @@ -82,7 +82,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -98,7 +98,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -125,7 +125,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -148,7 +148,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -161,7 +161,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteLiteralIndented(propertyName, value); } @@ -174,7 +174,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteLiteralIndented(utf8PropertyName, value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 4d2f4fe..afee84c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -108,7 +108,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan propertyName, Guid value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -124,7 +124,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan utf8PropertyName, Guid value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -151,7 +151,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -174,7 +174,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -187,7 +187,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(propertyName, value); } @@ -200,7 +200,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, Guid value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(utf8PropertyName, value); } @@ -303,7 +303,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -352,7 +352,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index 27fa38c..96418aa 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -35,7 +35,7 @@ namespace System.Text.Json [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ValidateWritingProperty() { - if (!Options.SkipValidation) + if (!_options.SkipValidation) { if (!_inObject || _tokenType == JsonTokenType.PropertyName) { @@ -48,7 +48,7 @@ namespace System.Text.Json [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ValidateWritingProperty(byte token) { - if (!Options.SkipValidation) + if (!_options.SkipValidation) { if (!_inObject || _tokenType == JsonTokenType.PropertyName) { @@ -109,7 +109,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -182,7 +182,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index d17ee71..d08c468 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -202,7 +202,7 @@ namespace System.Text.Json private void WriteLiteralEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -218,7 +218,7 @@ namespace System.Text.Json private void WriteLiteralEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -245,7 +245,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteLiteralByOptions(escapedPropertyName.Slice(0, written), value); @@ -268,7 +268,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteLiteralByOptions(escapedPropertyName.Slice(0, written), value); @@ -281,7 +281,7 @@ namespace System.Text.Json private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteLiteralIndented(propertyName, value); } @@ -294,7 +294,7 @@ namespace System.Text.Json private void WriteLiteralByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteLiteralIndented(utf8PropertyName, value); } @@ -390,7 +390,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -435,7 +435,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index eb9d10c..5b1360d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -180,7 +180,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan propertyName, long value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -196,7 +196,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, long value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -223,7 +223,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -246,7 +246,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -259,7 +259,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(propertyName, value); } @@ -272,7 +272,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, long value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(utf8PropertyName, value); } @@ -367,7 +367,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -412,7 +412,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index bd92951..fee7418 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -68,7 +68,7 @@ namespace System.Text.Json { JsonWriterHelper.ValidateProperty(propertyName); - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length && propertyIdx < int.MaxValue / 2); @@ -110,7 +110,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); propertyName = escapedPropertyName.Slice(0, written); } @@ -125,7 +125,7 @@ namespace System.Text.Json private void WriteStringByOptionsPropertyName(ReadOnlySpan propertyName) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndentedPropertyName(propertyName); } @@ -221,7 +221,7 @@ namespace System.Text.Json { JsonWriterHelper.ValidateProperty(utf8PropertyName); - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length && propertyIdx < int.MaxValue / 2); @@ -263,7 +263,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); utf8PropertyName = escapedPropertyName.Slice(0, written); } @@ -278,7 +278,7 @@ namespace System.Text.Json private void WriteStringByOptionsPropertyName(ReadOnlySpan utf8PropertyName) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndentedPropertyName(utf8PropertyName); } @@ -339,7 +339,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -547,7 +547,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateValue(value); - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(value, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < value.Length && valueIdx < int.MaxValue / 2); @@ -631,7 +631,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateValue(utf8Value); - int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < utf8Value.Length && valueIdx < int.MaxValue / 2); @@ -715,7 +715,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateProperty(propertyName); - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length && propertyIdx < int.MaxValue / 2); @@ -787,7 +787,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateProperty(utf8PropertyName); - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length && propertyIdx < int.MaxValue / 2); @@ -849,7 +849,7 @@ namespace System.Text.Json stackalloc byte[length] : (valueArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndex, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndex, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); @@ -872,7 +872,7 @@ namespace System.Text.Json stackalloc char[length] : (valueArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); @@ -895,7 +895,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndex, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndex, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), escapedValue); @@ -918,7 +918,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndex, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndex, _options.Encoder, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), escapedValue); @@ -930,8 +930,8 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int valueIdx = JsonWriterHelper.NeedsEscaping(value, _options.Encoder); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < value.Length && valueIdx < int.MaxValue / 2); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length && propertyIdx < int.MaxValue / 2); @@ -949,8 +949,8 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value, _options.Encoder); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < utf8Value.Length && valueIdx < int.MaxValue / 2); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length && propertyIdx < int.MaxValue / 2); @@ -968,8 +968,8 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value, _options.Encoder); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < utf8Value.Length && valueIdx < int.MaxValue / 2); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length && propertyIdx < int.MaxValue / 2); @@ -987,8 +987,8 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int valueIdx = JsonWriterHelper.NeedsEscaping(value, _options.Encoder); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < value.Length && valueIdx < int.MaxValue / 2); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length && propertyIdx < int.MaxValue / 2); @@ -1032,7 +1032,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, _options.Encoder, out int written); value = escapedValue.Slice(0, written); } @@ -1056,7 +1056,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); propertyName = escapedPropertyName.Slice(0, written); } @@ -1101,7 +1101,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, _options.Encoder, out int written); utf8Value = escapedValue.Slice(0, written); } @@ -1125,7 +1125,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); utf8PropertyName = escapedPropertyName.Slice(0, written); } @@ -1170,7 +1170,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, _options.Encoder, out int written); utf8Value = escapedValue.Slice(0, written); } @@ -1194,7 +1194,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); propertyName = escapedPropertyName.Slice(0, written); } @@ -1239,7 +1239,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, _options.Encoder, out int written); value = escapedValue.Slice(0, written); } @@ -1263,7 +1263,7 @@ namespace System.Text.Json } } - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); utf8PropertyName = escapedPropertyName.Slice(0, written); } @@ -1283,7 +1283,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(propertyName, value); } @@ -1296,7 +1296,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan utf8Value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(utf8PropertyName, utf8Value); } @@ -1309,7 +1309,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan utf8Value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(propertyName, utf8Value); } @@ -1322,7 +1322,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(utf8PropertyName, value); } @@ -1500,7 +1500,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -1549,7 +1549,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -1601,7 +1601,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -1652,7 +1652,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 30b0fad..29d13cc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -188,7 +188,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan propertyName, ulong value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -204,7 +204,7 @@ namespace System.Text.Json private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, ulong value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -231,7 +231,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -254,7 +254,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -267,7 +267,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(propertyName, value); } @@ -280,7 +280,7 @@ namespace System.Text.Json private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, ulong value) { ValidateWritingProperty(); - if (Options.Indented) + if (_options.Indented) { WriteNumberIndented(utf8PropertyName, value); } @@ -375,7 +375,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { @@ -420,7 +420,7 @@ namespace System.Text.Json output[BytesPending++] = JsonConstants.ListSeparator; } - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.PropertyName); if (_tokenType != JsonTokenType.None) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs index 35900c0..e83e3f2 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs @@ -36,7 +36,7 @@ namespace System.Text.Json { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteBase64Indented(bytes); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index ef7ab6b..da0edc4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -53,7 +53,7 @@ namespace System.Text.Json private void WriteCommentByOptions(ReadOnlySpan value) { - if (Options.Indented) + if (_options.Indented) { WriteCommentIndented(value); } @@ -152,7 +152,7 @@ namespace System.Text.Json private void WriteCommentByOptions(ReadOnlySpan utf8Value) { - if (Options.Indented) + if (_options.Indented) { WriteCommentIndented(utf8Value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index f9cd8cb..ef901b4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -23,7 +23,7 @@ namespace System.Text.Json public void WriteStringValue(DateTime value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteStringValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 1c99640..3b02456 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -24,7 +24,7 @@ namespace System.Text.Json public void WriteStringValue(DateTimeOffset value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteStringValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index 412b395..65203c8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -23,7 +23,7 @@ namespace System.Text.Json public void WriteNumberValue(decimal value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteNumberValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index be4f952..f57240f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -27,7 +27,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateDouble(value); ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteNumberValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 186f163..ae0c7a1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -27,7 +27,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateSingle(value); ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteNumberValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs index 4c468f3..6d260ab 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs @@ -28,7 +28,7 @@ namespace System.Text.Json JsonWriterHelper.ValidateNumber(utf8FormattedNumber); ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteNumberValueIndented(utf8FormattedNumber); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index 0a80cdc..cb5729d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -23,7 +23,7 @@ namespace System.Text.Json public void WriteStringValue(Guid value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteStringValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs index 6124a09..283a7c4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -13,7 +13,7 @@ namespace System.Text.Json { private void ValidateWritingValue() { - if (!Options.SkipValidation) + if (!_options.SkipValidation) { if (_inObject) { @@ -60,7 +60,7 @@ namespace System.Text.Json else { Debug.Assert(destination.Length >= written * JsonConstants.MaxExpansionFactorWhileEscaping); - JsonWriterHelper.EscapeString(encodedBytes, destination, firstEscapeIndexVal, encoder: null, out written); + JsonWriterHelper.EscapeString(encodedBytes, destination, firstEscapeIndexVal, _options.Encoder, out written); BytesPending += written; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 2a718f1..836df56 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -48,7 +48,7 @@ namespace System.Text.Json private void WriteLiteralByOptions(ReadOnlySpan utf8Value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteLiteralIndented(utf8Value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 994aa78..35438b1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -36,7 +36,7 @@ namespace System.Text.Json public void WriteNumberValue(long value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteNumberValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 60d6803..36e27ad 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -86,7 +86,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(value, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < value.Length); @@ -103,7 +103,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(value); } @@ -194,7 +194,7 @@ namespace System.Text.Json stackalloc char[length] : (valueArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, _options.Encoder, out int written); WriteStringByOptions(escapedValue.Slice(0, written)); @@ -229,7 +229,7 @@ namespace System.Text.Json private void WriteStringEscape(ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value, _options.Encoder); Debug.Assert(valueIdx >= -1 && valueIdx < utf8Value.Length); @@ -246,7 +246,7 @@ namespace System.Text.Json private void WriteStringByOptions(ReadOnlySpan utf8Value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteStringIndented(utf8Value); } @@ -337,7 +337,7 @@ namespace System.Text.Json stackalloc byte[length] : (valueArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, _options.Encoder, out int written); WriteStringByOptions(escapedValue.Slice(0, written)); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index e961cbd..f6cec3d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -38,7 +38,7 @@ namespace System.Text.Json public void WriteNumberValue(ulong value) { ValidateWritingValue(); - if (Options.Indented) + if (_options.Indented) { WriteNumberValueIndented(value); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index c2c5414..ad421c1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -57,6 +57,8 @@ namespace System.Text.Json // else, no list separator is needed since we are writing the first item. private int _currentDepth; + private JsonWriterOptions _options; // Since JsonWriterOptions is a struct, use a field to avoid a copy for internal code. + /// /// Returns the amount of bytes written by the so far /// that have not yet been flushed to the output and committed. @@ -77,7 +79,13 @@ namespace System.Text.Json /// the which indicates whether to format the output /// while writing and whether to skip structural JSON validation or not. /// - public JsonWriterOptions Options { get; } + public JsonWriterOptions Options + { + get + { + return _options; + } + } private int Indentation => CurrentDepth * JsonConstants.SpacesPerIndent; @@ -111,7 +119,7 @@ namespace System.Text.Json _isNotPrimitive = default; _tokenType = default; _currentDepth = default; - Options = options; + _options = options; // Only allocate if the user writes a JSON payload beyond the depth that the _allocationFreeContainer can handle. // This way we avoid allocations in the common, default cases, and allocate lazily. @@ -147,7 +155,7 @@ namespace System.Text.Json _isNotPrimitive = default; _tokenType = default; _currentDepth = default; - Options = options; + _options = options; // Only allocate if the user writes a JSON payload beyond the depth that the _allocationFreeContainer can handle. // This way we avoid allocations in the common, default cases, and allocate lazily. @@ -451,7 +459,7 @@ namespace System.Text.Json if (CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.DepthTooLarge, _currentDepth, token: default, tokenType: default); - if (Options.IndentedOrNotSkipValidation) + if (_options.IndentedOrNotSkipValidation) { WriteStartSlow(token); } @@ -482,11 +490,11 @@ namespace System.Text.Json private void WriteStartSlow(byte token) { - Debug.Assert(Options.Indented || !Options.SkipValidation); + Debug.Assert(_options.Indented || !_options.SkipValidation); - if (Options.Indented) + if (_options.Indented) { - if (!Options.SkipValidation) + if (!_options.SkipValidation) { ValidateStart(); UpdateBitStackOnStart(token); @@ -495,7 +503,7 @@ namespace System.Text.Json } else { - Debug.Assert(!Options.SkipValidation); + Debug.Assert(!_options.SkipValidation); ValidateStart(); UpdateBitStackOnStart(token); WriteStartMinimized(token); @@ -657,7 +665,7 @@ namespace System.Text.Json private void WriteStartEscape(ReadOnlySpan utf8PropertyName, byte token) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length); @@ -675,7 +683,7 @@ namespace System.Text.Json { ValidateWritingProperty(token); - if (Options.Indented) + if (_options.Indented) { WritePropertyNameIndented(utf8PropertyName, token); } @@ -698,7 +706,7 @@ namespace System.Text.Json stackalloc byte[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, encoder: null, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStartByOptions(escapedPropertyName.Slice(0, written), token); @@ -802,7 +810,7 @@ namespace System.Text.Json private void WriteStartEscape(ReadOnlySpan propertyName, byte token) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName, _options.Encoder); Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length); @@ -820,7 +828,7 @@ namespace System.Text.Json { ValidateWritingProperty(token); - if (Options.Indented) + if (_options.Indented) { WritePropertyNameIndented(propertyName, token); } @@ -843,7 +851,7 @@ namespace System.Text.Json stackalloc char[length] : (propertyArray = ArrayPool.Shared.Rent(length)); - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, _options.Encoder, out int written); WriteStartByOptions(escapedPropertyName.Slice(0, written), token); @@ -879,7 +887,7 @@ namespace System.Text.Json private void WriteEnd(byte token) { - if (Options.IndentedOrNotSkipValidation) + if (_options.IndentedOrNotSkipValidation) { WriteEndSlow(token); } @@ -909,11 +917,11 @@ namespace System.Text.Json private void WriteEndSlow(byte token) { - Debug.Assert(Options.Indented || !Options.SkipValidation); + Debug.Assert(_options.Indented || !_options.SkipValidation); - if (Options.Indented) + if (_options.Indented) { - if (!Options.SkipValidation) + if (!_options.SkipValidation) { ValidateEnd(token); } @@ -921,7 +929,7 @@ namespace System.Text.Json } else { - Debug.Assert(!Options.SkipValidation); + Debug.Assert(!_options.SkipValidation); ValidateEnd(token); WriteEndMinimized(token); } @@ -973,7 +981,7 @@ namespace System.Text.Json } Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth); - Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.None); + Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.None); int maxRequired = indent + 3; // 1 end token, 1-2 bytes for new line diff --git a/src/libraries/System.Text.Json/tests/JsonElementWriteTests.cs b/src/libraries/System.Text.Json/tests/JsonElementWriteTests.cs index 744cc60..ce87015 100644 --- a/src/libraries/System.Text.Json/tests/JsonElementWriteTests.cs +++ b/src/libraries/System.Text.Json/tests/JsonElementWriteTests.cs @@ -1228,7 +1228,7 @@ null, #endif ); - // Temporary hack until we can use the same escape algorithm throughout. + // Temporary hack until we can use the same escape algorithm on both sides and make sure we want uppercase hex. Assert.Equal(expectedValue.NormalizeToJsonNetFormat(), value.NormalizeToJsonNetFormat()); } } diff --git a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs index 6dd4d0b..5dc5607 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs @@ -2,6 +2,9 @@ // 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.Collections.Generic; +using System.Text.Encodings.Web; +using System.Text.Unicode; using Xunit; namespace System.Text.Json.Serialization.Tests @@ -49,6 +52,7 @@ namespace System.Text.Json.Serialization.Tests Assert.False(options.AllowTrailingCommas); Assert.Equal(16 * 1024, options.DefaultBufferSize); Assert.Equal(null, options.DictionaryKeyPolicy); + Assert.Null(options.Encoder); Assert.False(options.IgnoreNullValues); Assert.Equal(0, options.MaxDepth); Assert.Equal(false, options.PropertyNameCaseInsensitive); @@ -69,6 +73,7 @@ namespace System.Text.Json.Serialization.Tests Assert.Throws(() => options.AllowTrailingCommas = options.AllowTrailingCommas); Assert.Throws(() => options.DefaultBufferSize = options.DefaultBufferSize); Assert.Throws(() => options.DictionaryKeyPolicy = options.DictionaryKeyPolicy); + Assert.Throws(() => options.Encoder = JavaScriptEncoder.Default); Assert.Throws(() => options.IgnoreNullValues = options.IgnoreNullValues); Assert.Throws(() => options.MaxDepth = options.MaxDepth); Assert.Throws(() => options.PropertyNameCaseInsensitive = options.PropertyNameCaseInsensitive); @@ -235,5 +240,86 @@ namespace System.Text.Json.Serialization.Tests Assert.Throws(() => JsonSerializer.Deserialize(BasicCompany.s_data, options)); } + + private class TestClassForEncoding + { + public string MyString { get; set; } + } + + // This is a copy of the test data in System.Text.Json.Tests.JsonEncodedTextTests.JsonEncodedTextStringsCustom + public static IEnumerable JsonEncodedTextStringsCustom + { + get + { + return new List + { + new object[] { "age", "\\u0061\\u0067\\u0065" }, + new object[] { "éééééêêêêê", "éééééêêêêê" }, + new object[] { "ééééé\"êêêêê", "ééééé\\u0022êêêêê" }, + new object[] { "ééééé\\u0022êêêêê", "ééééé\\\\\\u0075\\u0030\\u0030\\u0032\\u0032êêêêê" }, + new object[] { "ééééé>>>>>êêêêê", "ééééé\\u003E\\u003E\\u003E\\u003E\\u003Eêêêêê" }, + new object[] { "ééééé\\u003e\\u003eêêêêê", "ééééé\\\\\\u0075\\u0030\\u0030\\u0033\\u0065\\\\\\u0075\\u0030\\u0030\\u0033\\u0065êêêêê" }, + new object[] { "ééééé\\u003E\\u003Eêêêêê", "ééééé\\\\\\u0075\\u0030\\u0030\\u0033\\u0045\\\\\\u0075\\u0030\\u0030\\u0033\\u0045êêêêê" }, + }; + } + } + + [Theory] + [MemberData(nameof(JsonEncodedTextStringsCustom))] + public static void CustomEncoderAllowLatin1Supplement(string message, string expectedMessage) + { + // Latin-1 Supplement block starts from U+0080 and ends at U+00FF + JavaScriptEncoder encoder = JavaScriptEncoder.Create(UnicodeRanges.Latin1Supplement); + + var options = new JsonSerializerOptions(); + options.Encoder = encoder; + + var obj = new TestClassForEncoding(); + obj.MyString = message; + + string baselineJson = JsonSerializer.Serialize(obj); + Assert.DoesNotContain(expectedMessage, baselineJson); + + string json = JsonSerializer.Serialize(obj, options); + Assert.Contains(expectedMessage, json); + + obj = JsonSerializer.Deserialize(json); + Assert.Equal(obj.MyString, message); + } + + public static IEnumerable JsonEncodedTextStringsCustomAll + { + get + { + return new List + { + new object[] { "éééééêêêêê", "éééééêêêêê" }, + new object[] { "aѧѦa", "aѧѦa" }, // U0467, U0466 + }; + } + } + + [Theory] + [MemberData(nameof(JsonEncodedTextStringsCustomAll))] + public static void JsonEncodedTextStringsCustomAllowAll(string message, string expectedMessage) + { + // Allow all unicode values (except forbidden characters which we don't have in test data here) + JavaScriptEncoder encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + + var options = new JsonSerializerOptions(); + options.Encoder = encoder; + + var obj = new TestClassForEncoding(); + obj.MyString = message; + + string baselineJson = JsonSerializer.Serialize(obj); + Assert.DoesNotContain(expectedMessage, baselineJson); + + string json = JsonSerializer.Serialize(obj, options); + Assert.Contains(expectedMessage, json); + + obj = JsonSerializer.Deserialize(json); + Assert.Equal(obj.MyString, message); + } } } diff --git a/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs index e3f5415..13734aa 100644 --- a/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/libraries/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -10,6 +10,8 @@ using System.Globalization; using System.Threading.Tasks; using System.IO.Pipelines; using System.Collections.Generic; +using System.Text.Encodings.Web; +using System.Text.Unicode; namespace System.Text.Json.Tests { @@ -61,6 +63,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writer.BytesCommitted); Assert.Equal(0, writer.BytesPending); Assert.Equal(0, writer.CurrentDepth); + Assert.Equal(null, writer.Options.Encoder); Assert.Equal(formatted, writer.Options.Indented); Assert.Equal(skipValidation, writer.Options.SkipValidation); Assert.Equal(0, stream.Position); @@ -70,6 +73,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writer.BytesCommitted); Assert.Equal(0, writer.BytesPending); Assert.Equal(0, writer.CurrentDepth); + Assert.Equal(null, writer.Options.Encoder); Assert.Equal(formatted, writer.Options.Indented); Assert.Equal(skipValidation, writer.Options.SkipValidation); Assert.Equal(0, output.FormattedCount); @@ -95,6 +99,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writeToStream.BytesCommitted); Assert.Equal(0, writeToStream.BytesPending); Assert.Equal(0, writeToStream.CurrentDepth); + Assert.Equal(null, writeToStream.Options.Encoder); Assert.Equal(formatted, writeToStream.Options.Indented); Assert.Equal(skipValidation, writeToStream.Options.SkipValidation); Assert.True(stream.Position != 0); @@ -114,6 +119,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writeToIBW.BytesCommitted); Assert.Equal(0, writeToIBW.BytesPending); Assert.Equal(0, writeToIBW.CurrentDepth); + Assert.Equal(null, writeToIBW.Options.Encoder); Assert.Equal(formatted, writeToIBW.Options.Indented); Assert.Equal(skipValidation, writeToIBW.Options.SkipValidation); Assert.True(output.FormattedCount != 0); @@ -143,6 +149,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writeToStream.BytesCommitted); Assert.Equal(0, writeToStream.BytesPending); Assert.Equal(0, writeToStream.CurrentDepth); + Assert.Equal(null, writeToStream.Options.Encoder); Assert.Equal(formatted, writeToStream.Options.Indented); Assert.Equal(skipValidation, writeToStream.Options.SkipValidation); Assert.True(stream.Position != 0); @@ -168,6 +175,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writeToIBW.BytesCommitted); Assert.Equal(0, writeToIBW.BytesPending); Assert.Equal(0, writeToIBW.CurrentDepth); + Assert.Equal(null, writeToIBW.Options.Encoder); Assert.Equal(formatted, writeToIBW.Options.Indented); Assert.Equal(skipValidation, writeToIBW.Options.SkipValidation); Assert.True(output.FormattedCount != 0); @@ -204,6 +212,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writeToStream.BytesCommitted); Assert.Equal(0, writeToStream.BytesPending); Assert.Equal(0, writeToStream.CurrentDepth); + Assert.Equal(null, writeToStream.Options.Encoder); Assert.Equal(formatted, writeToStream.Options.Indented); Assert.Equal(skipValidation, writeToStream.Options.SkipValidation); Assert.True(stream.Position != 0); @@ -234,6 +243,7 @@ namespace System.Text.Json.Tests Assert.Equal(0, writeToIBW.BytesCommitted); Assert.Equal(0, writeToIBW.BytesPending); Assert.Equal(0, writeToIBW.CurrentDepth); + Assert.Equal(null, writeToIBW.Options.Encoder); Assert.Equal(formatted, writeToIBW.Options.Indented); Assert.Equal(skipValidation, writeToIBW.Options.SkipValidation); Assert.True(output.FormattedCount != 0); @@ -3087,54 +3097,58 @@ namespace System.Text.Json.Tests } } - [Theory(Skip = "Update test to match JavaScriptEncoder semantics.")] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidUTF8(bool formatted, bool skipValidation) - { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + private const string InvalidUtf8 = "\"\\uFFFD(\""; + private const string ValidUtf8 = "\"\\u00F1\""; - var output = new ArrayBufferWriter(1024); - var jsonUtf8 = new Utf8JsonWriter(output, options); + // todo: verify that we should be using replacement char and not throwing here if skipValidation=true + [Theory] + [InlineData(true, + "{" + InvalidUtf8 + ":" + InvalidUtf8 + "}", + "{" + InvalidUtf8 + ":" + ValidUtf8 + "}", + "{" + ValidUtf8 + ":" + InvalidUtf8 + "}", + "{" + ValidUtf8 + ":" + ValidUtf8 + "}")] + [InlineData(false, + "{" + InvalidUtf8 + ":" + InvalidUtf8 + "}", + "{" + InvalidUtf8 + ":" + ValidUtf8 + "}", + "{" + ValidUtf8 + ":" + InvalidUtf8 + "}", + "{" + ValidUtf8 + ":" + ValidUtf8 + "}")] + public void UTF8ReplacementCharacters(bool skipValidation, string expected0, string expected1, string expected2, string expected3) + { + var options = new JsonWriterOptions { SkipValidation = skipValidation }; var validUtf8 = new byte[2] { 0xc3, 0xb1 }; // 0xF1 var invalidUtf8 = new byte[2] { 0xc3, 0x28 }; - jsonUtf8.WriteStartObject(); - for (int i = 0; i < 6; i++) + string WriteProperty(byte[] propertyName, byte[] value) { - switch (i) - { - case 0: - Assert.Throws(() => jsonUtf8.WriteString(invalidUtf8, invalidUtf8)); - break; - case 1: - Assert.Throws(() => jsonUtf8.WriteString(invalidUtf8, validUtf8)); - break; - case 2: - Assert.Throws(() => jsonUtf8.WriteString(validUtf8, invalidUtf8)); - break; - case 3: - jsonUtf8.WriteString(validUtf8, validUtf8); - break; - case 4: - Assert.Throws(() => jsonUtf8.WritePropertyName(invalidUtf8)); - break; - case 5: - jsonUtf8.WritePropertyName(validUtf8); - Assert.Throws(() => jsonUtf8.WriteStringValue(invalidUtf8)); - jsonUtf8.WriteStringValue(validUtf8); - break; - case 6: - jsonUtf8.WritePropertyName(validUtf8); - jsonUtf8.WriteStringValue(validUtf8); - break; - } + var output = new ArrayBufferWriter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, options); + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteString(propertyName, value); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + string result = Encoding.UTF8.GetString( + output.WrittenSpan +#if netfx + .ToArray() +#endif + ); + output.Clear(); + return result; } - jsonUtf8.WriteEndObject(); - jsonUtf8.Flush(); + + string result; + result = WriteProperty(invalidUtf8, invalidUtf8); + Assert.Equal(expected0, result); + + result = WriteProperty(invalidUtf8, validUtf8); + Assert.Equal(expected1, result); + + result = WriteProperty(validUtf8, invalidUtf8); + Assert.Equal(expected2, result); + + result = WriteProperty(validUtf8, validUtf8); + Assert.Equal(expected3, result); } [Theory] @@ -3187,6 +3201,76 @@ namespace System.Text.Json.Tests jsonUtf8.Flush(); } + public static IEnumerable JsonEncodedTextStringsCustomAll + { + get + { + return new List + { + new object[] { "éééééêêêêê", "{\"Prop\":\"éééééêêêêê\"}" }, + new object[] { "aѧѦa", "{\"Prop\":\"aѧѦa\"}" }, // U0467, U0466 + }; + } + } + + [Theory] + [MemberData(nameof(JsonEncodedTextStringsCustomAll))] + public void CustomEscaper(string value, string expectedStr) + { + const string PropertyName = "Prop"; + + // Allow all unicode values (except forbidden characters which we don't have in test data here) + JavaScriptEncoder encoder = JavaScriptEncoder.Create(UnicodeRanges.All); + + var options = new JsonWriterOptions(); + options.Encoder = encoder; + + for (int i = 0; i < 6; i++) + { + var output = new ArrayBufferWriter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, options); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString(PropertyName, value); + break; + case 1: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(PropertyName), Encoding.UTF8.GetBytes(value)); + break; + case 2: + jsonUtf8.WriteString(JsonEncodedText.Encode(PropertyName), JsonEncodedText.Encode(value, encoder)); + break; + case 3: + jsonUtf8.WritePropertyName(PropertyName); + jsonUtf8.WriteStringValue(value); + break; + case 4: + jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes(PropertyName)); + jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value)); + break; + case 5: + jsonUtf8.WritePropertyName(JsonEncodedText.Encode(PropertyName, encoder)); + jsonUtf8.WriteStringValue(JsonEncodedText.Encode(value, encoder)); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + string result = Encoding.UTF8.GetString( + output.WrittenSpan +#if netfx + .ToArray() +#endif + ); + + Assert.Equal(expectedStr, result); + } + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] @@ -5828,7 +5912,7 @@ namespace System.Text.Json.Tests #endif ); - // Temporary hack until we can use the same escape algorithm throughout. + // Temporary hack until we can use the same escape algorithm on both sides and make sure we want uppercase hex. Assert.Equal(expectedValue.NormalizeToJsonNetFormat(), value.NormalizeToJsonNetFormat()); } @@ -5857,7 +5941,7 @@ namespace System.Text.Json.Tests { var sb = new StringBuilder(json.Length); int i = 0; - while (i < json.Length - 1) + while (i < json.Length) { if (json[i] == '\\') { -- 2.7.4