From aeb2103c06035e07e890ae1f9df1dbaaed4783e2 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 02:12:29 -0800 Subject: [PATCH 01/33] Move JsonReader related files to the Reader directory. --- .../src/System.Text.Json.csproj | 20 ++++++++++--------- .../Json/{ => Reader}/ConsumeNumberResult.cs | 0 .../Json/{ => Reader}/ConsumeTokenResult.cs | 0 .../Json/{ => Reader}/JsonReaderException.cs | 0 .../Json/{ => Reader}/JsonReaderHelper.cs | 0 .../Json/{ => Reader}/JsonReaderOptions.cs | 0 .../Text/Json/{ => Reader}/JsonReaderState.cs | 0 .../Utf8JsonReader.MultiSegment.cs | 0 .../{ => Reader}/Utf8JsonReader.TryGet.cs | 0 .../Text/Json/{ => Reader}/Utf8JsonReader.cs | 0 10 files changed, 11 insertions(+), 9 deletions(-) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/ConsumeNumberResult.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/ConsumeTokenResult.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/JsonReaderException.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/JsonReaderHelper.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/JsonReaderOptions.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/JsonReaderState.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/Utf8JsonReader.MultiSegment.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/Utf8JsonReader.TryGet.cs (100%) rename src/System.Text.Json/src/System/Text/Json/{ => Reader}/Utf8JsonReader.cs (100%) diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index a158dabc85f3..7768706794e4 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -8,19 +8,21 @@ - - - - - - - - - + + + + + + + + + + + diff --git a/src/System.Text.Json/src/System/Text/Json/ConsumeNumberResult.cs b/src/System.Text.Json/src/System/Text/Json/Reader/ConsumeNumberResult.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/ConsumeNumberResult.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/ConsumeNumberResult.cs diff --git a/src/System.Text.Json/src/System/Text/Json/ConsumeTokenResult.cs b/src/System.Text.Json/src/System/Text/Json/Reader/ConsumeTokenResult.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/ConsumeTokenResult.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/ConsumeTokenResult.cs diff --git a/src/System.Text.Json/src/System/Text/Json/JsonReaderException.cs b/src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/JsonReaderException.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderException.cs diff --git a/src/System.Text.Json/src/System/Text/Json/JsonReaderHelper.cs b/src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/JsonReaderHelper.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs diff --git a/src/System.Text.Json/src/System/Text/Json/JsonReaderOptions.cs b/src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderOptions.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/JsonReaderOptions.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderOptions.cs diff --git a/src/System.Text.Json/src/System/Text/Json/JsonReaderState.cs b/src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderState.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/JsonReaderState.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/JsonReaderState.cs diff --git a/src/System.Text.Json/src/System/Text/Json/Utf8JsonReader.MultiSegment.cs b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/Utf8JsonReader.MultiSegment.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs diff --git a/src/System.Text.Json/src/System/Text/Json/Utf8JsonReader.TryGet.cs b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/Utf8JsonReader.TryGet.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs diff --git a/src/System.Text.Json/src/System/Text/Json/Utf8JsonReader.cs b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs similarity index 100% rename from src/System.Text.Json/src/System/Text/Json/Utf8JsonReader.cs rename to src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs From 76a459bfee796d617db62474b9d73a326949125d Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 02:13:26 -0800 Subject: [PATCH 02/33] Update S.T.Json ref to include new JsonWriter APIs. --- src/System.Text.Json/ref/System.Text.Json.cs | 109 +++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index b95392a5e26a..9a083b938292 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -20,11 +20,21 @@ public JsonReaderException(string message, long lineNumber, long bytePositionInL public long LineNumber { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } + public sealed partial class JsonWriterException : System.Exception + { + public JsonWriterException(string message) { } + } public partial struct JsonReaderOptions { private object _dummy; public System.Text.Json.JsonCommentHandling CommentHandling { get { throw null; } set { } } } + public partial struct JsonWriterOptions + { + private object _dummy; + public bool Indented { get { throw null; } set { } } + public bool SkipValidation { get { throw null; } set { } } + } public partial struct JsonReaderState { private object _dummy; @@ -34,6 +44,14 @@ public partial struct JsonReaderState public System.Text.Json.JsonReaderOptions Options { get { throw null; } } public System.SequencePosition Position { get { throw null; } } } + public partial struct JsonWriterState + { + private object _dummy; + public JsonWriterState(System.Text.Json.JsonWriterOptions options = default(System.Text.Json.JsonWriterOptions)) { throw null; } + public long BytesCommitted { get { throw null; } } + public long BytesWritten { get { throw null; } } + public System.Text.Json.JsonWriterOptions Options { get { throw null; } } + } public enum JsonTokenType : byte { Comment = (byte)11, @@ -71,4 +89,95 @@ public ref partial struct Utf8JsonReader public bool TryGetInt64Value(out long value) { throw null; } public bool TryGetSingleValue(out float value) { throw null; } } + public ref partial struct Utf8JsonWriter + { + private object _dummy; + public Utf8JsonWriter(System.Buffers.IBufferWriter bufferWriter, JsonWriterState state = default(System.Text.Json.JsonWriterState)) { throw null; } + public long BytesCommitted { get { throw null; } } + public long BytesWritten { get { throw null; } } + public int CurrentDepth { get { throw null; } } + public System.Text.Json.JsonWriterState CurrentState { get { throw null; } } + public void Flush(bool isFinalBlock = true) { throw null; } + public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { throw null; } + public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { throw null; } + public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { throw null; } + public void WriteBooleanValue(bool value) { throw null; } + public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) { throw null; } + public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) { throw null; } + public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) { throw null; } + public void WriteEndArray() { throw null; } + public void WriteEndObject() { throw null; } + public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } + public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } + public void WriteNull(string propertyName, bool suppressEscaping = false) { throw null; } + public void WriteNullValue() { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) { throw null; } + public void WriteNumberValue(decimal value) { throw null; } + public void WriteNumberValue(double value) { throw null; } + public void WriteNumberValue(int value) { throw null; } + public void WriteNumberValue(long value) { throw null; } + public void WriteNumberValue(float value) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumberValue(uint value) { throw null; } + [System.CLSCompliantAttribute(false)] + public void WriteNumberValue(ulong value) { throw null; } + public void WriteStartArray() { throw null; } + public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } + public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } + public void WriteStartArray(string propertyName, bool suppressEscaping = false) { throw null; } + public void WriteStartObject() { throw null; } + public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } + public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } + public void WriteStartObject(string propertyName, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } + public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { throw null; } + public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) { throw null; } + public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) { throw null; } + public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) { throw null; } + public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } + public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } + public void WriteString(string propertyName, string value, bool suppressEscaping = false) { throw null; } + public void WriteStringValue(DateTime value) { throw null; } + public void WriteStringValue(DateTimeOffset value) { throw null; } + public void WriteStringValue(Guid value) { throw null; } + public void WriteStringValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) { throw null; } + public void WriteStringValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) { throw null; } + public void WriteStringValue(string utf16Text, bool suppressEscaping = false) { throw null; } + } } From f1eae6f6166bf3450527ce5c2094a57f4e6c4d5f Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 02:57:22 -0800 Subject: [PATCH 03/33] Port initial JsonWriter files from corefxlab. --- .../src/System.Text.Json.csproj | 34 + .../src/System/Text/Json/JsonConstants.cs | 20 + .../src/System/Text/Json/ThrowHelper.cs | 165 ++++ .../Text/Json/Writer/JsonWriterException.cs | 14 + .../Json/Writer/JsonWriterHelper.Escaping.cs | 496 +++++++++++ .../Text/Json/Writer/JsonWriterHelper.cs | 836 ++++++++++++++++++ .../Text/Json/Writer/JsonWriterOptions.cs | 43 + .../Text/Json/Writer/JsonWriterState.cs | 37 + .../Text/Json/Writer/SequenceValidity.cs | 55 ++ .../System/Text/Json/Writer/UnicodeScalar.cs | 70 ++ ...Utf8JsonWriter.WriteProperties.DateTime.cs | 242 +++++ ...onWriter.WriteProperties.DateTimeOffset.cs | 242 +++++ .../Utf8JsonWriter.WriteProperties.Decimal.cs | 223 +++++ .../Utf8JsonWriter.WriteProperties.Double.cs | 223 +++++ .../Utf8JsonWriter.WriteProperties.Float.cs | 223 +++++ .../Utf8JsonWriter.WriteProperties.Guid.cs | 242 +++++ .../Utf8JsonWriter.WriteProperties.Helpers.cs | 265 ++++++ .../Utf8JsonWriter.WriteProperties.Literal.cs | 236 +++++ ...JsonWriter.WriteProperties.SignedNumber.cs | 234 +++++ .../Utf8JsonWriter.WriteProperties.String.cs | 720 +++++++++++++++ ...onWriter.WriteProperties.UnsignedNumber.cs | 240 +++++ .../Utf8JsonWriter.WriteValues.Comment.cs | 365 ++++++++ .../Utf8JsonWriter.WriteValues.DateTime.cs | 93 ++ ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 93 ++ .../Utf8JsonWriter.WriteValues.Decimal.cs | 83 ++ .../Utf8JsonWriter.WriteValues.Double.cs | 83 ++ .../Utf8JsonWriter.WriteValues.Float.cs | 83 ++ .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 93 ++ .../Utf8JsonWriter.WriteValues.Helpers.cs | 27 + .../Utf8JsonWriter.WriteValues.Literal.cs | 107 +++ ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 89 ++ .../Utf8JsonWriter.WriteValues.String.cs | 285 ++++++ ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 91 ++ .../System/Text/Json/Writer/Utf8JsonWriter.cs | 760 ++++++++++++++++ 34 files changed, 7112 insertions(+) create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/SequenceValidity.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index 7768706794e4..c699fab93551 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -24,6 +24,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -32,6 +65,7 @@ + diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 859d70611f90..2237e11bf891 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -36,5 +36,25 @@ internal static class JsonConstants // Explicitly skipping ReverseSolidus since that is handled separately public static ReadOnlySpan EscapableChars => new byte[] { Quote, (byte)'n', (byte)'r', (byte)'t', Slash, (byte)'u', (byte)'b', (byte)'f' }; + + public const int RemoveFlagsBitMask = 0x7FFFFFFF; + public const int MaxWriterDepth = 1_000; + public const int MaxTokenSize = 2_000_000_000 / 6; // 357_913_941 bytes + public const int MaxCharacterTokenSize = 2_000_000_000 / 6; // 357_913_941 characters + + public const int MaximumInt64Length = 20; // 19 + sign (i.e. -9223372036854775808) + public const int MaximumUInt64Length = 20; // i.e. 18446744073709551615 + public const int MaximumDoubleLength = 32; // default (i.e. 'G') TODO: Should it be 22? + public const int MaximumSingleLength = 32; // default (i.e. 'G') TODO: Should it be 13? + public const int MaximumDecimalLength = 32; // default (i.e. 'G') TODO: Should it be 31? + public const int MaximumGuidLength = 36; // default (i.e. 'D') 8 + 4 + 4 + 4 + 12 + 4 for the hyphens (e.g. 094ffa0a-0442-494d-b452-04003fa755cc) + public const int MaximumDateTimeLength = 26; // default (i.e. 'G') e.g. 05/25/2017 10:30:15 -08:00 + public const int MaximumDateTimeOffsetLength = 26; // default (i.e. 'G') e.g. 05/25/2017 10:30:15 -08:00 + + // Encoding Helpers + public const char HighSurrogateStart = '\ud800'; + public const char HighSurrogateEnd = '\udbff'; + public const char LowSurrogateStart = '\udc00'; + public const char LowSurrogateEnd = '\udfff'; } } diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index 14e492732b23..6168adf16225 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -20,6 +20,125 @@ private static ArgumentException GetArgumentException(string message) return new ArgumentException(message); } + public static void ThrowArgumentException(string message) + { + throw GetArgumentException(message); + } + + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + GetArgumentException(propertyName, value); + } + + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + GetArgumentException(propertyName, value); + } + + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + GetArgumentException(propertyName, value); + } + + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + GetArgumentException(propertyName, value); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + if (propertyName.Length > JsonConstants.MaxTokenSize) + { + ThrowArgumentException("propertyName too large"); + } + else + { + Debug.Assert(value.Length > JsonConstants.MaxTokenSize); + ThrowArgumentException("value too large"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + if (propertyName.Length > JsonConstants.MaxTokenSize) + { + ThrowArgumentException("propertyName too large"); + } + else + { + Debug.Assert(value.Length > JsonConstants.MaxCharacterTokenSize); + ThrowArgumentException("value too large"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) + { + ThrowArgumentException("propertyName too large"); + } + else + { + Debug.Assert(value.Length > JsonConstants.MaxTokenSize); + ThrowArgumentException("value too large"); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + { + if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) + { + ThrowArgumentException("propertyName too large"); + } + else + { + Debug.Assert(value.Length > JsonConstants.MaxCharacterTokenSize); + ThrowArgumentException("value too large"); + } + } + + public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + { + GetJsonWriterOrArgumentException(propertyName, indent); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + { + if ((indent & JsonConstants.RemoveFlagsBitMask) >= JsonConstants.MaxWriterDepth) + { + ThrowJsonWriterException("Depth too large."); + } + else + { + Debug.Assert(propertyName.Length > JsonConstants.MaxCharacterTokenSize); + ThrowArgumentException("Argument too large."); + } + } + + public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + { + GetJsonWriterOrArgumentException(propertyName, indent); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + { + if ((indent & JsonConstants.RemoveFlagsBitMask) >= JsonConstants.MaxWriterDepth) + { + ThrowJsonWriterException("Depth too large."); + } + else + { + Debug.Assert(propertyName.Length > JsonConstants.MaxCharacterTokenSize); + ThrowArgumentException("Argument too large."); + } + } + public static InvalidOperationException GetInvalidOperationException_ExpectedNumber(JsonTokenType tokenType) { return GetInvalidOperationException("number", tokenType); @@ -41,6 +160,52 @@ private static InvalidOperationException GetInvalidOperationException(string mes return new InvalidOperationException(SR.Format(SR.InvalidCast, tokenType, message)); } + public static void ThrowJsonWriterException(string message) + { + throw GetJsonWriterException(message); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static JsonWriterException GetJsonWriterException(string message) + { + return new JsonWriterException(message); + } + + public static void ThrowJsonWriterException(byte token) + { + throw GetJsonWriterException(token); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static JsonWriterException GetJsonWriterException(byte token) + { + return new JsonWriterException(token.ToString()); + } + + public static void ThrowJsonWriterException(byte token, JsonTokenType tokenType) + { + throw GetJsonWriterException(token, tokenType); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static JsonWriterException GetJsonWriterException(byte token, JsonTokenType tokenType) + { + // TODO: Fix exception message + return new JsonWriterException(token.ToString()); + } + + public static void ThrowJsonWriterException(JsonTokenType tokenType) + { + throw GetJsonWriterException(tokenType); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static JsonWriterException GetJsonWriterException(JsonTokenType tokenType) + { + // TODO: Fix exception message + return new JsonWriterException(""); + } + public static void ThrowJsonReaderException(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte = default, ReadOnlySpan bytes = default) { throw GetJsonReaderException(ref json, resource, nextByte, bytes); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs new file mode 100644 index 000000000000..912508bf5f46 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs @@ -0,0 +1,14 @@ +// 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. + +namespace System.Text.Json +{ + //TODO: Mark as serializable + public sealed class JsonWriterException : Exception + { + public JsonWriterException(string message) : base(message) + { + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs new file mode 100644 index 000000000000..54ca1a6dbbe0 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -0,0 +1,496 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System.Text.Json +{ + internal static partial class JsonWriterHelper + { + // Only allow ASCII characters between ' ' (0x20) and '~' (0x7E), inclusively, + // but exclude characters that need to be escaped as hex: '"', '\'', '&', '+', '<', '>', '`' + // and exclude characters that need to be escaped by adding a backslash: '\n', '\r', '\t', '\\', '/', '\b', '\f' + // + // non-zero = allowed, 0 = disallowed + private static ReadOnlySpan AllowList => new byte[256] { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool NeedsEscaping(byte value) => AllowList[value] == 0; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool NeedsEscaping(char value) => value > 255 || AllowList[value] == 0; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int NeedsEscaping(ReadOnlySpan value) + { + int idx; + for (idx = 0; idx < value.Length; idx++) + { + if (NeedsEscaping(value[idx])) + { + goto Return; + } + } + + idx = -1; // all characters allowed + + Return: + return idx; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int NeedsEscaping(ReadOnlySpan value) + { + int idx; + for (idx = 0; idx < value.Length; idx++) + { + if (NeedsEscaping(value[idx])) + { + goto Return; + } + } + + idx = -1; // all characters allowed + + Return: + return idx; + } + + // TODO: Remmove this + [MethodImpl(MethodImplOptions.NoInlining)] + public static OperationStatus EscapeString(ReadOnlySpan value, Span destination, out int consumed, out int bytesWritten) + { + throw new NotImplementedException(); + } + + public static void EscapeString(ref ReadOnlySpan value, ref Span destination, int indexOfFirstByteToEscape, out int written) + { + Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); + + value.Slice(0, indexOfFirstByteToEscape).CopyTo(destination); + written = indexOfFirstByteToEscape; + int consumed = indexOfFirstByteToEscape; + + while (consumed < value.Length) + { + byte val = value[consumed]; + if (NeedsEscaping(val)) + { + consumed += EscapeNextBytes(value.Slice(consumed), ref destination, ref written); + } + else + { + destination[written] = val; + written++; + consumed++; + } + } + } + + private static int EscapeNextBytes(ReadOnlySpan value, ref Span destination, ref int written) + { + SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out UnicodeScalar unicodeScalar); + if (status != SequenceValidity.WellFormed) + ThrowHelper.ThrowJsonWriterException("Invalid UTF-8 string."); + + destination[written++] = (byte)'\\'; + int scalar = unicodeScalar.Value; + switch (scalar) + { + case '\n': + destination[written++] = (byte)'n'; + break; + case '\r': + destination[written++] = (byte)'r'; + break; + case '\t': + destination[written++] = (byte)'t'; + break; + case '\\': + destination[written++] = (byte)'\\'; + break; + case '/': + destination[written++] = (byte)'/'; + break; + case '\b': + destination[written++] = (byte)'b'; + break; + case '\f': + destination[written++] = (byte)'f'; + break; + default: + destination[written++] = (byte)'u'; + if (scalar < 0x10000) + { + WriteHex(scalar, ref destination, ref written); + } + else + { + int quotient = DivMod(scalar - 0x10000, 0x400, out int remainder); + int firstChar = quotient + 0xD800; + int nextChar = remainder + 0xDC00; + WriteHex(firstChar, ref destination, ref written); + destination[written++] = (byte)'\\'; + destination[written++] = (byte)'u'; + WriteHex(nextChar, ref destination, ref written); + } + break; + } + return numBytesConsumed; + } + + private static bool IsAsciiValue(byte value) => value < 0x80; + + /// + /// Returns iff is a UTF-8 continuation byte. + /// A UTF-8 continuation byte is a byte whose value is in the range 0x80-0xBF, inclusive. + /// + private static bool IsUtf8ContinuationByte(byte value) => (value & 0xC0) == 0x80; + + /// + /// Returns iff is between + /// and , inclusive. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsInRangeInclusive(byte value, byte lowerBound, byte upperBound) + => ((byte)(value - lowerBound) <= (byte)(upperBound - lowerBound)); + + /// + /// Returns iff is between + /// and , inclusive. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBound) + => (value - lowerBound) <= (upperBound - lowerBound); + + /// + /// Returns iff the low word of is a UTF-16 surrogate. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsLowWordSurrogate(uint @char) + => (@char & 0xF800U) == 0xD800U; + + public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out int numBytesConsumed, out UnicodeScalar scalarValue) + { + // This method is implemented to match the behavior of System.Text.Encoding.UTF8 in terms of + // how many bytes it consumes when reporting invalid sequences. The behavior is as follows: + // + // - Some bytes are *always* invalid (ranges [ C0..C1 ] and [ F5..FF ]), and when these + // are encountered it's an invalid sequence of length 1. + // + // - Multi-byte sequences which are overlong are reported as an invalid sequence of length 2, + // since per the Unicode Standard Table 3-7 it's always possible to tell these by the second byte. + // Exception: Sequences which begin with [ C0..C1 ] are covered by the above case, thus length 1. + // + // - Multi-byte sequences which are improperly terminated (no continuation byte when one is + // expected) are reported as invalid sequences up to and including the last seen continuation byte. + + scalarValue = UnicodeScalar.s_replacementChar; + + if (data.IsEmpty) + { + // No data to peek at + numBytesConsumed = 0; + return SequenceValidity.Empty; + } + + byte firstByte = data[0]; + + if (IsAsciiValue(firstByte)) + { + // ASCII byte = well-formed one-byte sequence. + scalarValue = UnicodeScalar.CreateWithoutValidation(firstByte); + numBytesConsumed = 1; + return SequenceValidity.WellFormed; + } + + if (!IsInRangeInclusive(firstByte, (byte)0xC2U, (byte)0xF4U)) + { + // Standalone continuation byte or "always invalid" byte = ill-formed one-byte sequence. + goto InvalidOneByteSequence; + } + + // At this point, we know we're working with a multi-byte sequence, + // and we know that at least the first byte is potentially valid. + + if (data.Length < 2) + { + // One byte of an incomplete multi-byte sequence. + goto OneByteOfIncompleteMultiByteSequence; + } + + byte secondByte = data[1]; + + if (!IsUtf8ContinuationByte(secondByte)) + { + // One byte of an improperly terminated multi-byte sequence. + goto InvalidOneByteSequence; + } + + if (firstByte < (byte)0xE0U) + { + // Well-formed two-byte sequence. + scalarValue = UnicodeScalar.CreateWithoutValidation((((uint)firstByte & 0x1FU) << 6) | ((uint)secondByte & 0x3FU)); + numBytesConsumed = 2; + return SequenceValidity.WellFormed; + } + + if (firstByte < (byte)0xF0U) + { + // Start of a three-byte sequence. + // Need to check for overlong or surrogate sequences. + + uint scalar = (((uint)firstByte & 0x0FU) << 12) | (((uint)secondByte & 0x3FU) << 6); + if (scalar < 0x800U || IsLowWordSurrogate(scalar)) + { goto OverlongOutOfRangeOrSurrogateSequence; } + + // At this point, we have a valid two-byte start of a three-byte sequence. + + if (data.Length < 3) + { + // Two bytes of an incomplete three-byte sequence. + goto TwoBytesOfIncompleteMultiByteSequence; + } + else + { + byte thirdByte = data[2]; + if (IsUtf8ContinuationByte(thirdByte)) + { + // Well-formed three-byte sequence. + scalar |= (uint)thirdByte & 0x3FU; + scalarValue = UnicodeScalar.CreateWithoutValidation(scalar); + numBytesConsumed = 3; + return SequenceValidity.WellFormed; + } + else + { + // Two bytes of improperly terminated multi-byte sequence. + goto InvalidTwoByteSequence; + } + } + } + + { + // Start of four-byte sequence. + // Need to check for overlong or out-of-range sequences. + + uint scalar = (((uint)firstByte & 0x07U) << 18) | (((uint)secondByte & 0x3FU) << 12); + if (!IsInRangeInclusive(scalar, 0x10000U, 0x10FFFFU)) + { goto OverlongOutOfRangeOrSurrogateSequence; } + + // At this point, we have a valid two-byte start of a four-byte sequence. + + if (data.Length < 3) + { + // Two bytes of an incomplete four-byte sequence. + goto TwoBytesOfIncompleteMultiByteSequence; + } + else + { + byte thirdByte = data[2]; + if (IsUtf8ContinuationByte(thirdByte)) + { + // Valid three-byte start of a four-byte sequence. + + if (data.Length < 4) + { + // Three bytes of an incomplete four-byte sequence. + goto ThreeBytesOfIncompleteMultiByteSequence; + } + else + { + byte fourthByte = data[3]; + if (IsUtf8ContinuationByte(fourthByte)) + { + // Well-formed four-byte sequence. + scalar |= (((uint)thirdByte & 0x3FU) << 6) | ((uint)fourthByte & 0x3FU); + scalarValue = UnicodeScalar.CreateWithoutValidation(scalar); + numBytesConsumed = 4; + return SequenceValidity.WellFormed; + } + else + { + // Three bytes of an improperly terminated multi-byte sequence. + goto InvalidThreeByteSequence; + } + } + } + else + { + // Two bytes of improperly terminated multi-byte sequence. + goto InvalidTwoByteSequence; + } + } + } + + // Everything below here is error handling. + + InvalidOneByteSequence: + numBytesConsumed = 1; + return SequenceValidity.Invalid; + + InvalidTwoByteSequence: + OverlongOutOfRangeOrSurrogateSequence: + numBytesConsumed = 2; + return SequenceValidity.Invalid; + + InvalidThreeByteSequence: + numBytesConsumed = 3; + return SequenceValidity.Invalid; + + OneByteOfIncompleteMultiByteSequence: + numBytesConsumed = 1; + return SequenceValidity.Incomplete; + + TwoBytesOfIncompleteMultiByteSequence: + numBytesConsumed = 2; + return SequenceValidity.Incomplete; + + ThreeBytesOfIncompleteMultiByteSequence: + numBytesConsumed = 3; + return SequenceValidity.Incomplete; + } + + /// + /// We don't have access to Math.DivRem, so this is a copy of the implementation. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int DivMod(int numerator, int denominator, out int modulo) + { + int div = numerator / denominator; + modulo = numerator - (div * denominator); + return div; + } + + public static void EscapeString(ref ReadOnlySpan value, ref Span destination, int indexOfFirstByteToEscape, out int written) + { + Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); + + value.Slice(0, indexOfFirstByteToEscape).CopyTo(destination); + written = indexOfFirstByteToEscape; + int consumed = indexOfFirstByteToEscape; + + while (consumed < value.Length) + { + char val = value[consumed]; + if (NeedsEscaping(val)) + { + EscapeNextChars(ref value, val, ref destination, ref consumed, ref written); + } + else + { + destination[written++] = val; + } + consumed++; + } + } + + private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, ref Span destination, ref int consumed, ref int written) + { + int nextChar = -1; + if (InRange(firstChar, 0xD800, 0xDFFF)) + { + consumed++; + if (value.Length <= consumed || firstChar >= 0xDC00) + { + ThrowHelper.ThrowJsonWriterException("Invalid UTF-16 string ending in an invalid surrogate pair."); + } + + nextChar = value[consumed]; + if (!InRange(nextChar, 0xDC00, 0xDFFF)) + { + ThrowHelper.ThrowJsonWriterException("Invalid UTF-16 string ending in an invalid surrogate pair."); + } + } + + destination[written++] = '\\'; + switch (firstChar) + { + case '\n': + destination[written++] = 'n'; + break; + case '\r': + destination[written++] = 'r'; + break; + case '\t': + destination[written++] = 't'; + break; + case '\\': + destination[written++] = '\\'; + break; + case '/': + destination[written++] = '/'; + break; + case '\b': + destination[written++] = 'b'; + break; + case '\f': + destination[written++] = 'f'; + break; + default: + destination[written++] = 'u'; + WriteHex(firstChar, ref destination, ref written); + if (nextChar != -1) + { + destination[written++] = '\\'; + destination[written++] = 'u'; + WriteHex(nextChar, ref destination, ref written); + } + break; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool InRange(int ch, int start, int end) + { + return (uint)(ch - start) <= (uint)(end - start); + } + + private static void WriteHex(int value, ref Span destination, ref int written) + { + destination[written++] = Int32LsbToHexDigit(value >> 12); + destination[written++] = Int32LsbToHexDigit((int)((value >> 8) & 0xFU)); + destination[written++] = Int32LsbToHexDigit((int)((value >> 4) & 0xFU)); + destination[written++] = Int32LsbToHexDigit((int)(value & 0xFU)); + } + + private static void WriteHex(int value, ref Span destination, ref int written) + { + destination[written++] = (char)Int32LsbToHexDigit(value >> 12); + destination[written++] = (char)Int32LsbToHexDigit((int)((value >> 8) & 0xFU)); + destination[written++] = (char)Int32LsbToHexDigit((int)((value >> 4) & 0xFU)); + destination[written++] = (char)Int32LsbToHexDigit((int)(value & 0xFU)); + } + + /// + /// Converts a number 0 - 15 to its associated hex character '0' - 'f' as byte. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static byte Int32LsbToHexDigit(int value) + { + Debug.Assert(value < 16); + return (byte)((value < 10) ? ('0' + value) : ('a' + (value - 10))); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs new file mode 100644 index 000000000000..87f775efa46f --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -0,0 +1,836 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Internal.Runtime.CompilerServices; + +namespace System.Text.Json +{ + internal static partial class JsonWriterHelper + { + public static readonly byte[] s_newLineUtf8 = Encoding.UTF8.GetBytes(Environment.NewLine); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int WriteIndentation(Span buffer) + { + Debug.Assert(buffer.Length % 2 == 0); + + if (buffer.Length < 8) + { + int i = 0; + while (i < buffer.Length) + { + buffer[i++] = JsonConstants.Space; + buffer[i++] = JsonConstants.Space; + } + } + else + { + buffer.Fill(JsonConstants.Space); + } + return buffer.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryWriteIndentation(Span buffer, int indent, out int bytesWritten) + { + Debug.Assert(indent % 2 == 0); + + if (buffer.Length >= indent) + { + if (indent < 8) + { + int i = 0; + while (i < indent) + { + buffer[i++] = JsonConstants.Space; + buffer[i++] = JsonConstants.Space; + } + } + else + { + buffer.Slice(0, indent).Fill(JsonConstants.Space); + } + bytesWritten = indent; + return true; + } + else + { + int i = 0; + while (i < buffer.Length - 1) + { + buffer[i++] = JsonConstants.Space; + buffer[i++] = JsonConstants.Space; + } + bytesWritten = i; + return false; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateProperty(ref ReadOnlySpan propertyName) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxTokenSize) + ThrowHelper.ThrowArgumentException("Argument too large."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateValue(ref ReadOnlySpan value) + { + // TODO: Use throw helper with proper error messages + if (value.Length > JsonConstants.MaxTokenSize) + ThrowHelper.ThrowArgumentException("Argument too large."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateProperty(ref ReadOnlySpan propertyName) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) + ThrowHelper.ThrowArgumentException("Argument too large."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateValue(ref ReadOnlySpan value) + { + // TODO: Use throw helper with proper error messages + if (value.Length > JsonConstants.MaxCharacterTokenSize) + ThrowHelper.ThrowArgumentException("Argument too large."); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxTokenSize) + ThrowHelper.ThrowArgumentException(propertyName, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) + ThrowHelper.ThrowArgumentException(propertyName, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxTokenSize) + ThrowHelper.ThrowArgumentException(propertyName, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) + ThrowHelper.ThrowArgumentException(propertyName, value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteDigitsUInt64D(ulong value, Span buffer) + { + // We can mutate the 'value' parameter since it's a copy-by-value local. + // It'll be used to represent the value left over after each division by 10. + + Debug.Assert(CountDigits(value) == buffer.Length); + + for (int i = buffer.Length - 1; i >= 1; i--) + { + ulong temp = '0' + value; + value /= 10; + buffer[i] = (byte)(temp - (value * 10)); + } + + Debug.Assert(value < 10); + buffer[0] = (byte)('0' + value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteDigitsUInt64D(ulong value, Span buffer) + { + // We can mutate the 'value' parameter since it's a copy-by-value local. + // It'll be used to represent the value left over after each division by 10. + + Debug.Assert(CountDigits(value) == buffer.Length); + + for (int i = buffer.Length - 1; i >= 1; i--) + { + ulong temp = '0' + value; + value /= 10; + buffer[i] = (char)(temp - (value * 10)); + } + + Debug.Assert(value < 10); + buffer[0] = (char)('0' + value); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int CountDigits(ulong value) + { + int digits = 1; + uint part; + if (value >= 10000000) + { + if (value >= 100000000000000) + { + part = (uint)(value / 100000000000000); + digits += 14; + } + else + { + part = (uint)(value / 10000000); + digits += 7; + } + } + else + { + part = (uint)value; + } + + if (part < 10) + { + // no-op + } + else if (part < 100) + { + digits += 1; + } + else if (part < 1000) + { + digits += 2; + } + else if (part < 10000) + { + digits += 3; + } + else if (part < 100000) + { + digits += 4; + } + else if (part < 1000000) + { + digits += 5; + } + else + { + Debug.Assert(part < 10000000); + digits += 6; + } + + return digits; + } + + /// + /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes. + /// + /// This method will consume as many of the input bytes as possible. + /// + /// On successful exit, the entire input was consumed and encoded successfully. In this case, will be + /// equal to the length of the and will equal the total number of bytes written to + /// the . + /// + /// A span containing a sequence of UTF-16 bytes. + /// A span to write the UTF-8 bytes into. + /// On exit, contains the number of bytes that were consumed from the . + /// On exit, contains the number of bytes written to + /// A value representing the state of the conversion. + public unsafe static OperationStatus ToUtf8(ReadOnlySpan source, Span destination, out int bytesConsumed, out int bytesWritten) + { + // + // + // KEEP THIS IMPLEMENTATION IN SYNC WITH https://github.com/dotnet/corert/blob/master/src/System.Private.CoreLib/src/System/Text/UTF8Encoding.cs + // + // + fixed (byte* chars = &MemoryMarshal.GetReference(source)) + fixed (byte* bytes = &MemoryMarshal.GetReference(destination)) + { + char* pSrc = (char*)chars; + byte* pTarget = bytes; + + char* pEnd = (char*)(chars + source.Length); + byte* pAllocatedBufferEnd = pTarget + destination.Length; + + // assume that JIT will enregister pSrc, pTarget and ch + + // Entering the fast encoding loop incurs some overhead that does not get amortized for small + // number of characters, and the slow encoding loop typically ends up running for the last few + // characters anyway since the fast encoding loop needs 5 characters on input at least. + // Thus don't use the fast decoding loop at all if we don't have enough characters. The threashold + // was choosen based on performance testing. + // Note that if we don't have enough bytes, pStop will prevent us from entering the fast loop. + while (pEnd - pSrc > 13) + { + // we need at least 1 byte per character, but Convert might allow us to convert + // only part of the input, so try as much as we can. Reduce charCount if necessary + int available = Math.Min(PtrDiff(pEnd, pSrc), PtrDiff(pAllocatedBufferEnd, pTarget)); + + // FASTLOOP: + // - optimistic range checks + // - fallbacks to the slow loop for all special cases, exception throwing, etc. + + // To compute the upper bound, assume that all characters are ASCII characters at this point, + // the boundary will be decreased for every non-ASCII character we encounter + // Also, we need 5 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates + // If there aren't enough bytes for the output, then pStop will be <= pSrc and will bypass the loop. + char* pStop = pSrc + available - 5; + if (pSrc >= pStop) + break; + + do + { + int ch = *pSrc; + pSrc++; + + if (ch > 0x7F) + { + goto LongCode; + } + *pTarget = (byte)ch; + pTarget++; + + // get pSrc aligned + if ((unchecked((int)pSrc) & 0x2) != 0) + { + ch = *pSrc; + pSrc++; + if (ch > 0x7F) + { + goto LongCode; + } + *pTarget = (byte)ch; + pTarget++; + } + + // Run 4 characters at a time! + while (pSrc < pStop) + { + ch = *(int*)pSrc; + int chc = *(int*)(pSrc + 2); + if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) + { + goto LongCodeWithMask; + } + + // Unfortunately, this is endianess sensitive +#if BIGENDIAN + *pTarget = (byte)(ch >> 16); + *(pTarget + 1) = (byte)ch; + pSrc += 4; + *(pTarget + 2) = (byte)(chc >> 16); + *(pTarget + 3) = (byte)chc; + pTarget += 4; +#else // BIGENDIAN + *pTarget = (byte)ch; + *(pTarget + 1) = (byte)(ch >> 16); + pSrc += 4; + *(pTarget + 2) = (byte)chc; + *(pTarget + 3) = (byte)(chc >> 16); + pTarget += 4; +#endif // BIGENDIAN + } + continue; + + LongCodeWithMask: +#if BIGENDIAN + // be careful about the sign extension + ch = (int)(((uint)ch) >> 16); +#else // BIGENDIAN + ch = (char)ch; +#endif // BIGENDIAN + pSrc++; + + if (ch > 0x7F) + { + goto LongCode; + } + *pTarget = (byte)ch; + pTarget++; + continue; + + LongCode: + // use separate helper variables for slow and fast loop so that the jit optimizations + // won't get confused about the variable lifetimes + int chd; + if (ch <= 0x7FF) + { + // 2 byte encoding + chd = unchecked((sbyte)0xC0) | (ch >> 6); + } + else + { + // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) + if (!InRange(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + // 3 byte encoding + chd = unchecked((sbyte)0xE0) | (ch >> 12); + } + else + { + // 4 byte encoding - high surrogate + low surrogate + // if (!IsHighSurrogate(ch)) + if (ch > JsonConstants.HighSurrogateEnd) + { + // low without high -> bad + goto InvalidData; + } + + chd = *pSrc; + + // if (!IsLowSurrogate(chd)) { + if (!InRange(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + // high not followed by low -> bad + goto InvalidData; + } + + pSrc++; + + ch = chd + (ch << 10) + + (0x10000 + - JsonConstants.LowSurrogateStart + - (JsonConstants.HighSurrogateStart << 10)); + + *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18)); + // pStop - this byte is compensated by the second surrogate character + // 2 input chars require 4 output bytes. 2 have been anticipated already + // and 2 more will be accounted for by the 2 pStop-- calls below. + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F; + } + *pTarget = (byte)chd; + pStop--; // 3 byte sequence for 1 char, so need pStop-- and the one below too. + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F; + } + *pTarget = (byte)chd; + pStop--; // 2 byte sequence for 1 char so need pStop--. + + *(pTarget + 1) = (byte)(unchecked((sbyte)0x80) | ch & 0x3F); + // pStop - this byte is already included + + pTarget += 2; + } + while (pSrc < pStop); + + Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd"); + } + + while (pSrc < pEnd) + { + // SLOWLOOP: does all range checks, handles all special cases, but it is slow + + // read next char. The JIT optimization seems to be getting confused when + // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead + int ch = *pSrc; + pSrc++; + + if (ch <= 0x7F) + { + if (pAllocatedBufferEnd - pTarget <= 0) + goto DestinationFull; + + *pTarget = (byte)ch; + pTarget++; + continue; + } + + int chd; + if (ch <= 0x7FF) + { + if (pAllocatedBufferEnd - pTarget <= 1) + goto DestinationFull; + + // 2 byte encoding + chd = unchecked((sbyte)0xC0) | (ch >> 6); + } + else + { + // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) + if (!InRange(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + if (pAllocatedBufferEnd - pTarget <= 2) + goto DestinationFull; + + // 3 byte encoding + chd = unchecked((sbyte)0xE0) | (ch >> 12); + } + else + { + if (pAllocatedBufferEnd - pTarget <= 3) + goto DestinationFull; + + // 4 byte encoding - high surrogate + low surrogate + // if (!IsHighSurrogate(ch)) + if (ch > JsonConstants.HighSurrogateEnd) + { + // low without high -> bad + goto InvalidData; + } + + if (pSrc >= pEnd) + goto NeedMoreData; + + chd = *pSrc; + + // if (!IsLowSurrogate(chd)) { + if (!InRange(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + // high not followed by low -> bad + goto InvalidData; + } + + pSrc++; + + ch = chd + (ch << 10) + + (0x10000 + - JsonConstants.LowSurrogateStart + - (JsonConstants.HighSurrogateStart << 10)); + + *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18)); + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F; + } + *pTarget = (byte)chd; + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F; + } + + *pTarget = (byte)chd; + *(pTarget + 1) = (byte)(unchecked((sbyte)0x80) | ch & 0x3F); + + pTarget += 2; + } + + bytesConsumed = (int)((byte*)pSrc - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.Done; + + InvalidData: + bytesConsumed = (int)((byte*)(pSrc - 1) - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.InvalidData; + + DestinationFull: + bytesConsumed = (int)((byte*)(pSrc - 1) - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.DestinationTooSmall; + + NeedMoreData: + bytesConsumed = (int)((byte*)(pSrc - 1) - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.NeedMoreData; + } + } + + // Borrowed from https://github.com/dotnet/corefx/blob/master/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.Default.cs#L16 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryFormatInt64Default(long value, Span destination, out int bytesWritten) + { + if ((ulong)value < 10) + { + return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); + } + + return TryFormatInt64MultipleDigits(value, destination, out bytesWritten); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool TryFormatUInt64Default(ulong value, Span destination, out int bytesWritten) + { + if (value < 10) + { + return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); + } + + return TryFormatUInt64MultipleDigits(value, destination, out bytesWritten); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryFormatUInt32SingleDigit(uint value, Span destination, out int bytesWritten) + { + if (destination.Length == 0) + { + bytesWritten = 0; + return false; + } + destination[0] = (byte)('0' + value); + bytesWritten = 1; + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryFormatInt64MultipleDigits(long value, Span destination, out int bytesWritten) + { + if (value < 0) + { + value = -value; + int digitCount = CountDigits((ulong)value); + // WriteDigits does not do bounds checks + if (digitCount >= destination.Length) + { + bytesWritten = 0; + return false; + } + destination[0] = (byte)'-'; + bytesWritten = digitCount + 1; + WriteDigits((ulong)value, destination.Slice(1, digitCount)); + return true; + } + else + { + return TryFormatUInt64MultipleDigits((ulong)value, destination, out bytesWritten); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool TryFormatUInt64MultipleDigits(ulong value, Span destination, out int bytesWritten) + { + int digitCount = CountDigits(value); + // WriteDigits does not do bounds checks + if (digitCount > destination.Length) + { + bytesWritten = 0; + return false; + } + bytesWritten = digitCount; + WriteDigits(value, destination.Slice(0, digitCount)); + return true; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void WriteDigits(ulong value, Span buffer) + { + // We can mutate the 'value' parameter since it's a copy-by-value local. + // It'll be used to represent the value left over after each division by 10. + + for (int i = buffer.Length - 1; i >= 1; i--) + { + ulong temp = '0' + value; + value /= 10; + buffer[i] = (byte)(temp - (value * 10)); + } + + Debug.Assert(value < 10); + buffer[0] = (byte)('0' + value); + } + + // https://tools.ietf.org/html/rfc8259 + // Escape '"', '\', '/', and all control characters (i.e. 0 to 31) + // IndexOfAny(34, 47, 92, < 32) + // Borrowed and modified from SpanHelpers.Byte: + // https://github.com/dotnet/corefx/blob/fc169cddedb6820aaabbdb8b7bece2a3df0fd1a5/src/Common/src/CoreLib/System/SpanHelpers.Byte.cs#L473-L604 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int IndexOfAnyEscape(this ReadOnlySpan span) + { + return IndexOfAny( + ref MemoryMarshal.GetReference(span), + JsonConstants.Quote, + JsonConstants.Slash, + JsonConstants.BackSlash, + JsonConstants.Space, + span.Length); + } + + private static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, byte lessThan, int length) + { + Debug.Assert(length >= 0); + + uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions + uint uValue1 = value1; // Use uint for comparisons to avoid unnecessary 8->32 extensions + uint uValue2 = value2; // Use uint for comparisons to avoid unnecessary 8->32 extensions + uint uLessThan = lessThan; // Use uint for comparisons to avoid unnecessary 8->32 extensions + IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations + IntPtr nLength = (IntPtr)length; + + if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) + { + int unaligned = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); + nLength = (IntPtr)((Vector.Count - unaligned) & (Vector.Count - 1)); + } + SequentialScan: + uint lookUp; + while ((byte*)nLength >= (byte*)8) + { + nLength -= 8; + + lookUp = Unsafe.AddByteOffset(ref searchSpace, index); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 1); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found1; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 2); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found2; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 3); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found3; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 4); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found4; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 5); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found5; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 6); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found6; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 7); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found7; + + index += 8; + } + + if ((byte*)nLength >= (byte*)4) + { + nLength -= 4; + + lookUp = Unsafe.AddByteOffset(ref searchSpace, index); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 1); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found1; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 2); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found2; + lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 3); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found3; + + index += 4; + } + + while ((byte*)nLength > (byte*)0) + { + nLength -= 1; + + lookUp = Unsafe.AddByteOffset(ref searchSpace, index); + if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) + goto Found; + + index += 1; + } + + if (Vector.IsHardwareAccelerated && ((int)(byte*)index < length)) + { + nLength = (IntPtr)((length - (int)(byte*)index) & ~(Vector.Count - 1)); + + // Get comparison Vector + Vector values0 = new Vector(value0); + Vector values1 = new Vector(value1); + Vector values2 = new Vector(value2); + Vector valuesLessThan = new Vector(lessThan); + + while ((byte*)nLength > (byte*)index) + { + Vector vData = Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, index)); + + var vMatches = Vector.BitwiseOr( + Vector.BitwiseOr( + Vector.BitwiseOr( + Vector.Equals(vData, values0), + Vector.Equals(vData, values1)), + Vector.Equals(vData, values2)), + Vector.LessThan(vData, valuesLessThan)); + + if (Vector.Zero.Equals(vMatches)) + { + index += Vector.Count; + continue; + } + // Find offset of first match + return (int)(byte*)index + LocateFirstFoundByte(vMatches); + } + + if ((int)(byte*)index < length) + { + nLength = (IntPtr)(length - (int)(byte*)index); + goto SequentialScan; + } + } + return -1; + Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549 + return (int)(byte*)index; + Found1: + return (int)(byte*)(index + 1); + Found2: + return (int)(byte*)(index + 2); + Found3: + return (int)(byte*)(index + 3); + Found4: + return (int)(byte*)(index + 4); + Found5: + return (int)(byte*)(index + 5); + Found6: + return (int)(byte*)(index + 6); + Found7: + return (int)(byte*)(index + 7); + } + + // Vector sub-search adapted from https://github.com/aspnet/KestrelHttpServer/pull/1138 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int LocateFirstFoundByte(Vector match) + { + var vector64 = Vector.AsVectorUInt64(match); + ulong candidate = 0; + int i = 0; + // Pattern unrolled by jit https://github.com/dotnet/coreclr/pull/8001 + for (; i < Vector.Count; i++) + { + candidate = vector64[i]; + if (candidate != 0) + { + break; + } + } + + // Single LEA instruction with jitted const (using function result) + return i * 8 + LocateFirstFoundByte(candidate); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int LocateFirstFoundByte(ulong match) + { + // Flag least significant power of two bit + var powerOfTwoFlag = match ^ (match - 1); + // Shift all powers of two into the high byte and extract + return (int)((powerOfTwoFlag * XorPowerOfTwoToHighByte) >> 57); + } + + private const ulong XorPowerOfTwoToHighByte = (0x07ul | + 0x06ul << 8 | + 0x05ul << 16 | + 0x04ul << 24 | + 0x03ul << 32 | + 0x02ul << 40 | + 0x01ul << 48) + 1; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private unsafe static int PtrDiff(char* a, char* b) + { + return (int)(((uint)((byte*)a - (byte*)b)) >> 1); + } + + // byte* flavor just for parity + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private unsafe static int PtrDiff(byte* a, byte* b) + { + return (int)(a - b); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs new file mode 100644 index 000000000000..32a664f0b12f --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -0,0 +1,43 @@ +// 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. + +namespace System.Text.Json +{ + public struct JsonWriterOptions + { + private int _optionsMask; + + public bool Indented + { + get + { + return (_optionsMask & 1) != 0; + } + set + { + if (value) + _optionsMask |= 1; + else + _optionsMask &= ~1; + } + } + + public bool SkipValidation + { + get + { + return (_optionsMask & 2) != 0; + } + set + { + if (value) + _optionsMask |= 2; + else + _optionsMask &= ~2; + } + } + + internal bool SlowPath => _optionsMask != 2; // Equivalent to: Indented || !SkipValidation; + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs new file mode 100644 index 000000000000..dd68d8d3f7a9 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs @@ -0,0 +1,37 @@ +// 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. + +namespace System.Text.Json +{ + public struct JsonWriterState + { + internal long _bytesWritten; + internal long _bytesCommitted; + internal bool _inObject; + internal bool _isNotPrimitive; + internal JsonTokenType _tokenType; + internal JsonWriterOptions _writerOptions; + internal BitStack _bitStack; + + public long BytesWritten => _bytesWritten; + + public long BytesCommitted => _bytesCommitted; + + public JsonWriterState(JsonWriterOptions options = default) + { + _bytesWritten = default; + _bytesCommitted = default; + _inObject = default; + _isNotPrimitive = default; + _tokenType = default; + _writerOptions = 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. + _bitStack = default; + } + + public JsonWriterOptions Options => _writerOptions; + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/SequenceValidity.cs b/src/System.Text.Json/src/System/Text/Json/Writer/SequenceValidity.cs new file mode 100644 index 000000000000..d96c482e7358 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/SequenceValidity.cs @@ -0,0 +1,55 @@ +// 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. + +namespace System.Buffers.Text +{ + /// + /// Represents the validity of a UTF code unit sequence. + /// + internal enum SequenceValidity + { + /// + /// The sequence is empty. + /// + Empty = 0, + + /// + /// The sequence is well-formed and unambiguously represents a proper Unicode scalar value. + /// + /// + /// [ 20 ] (U+0020 SPACE) is a well-formed UTF-8 sequence. + /// [ C3 A9 ] (U+00E9 LATIN SMALL LETTER E WITH ACUTE) is a well-formed UTF-8 sequence. + /// [ F0 9F 98 80 ] (U+1F600 GRINNING FACE) is a well-formed UTF-8 sequence. + /// [ D83D DE00 ] (U+1F600 GRINNING FACE) is a well-formed UTF-16 sequence. + /// + WellFormed = 1, + + /// + /// The sequence is not well-formed on its own, but it could appear as a prefix + /// of a longer well-formed sequence. More code units are needed to make a proper + /// determination as to whether this sequence is well-formed. Incomplete sequences + /// can only appear at the end of a string. + /// + /// + /// [ C2 ] is an incomplete UTF-8 sequence if it is followed by nothing. + /// [ F0 9F ] is an incomplete UTF-8 sequence if it is followed by nothing. + /// [ D83D ] is an incomplete UTF-16 sequence if it is followed by nothing. + /// + Incomplete = 2, + + /// + /// The sequence is never well-formed anywhere, or this sequence can never appear as a prefix + /// of a longer well-formed sequence, or the sequence was improperly terminated by the code + /// unit which appeared immediately after this sequence. + /// + /// + /// [ 80 ] is an invalid UTF-8 sequence (code unit cannot appear at start of sequence). + /// [ FE ] is an invalid UTF-8 sequence (sequence is never well-formed anywhere in UTF-8 string). + /// [ C2 ] is an invalid UTF-8 sequence if it is followed by [ 20 ] (sequence improperly terminated). + /// [ ED A0 ] is an invalid UTF-8 sequence (sequence is never well-formed anywhere in UTF-8 string). + /// [ DE00 ] is an invalid UTF-16 sequence (code unit cannot appear at start of sequence). + /// + Invalid = 3 + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs b/src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs new file mode 100644 index 000000000000..fc8ba9189d3d --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs @@ -0,0 +1,70 @@ +// 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. + +using System.Runtime.CompilerServices; + +namespace System.Buffers.Text +{ + /// + /// Represents a 24-bit Unicode scalar value. + /// A scalar value is any value in the range [U+0000..U+D7FF] or [U+E000..U+10FFFF]. + /// + internal struct UnicodeScalar : IComparable, IEquatable + { + /// + /// The Unicode Replacement Character U+FFFD. + /// + public static readonly UnicodeScalar s_replacementChar = new UnicodeScalar(0xFFFD); + + /// + /// The integer value of this scalar. + /// + public readonly int Value; // = U+0000 if using default init + + /// + /// Constructs a Unicode scalar from the given value. + /// The value must represent a valid scalar. + /// + public UnicodeScalar(int value) + : this((uint)value) + { + // None of the APIs on this type are guaranteed to produce correct results + // if we don't validate the input during construction. + + if (!IsValidScalar((uint)Value)) + { + throw new ArgumentOutOfRangeException( + message: "Value must be between U+0000 and U+D7FF, inclusive; or value must be between U+E000 and U+10FFFF, inclusive.", + paramName: nameof(value)); + } + } + + // non-validating ctor for internal use + private UnicodeScalar(uint value) + { + Value = (int)value; + } + + internal static UnicodeScalar CreateWithoutValidation(uint value) => new UnicodeScalar(value); + + public int CompareTo(UnicodeScalar other) => Value.CompareTo(other.Value); + + public override bool Equals(object other) => (other is UnicodeScalar) && Equals((UnicodeScalar)other); + + public bool Equals(UnicodeScalar other) => Value == other.Value; + + public override int GetHashCode() => Value; + + private static bool IsValidScalar(uint value) + => (value < 0xD800U) || IsInRangeInclusive(value, 0xE000U, 0x10FFFFU); + + /// + /// Returns iff is between + /// and , inclusive. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBound) + => (value - lowerBound) <= (upperBound - lowerBound); + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs new file mode 100644 index 000000000000..9ff923dd7d1c --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -0,0 +1,242 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) + => WriteString(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, value); + else + WriteStringByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, value); + else + WriteStringByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTime value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteStringByOptions(ref propertyName, value); + } + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTime value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteStringByOptions(ref propertyName, value); + } + } + + private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStringByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStringByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, value); + } + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTime value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTime value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTime value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTime value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringValue(DateTime value, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + FormatLoop(value, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + } + + private void FormatLoop(DateTime value, ref int idx) + { + int bytesWritten; + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumDateTimeLength); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs new file mode 100644 index 000000000000..5025a91c20f1 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -0,0 +1,242 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) + => WriteString(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, value); + else + WriteStringByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, value); + else + WriteStringByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTimeOffset value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteStringByOptions(ref propertyName, value); + } + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTimeOffset value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteStringByOptions(ref propertyName, value); + } + } + + private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStringByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStringByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeOffset value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeOffset value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, value); + } + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringValue(DateTimeOffset value, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + FormatLoop(value, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + } + + private void FormatLoop(DateTimeOffset value, ref int idx) + { + int bytesWritten; + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumDateTimeOffsetLength); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs new file mode 100644 index 000000000000..46a24121e8fb --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -0,0 +1,223 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decimal value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decimal value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, decimal value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, decimal value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, decimal value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, decimal value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueFormatLoop(decimal value, ref int idx) + { + int bytesWritten; + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumDecimalLength); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs new file mode 100644 index 000000000000..476f75f66994 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -0,0 +1,223 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, double value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, double value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, double value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, double value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, double value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, double value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueFormatLoop(double value, ref int idx) + { + int bytesWritten; + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumDoubleLength); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs new file mode 100644 index 000000000000..aae5e1915097 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -0,0 +1,223 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, float value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, float value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, float value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, float value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueFormatLoop(float value, ref int idx) + { + int bytesWritten; + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumSingleLength); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs new file mode 100644 index 000000000000..bc4e0ee304e4 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -0,0 +1,242 @@ +// 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. + +using System.Buffers; +using System.Buffers.Text; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) + => WriteString(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, value); + else + WriteStringByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, value); + else + WriteStringByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteStringByOptions(ref propertyName, value); + } + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteStringByOptions(ref propertyName, value); + } + } + + private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStringByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStringByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, value); + } + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, Guid value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, Guid value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, Guid value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, Guid value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(value, ref idx); + + Advance(idx); + } + + private void WriteStringValue(Guid value, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + FormatLoop(value, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + } + + private void FormatLoop(Guid value, ref int idx) + { + int bytesWritten; + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumGuidLength); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs new file mode 100644 index 000000000000..dddc1e2dc2a5 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -0,0 +1,265 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) + ThrowHelper.ThrowJsonWriterOrArgumentException(propertyName, _currentDepth); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) + { + // TODO: Use throw helper with proper error messages + if (propertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) + ThrowHelper.ThrowJsonWriterOrArgumentException(propertyName, _currentDepth); + } + + private void ValidateWritingProperty() + { + if (!_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.StartObject); + ThrowHelper.ThrowJsonWriterException("Cannot add a property within an array or as the first JSON token."); //TODO: Add resouce message + } + } + + private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyName) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + CopyLoop(ref escapedPropertyName, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.KeyValueSeperator; + + return idx; + } + + private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + CopyLoop(ref escapedPropertyName, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.KeyValueSeperator; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Space; + + return idx; + } + + private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyName) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + ReadOnlySpan byteSpan = MemoryMarshal.AsBytes(escapedPropertyName); + int partialConsumed = 0; + while (true) + { + OperationStatus status = JsonWriterHelper.ToUtf8(byteSpan.Slice(partialConsumed), _buffer.Slice(idx), out int consumed, out int written); + idx += written; + if (status == OperationStatus.Done) + { + break; + } + partialConsumed += consumed; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.KeyValueSeperator; + + return idx; + } + + private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + ReadOnlySpan byteSpan = MemoryMarshal.AsBytes(escapedPropertyName); + int partialConsumed = 0; + while (true) + { + OperationStatus status = JsonWriterHelper.ToUtf8(byteSpan.Slice(partialConsumed), _buffer.Slice(idx), out int consumed, out int written); + idx += written; + if (status == OperationStatus.Done) + { + break; + } + partialConsumed += consumed; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.KeyValueSeperator; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Space; + + return idx; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs new file mode 100644 index 000000000000..cf2e6eb0d951 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -0,0 +1,236 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNull(string propertyName, bool suppressEscaping = false) + => WriteNull(propertyName.AsSpan(), suppressEscaping); + + public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + ReadOnlySpan span = JsonConstants.NullValue; + + if (!suppressEscaping) + WriteLiteralSuppressFalse(ref propertyName, ref span); + else + WriteLiteralByOptions(ref propertyName, ref span); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Null; + } + + public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + ReadOnlySpan span = JsonConstants.NullValue; + + if (!suppressEscaping) + WriteLiteralSuppressFalse(ref propertyName, ref span); + else + WriteLiteralByOptions(ref propertyName, ref span); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Null; + } + + public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) + => WriteBoolean(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; + + if (!suppressEscaping) + WriteLiteralSuppressFalse(ref propertyName, ref span); + else + WriteLiteralByOptions(ref propertyName, ref span); + + _currentDepth |= 1 << 31; + _tokenType = value ? JsonTokenType.True : JsonTokenType.False; + } + + public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; + + if (!suppressEscaping) + WriteLiteralSuppressFalse(ref propertyName, ref span); + else + WriteLiteralByOptions(ref propertyName, ref span); + + _currentDepth |= 1 << 31; + _tokenType = value ? JsonTokenType.True : JsonTokenType.False; + } + + private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteLiteralEscapeProperty(ref propertyName, ref value, propertyIdx); + } + else + { + WriteLiteralByOptions(ref propertyName, ref value); + } + } + + private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteLiteralEscapeProperty(ref propertyName, ref value, propertyIdx); + } + else + { + WriteLiteralByOptions(ref propertyName, ref value); + } + } + + private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteLiteralByOptions(ref propertyName, ref value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteLiteralByOptions(ref propertyName, ref value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int idx; + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + idx = WritePropertyNameIndented(ref propertyName); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + idx = WritePropertyNameMinimized(ref propertyName); + } + + if (value.Length > _buffer.Length - idx) + { + AdvanceAndGrow(idx, value.Length); + idx = 0; + } + + value.CopyTo(_buffer.Slice(idx)); + idx += value.Length; + + Advance(idx); + } + + private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int idx; + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + idx = WritePropertyNameIndented(ref propertyName); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + idx = WritePropertyNameMinimized(ref propertyName); + } + + if (value.Length > _buffer.Length - idx) + { + AdvanceAndGrow(idx, value.Length); + idx = 0; + } + + value.CopyTo(_buffer.Slice(idx)); + idx += value.Length; + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs new file mode 100644 index 000000000000..f65f25461101 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -0,0 +1,234 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), (long)value, suppressEscaping); + + public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) + => WriteNumber(propertyName, (long)value, suppressEscaping); + + public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) + => WriteNumber(propertyName, (long)value, suppressEscaping); + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, long value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, long value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, long value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, long value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueFormatLoop(long value, ref int idx) + { + int bytesWritten; + // Using Utf8Formatter with default StandardFormat is roughly 30% slower (17 ns versus 12 ns) + // See: https://github.com/dotnet/corefx/issues/25425 + // Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten); + while (!JsonWriterHelper.TryFormatInt64Default(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumInt64Length); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs new file mode 100644 index 000000000000..baeee86e4ae4 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -0,0 +1,720 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteString(string propertyName, string value, bool suppressEscaping = false) + => WriteString(propertyName.AsSpan(), value.AsSpan(), suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, ref value); + else + WriteStringSuppressTrue(ref propertyName, ref value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, ref value); + else + WriteStringSuppressTrue(ref propertyName, ref value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) + => WriteString(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, ref value); + else + WriteStringSuppressTrue(ref propertyName, ref value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) + => WriteString(propertyName.AsSpan(), value, suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref propertyName, ref value); + else + WriteStringSuppressTrue(ref propertyName, ref value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) + => WriteString(propertyName, value.AsSpan(), suppressEscaping); + + public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) + => WriteString(propertyName, value.AsSpan(), suppressEscaping); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + if (valueIdx != -1) + { + WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + } + else + { + WriteStringByOptions(ref escapedPropertyName, ref value); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + if (valueIdx != -1) + { + WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + } + else + { + WriteStringByOptions(ref escapedPropertyName, ref value); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + if (valueIdx != -1) + { + WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + } + else + { + WriteStringByOptions(ref escapedPropertyName, ref value); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + if (valueIdx != -1) + { + WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + } + else + { + WriteStringByOptions(ref escapedPropertyName, ref value); + } + } + + private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + Span span = valueArray; + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); + value = span.Slice(0, written); + + WriteStringByOptions(ref escapedPropertyName, ref value); + + ArrayPool.Shared.Return(valueArray); + } + + private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + Span span = valueArray; + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); + value = span.Slice(0, written); + + WriteStringByOptions(ref escapedPropertyName, ref value); + + ArrayPool.Shared.Return(valueArray); + } + + private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + Span span = valueArray; + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); + value = span.Slice(0, written); + + WriteStringByOptions(ref escapedPropertyName, ref value); + + ArrayPool.Shared.Return(valueArray); + } + + private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + Span span = valueArray; + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); + value = span.Slice(0, written); + + WriteStringByOptions(ref escapedPropertyName, ref value); + + ArrayPool.Shared.Return(valueArray); + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + // Equivalent to: valueIdx != -1 || propertyIdx != -1 + if (valueIdx + propertyIdx != -2) + { + WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + } + else + { + WriteStringByOptions(ref propertyName, ref value); + } + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + // Equivalent to: valueIdx != -1 || propertyIdx != -1 + if (valueIdx + propertyIdx != -2) + { + WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + } + else + { + WriteStringByOptions(ref propertyName, ref value); + } + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + // Equivalent to: valueIdx != -1 || propertyIdx != -1 + if (valueIdx + propertyIdx != -2) + { + WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + } + else + { + WriteStringByOptions(ref propertyName, ref value); + } + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + // Equivalent to: valueIdx != -1 || propertyIdx != -1 + if (valueIdx + propertyIdx != -2) + { + WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + } + else + { + WriteStringByOptions(ref propertyName, ref value); + } + } + + private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] valueArray = null; + char[] propertyArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + if (firstEscapeIndexProp != -1) + { + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + } + + WriteStringByOptions(ref propertyName, ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] valueArray = null; + byte[] propertyArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + if (firstEscapeIndexProp != -1) + { + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + } + + WriteStringByOptions(ref propertyName, ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] valueArray = null; + char[] propertyArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + if (firstEscapeIndexProp != -1) + { + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + } + + WriteStringByOptions(ref propertyName, ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] valueArray = null; + byte[] propertyArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + if (firstEscapeIndexProp != -1) + { + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + } + + WriteStringByOptions(ref propertyName, ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, ref value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, ref value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, ref value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringIndented(ref propertyName, ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteStringMinimized(ref propertyName, ref value); + } + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringValue(ref ReadOnlySpan escapedValue, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + ReadOnlySpan byteSpan = MemoryMarshal.AsBytes(escapedValue); + int partialConsumed = 0; + while (true) + { + OperationStatus status = JsonWriterHelper.ToUtf8(byteSpan.Slice(partialConsumed), _buffer.Slice(idx), out int consumed, out int written); + idx += written; + if (status == OperationStatus.Done) + { + break; + } + partialConsumed += consumed; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + } + + private void WriteStringValue(ref ReadOnlySpan escapedValue, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + + CopyLoop(ref escapedValue, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Quote; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs new file mode 100644 index 000000000000..05b21443e6fa --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -0,0 +1,240 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + [CLSCompliant(false)] + public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + + [CLSCompliant(false)] + public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + [CLSCompliant(false)] + public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateProperty(ref propertyName); + + if (!suppressEscaping) + WriteNumberSuppressFalse(ref propertyName, value); + else + WriteNumberByOptions(ref propertyName, value); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + [CLSCompliant(false)] + public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) + => WriteNumber(propertyName.AsSpan(), (ulong)value, suppressEscaping); + + [CLSCompliant(false)] + public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) + => WriteNumber(propertyName, (ulong)value, suppressEscaping); + + [CLSCompliant(false)] + public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) + => WriteNumber(propertyName, (ulong)value, suppressEscaping); + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong value) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + } + else + { + WriteNumberByOptions(ref propertyName, value); + } + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteNumberByOptions(ref propertyName, value); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberIndented(ref propertyName, value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + } + WriteNumberMinimized(ref propertyName, value); + } + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, ulong value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, ulong value) + { + int idx = WritePropertyNameMinimized(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, ulong value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, ulong value) + { + int idx = WritePropertyNameIndented(ref escapedPropertyName); + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueFormatLoop(ulong value, ref int idx) + { + int bytesWritten; + // Using Utf8Formatter with default StandardFormat is roughly 30% slower (17 ns versus 12 ns) + // See: https://github.com/dotnet/corefx/issues/25425 + // Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten); + while (!JsonWriterHelper.TryFormatUInt64Default(value, _buffer.Slice(idx), out bytesWritten)) + { + AdvanceAndGrow(idx, JsonConstants.MaximumUInt64Length); + idx = 0; + } + idx += bytesWritten; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs new file mode 100644 index 000000000000..6762109b2214 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -0,0 +1,365 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) + => WriteCommentValue(utf16Text.AsSpan(), suppressEscaping); + + public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateValue(ref utf16Text); + + if (!suppressEscaping) + WriteCommentSuppressFalse(ref utf16Text); + else + WriteCommentByOptions(ref utf16Text); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteCommentSuppressFalse(ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + + if (valueIdx != -1) + { + WriteCommentEscapeValue(ref value, valueIdx); + } + else + { + WriteCommentByOptions(ref value); + } + } + + private void WriteCommentByOptions(ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteCommentIndented(ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteCommentMinimized(ref value); + } + } + + private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteCommentValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteCommentIndented(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteCommentValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + char[] valueArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + WriteCommentByOptions(ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + } + + public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateValue(ref utf8Text); + + if (!suppressEscaping) + WriteCommentSuppressFalse(ref utf8Text); + else + WriteCommentByOptions(ref utf8Text); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteCommentSuppressFalse(ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + + if (valueIdx != -1) + { + WriteCommentEscapeValue(ref value, valueIdx); + } + else + { + WriteCommentByOptions(ref value); + } + } + + private void WriteCommentByOptions(ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteCommentIndented(ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteCommentMinimized(ref value); + } + } + + private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteCommentValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteCommentIndented(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteCommentValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + byte[] valueArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + WriteCommentByOptions(ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + } + + private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Slash; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + + ReadOnlySpan byteSpan = MemoryMarshal.AsBytes(escapedValue); + int partialConsumed = 0; + while (true) + { + OperationStatus status = JsonWriterHelper.ToUtf8(byteSpan.Slice(partialConsumed), _buffer.Slice(idx), out int consumed, out int written); + idx += written; + if (status == OperationStatus.Done) + { + break; + } + partialConsumed += consumed; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Slash; + } + + private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Slash; + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + + CopyLoop(ref escapedValue, ref idx); + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.Slash; + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs new file mode 100644 index 000000000000..aa09512a7cb9 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -0,0 +1,93 @@ +// 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. + +using System.Buffers.Text; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteStringValue(DateTime value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringValueMinimized(DateTime value) + { + // Calculated based on the following: ',"DateTime value"' + int bytesNeeded = JsonConstants.MaximumDateTimeLength + 1; + if (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(bytesNeeded); + } + + int idx = 0; + if (_currentDepth < 0) + { + _buffer[idx++] = JsonConstants.ListSeperator; + } + + _buffer[idx++] = JsonConstants.Quote; + + Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); + idx += bytesWritten; + + _buffer[idx++] = JsonConstants.Quote; + + Advance(idx); + } + + private void WriteStringValueIndented(DateTime value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteStringValue(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs new file mode 100644 index 000000000000..fe8504d46d9c --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -0,0 +1,93 @@ +// 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. + +using System.Buffers.Text; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteStringValue(DateTimeOffset value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringValueMinimized(DateTimeOffset value) + { + // Calculated based on the following: ',"DateTimeOffset value"' + int bytesNeeded = JsonConstants.MaximumDateTimeOffsetLength + 1; + if (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(bytesNeeded); + } + + int idx = 0; + if (_currentDepth < 0) + { + _buffer[idx++] = JsonConstants.ListSeperator; + } + + _buffer[idx++] = JsonConstants.Quote; + + Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); + idx += bytesWritten; + + _buffer[idx++] = JsonConstants.Quote; + + Advance(idx); + } + + private void WriteStringValueIndented(DateTimeOffset value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteStringValue(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs new file mode 100644 index 000000000000..8035d1264bf4 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -0,0 +1,83 @@ +// 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. + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumberValue(decimal value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberValueMinimized(decimal value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueIndented(decimal value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs new file mode 100644 index 000000000000..9346dbf70f35 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -0,0 +1,83 @@ +// 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. + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumberValue(double value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberValueMinimized(double value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueIndented(double value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs new file mode 100644 index 000000000000..e52a5064b4ed --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -0,0 +1,83 @@ +// 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. + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumberValue(float value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberValueMinimized(float value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + + private void WriteNumberValueIndented(float value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs new file mode 100644 index 000000000000..c0f034b1c502 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -0,0 +1,93 @@ +// 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. + +using System.Buffers.Text; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteStringValue(Guid value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringValueMinimized(Guid value) + { + // Calculated based on the following: ',"Guid value"' + int bytesNeeded = JsonConstants.MaximumGuidLength + 1; + if (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(bytesNeeded); + } + + int idx = 0; + if (_currentDepth < 0) + { + _buffer[idx++] = JsonConstants.ListSeperator; + } + + _buffer[idx++] = JsonConstants.Quote; + + Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); + idx += bytesWritten; + + _buffer[idx++] = JsonConstants.Quote; + + Advance(idx); + } + + private void WriteStringValueIndented(Guid value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteStringValue(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs new file mode 100644 index 000000000000..26bb39ddc191 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -0,0 +1,27 @@ +// 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. + +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + private void ValidateWritingValue() + { + if (_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); + ThrowHelper.ThrowJsonWriterException(_tokenType); //TODO: Add resource message + } + else + { + if (!_isNotPrimitive && _tokenType != JsonTokenType.None) + { + ThrowHelper.ThrowJsonWriterException(_tokenType); //TODO: Add resource message + } + } + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs new file mode 100644 index 000000000000..8e9ca1783062 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -0,0 +1,107 @@ +// 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. + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNullValue() + { + WriteLiteralByOptions(JsonConstants.NullValue); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Null; + } + + public void WriteBooleanValue(bool value) + { + if (value) + { + WriteLiteralByOptions(JsonConstants.TrueValue); + _tokenType = JsonTokenType.True; + } + else + { + WriteLiteralByOptions(JsonConstants.FalseValue); + _tokenType = JsonTokenType.False; + } + + _currentDepth |= 1 << 31; + } + + private void WriteLiteralByOptions(ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteLiteralIndented(ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteLiteralMinimized(ref value); + } + } + + private void WriteLiteralMinimized(ref ReadOnlySpan value) + { + // Calculated based on the following: ',null' OR ',true' OR ',false' + int bytesNeeded = value.Length + 1; + if (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(bytesNeeded); + } + + int idx = 0; + if (_currentDepth < 0) + { + _buffer[idx++] = JsonConstants.ListSeperator; + } + + value.CopyTo(_buffer.Slice(idx)); + + Advance(idx + value.Length); + } + + private void WriteLiteralIndented(ref ReadOnlySpan value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + CopyLoop(ref value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs new file mode 100644 index 000000000000..911a44b3193c --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -0,0 +1,89 @@ +// 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. + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteNumberValue(int value) + => WriteNumberValue((long)value); + + public void WriteNumberValue(long value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberValueMinimized(long value) + { + // Calculated based on the following: ',long.MaxValue' + int bytesNeeded = JsonConstants.MaximumInt64Length + 1; + if (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(bytesNeeded); + } + + int idx = 0; + if (_currentDepth < 0) + { + _buffer[idx++] = JsonConstants.ListSeperator; + } + + JsonWriterHelper.TryFormatInt64Default(value, _buffer.Slice(idx), out int bytesWritten); + + Advance(idx + bytesWritten); + } + + private void WriteNumberValueIndented(long value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs new file mode 100644 index 000000000000..7cb27f53c904 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -0,0 +1,285 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + public void WriteStringValue(string utf16Text, bool suppressEscaping = false) + => WriteStringValue(utf16Text.AsSpan(), suppressEscaping); + + public void WriteStringValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateValue(ref utf16Text); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref utf16Text); + else + WriteStringByOptions(ref utf16Text); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + + if (valueIdx != -1) + { + WriteStringEscapeValue(ref value, valueIdx); + } + else + { + WriteStringByOptions(ref value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringIndented(ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringMinimized(ref value); + } + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + char[] valueArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + WriteStringByOptions(ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + } + + public void WriteStringValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) + { + JsonWriterHelper.ValidateValue(ref utf8Text); + + if (!suppressEscaping) + WriteStringSuppressFalse(ref utf8Text); + else + WriteStringByOptions(ref utf8Text); + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.String; + } + + private void WriteStringSuppressFalse(ref ReadOnlySpan value) + { + int valueIdx = JsonWriterHelper.NeedsEscaping(value); + + Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); + + if (valueIdx != -1) + { + WriteStringEscapeValue(ref value, valueIdx); + } + else + { + WriteStringByOptions(ref value); + } + } + + private void WriteStringByOptions(ref ReadOnlySpan value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringIndented(ref value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteStringMinimized(ref value); + } + } + + private void WriteStringMinimized(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringIndented(ref ReadOnlySpan escapedValue) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteStringValue(ref escapedValue, ref idx); + + Advance(idx); + } + + private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + { + Debug.Assert(int.MaxValue / 6 >= value.Length); + + byte[] valueArray = null; + + if (firstEscapeIndexVal != -1) + { + int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + + Span span; + if (length > 256) + { + valueArray = ArrayPool.Shared.Rent(length); + span = valueArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + value = span.Slice(0, written); + } + + WriteStringByOptions(ref value); + + if (valueArray != null) + ArrayPool.Shared.Return(valueArray); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs new file mode 100644 index 000000000000..67f8f92df749 --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -0,0 +1,91 @@ +// 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. + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + [CLSCompliant(false)] + public void WriteNumberValue(uint value) + => WriteNumberValue((ulong)value); + + [CLSCompliant(false)] + public void WriteNumberValue(ulong value) + { + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueIndented(value); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingValue(); + } + WriteNumberValueMinimized(value); + } + + _currentDepth |= 1 << 31; + _tokenType = JsonTokenType.Number; + } + + private void WriteNumberValueMinimized(ulong value) + { + // Calculated based on the following: ',ulong.MaxValue' + int bytesNeeded = JsonConstants.MaximumUInt64Length + 1; + if (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(bytesNeeded); + } + + int idx = 0; + if (_currentDepth < 0) + { + _buffer[idx++] = JsonConstants.ListSeperator; + } + + JsonWriterHelper.TryFormatUInt64Default(value, _buffer.Slice(idx), out int bytesWritten); + + Advance(idx + bytesWritten); + } + + private void WriteNumberValueIndented(ulong value) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + WriteNumberValueFormatLoop(value, ref idx); + + Advance(idx); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs new file mode 100644 index 000000000000..1f32f8f81a0e --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -0,0 +1,760 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Text.Json +{ + public ref partial struct Utf8JsonWriter + { + private const int MinimumSizeThreshold = 256; + + private IBufferWriter _output; + private int _buffered; + private Span _buffer; + + public long BytesWritten + { + get + { + Debug.Assert(BytesCommitted <= long.MaxValue - _buffered); + return BytesCommitted + _buffered; + } + } + + public long BytesCommitted { get; private set; } + + private bool _inObject; + private bool _isNotPrimitive; + private JsonTokenType _tokenType; + private readonly JsonWriterOptions _writerOptions; + private BitStack _bitStack; + + // The highest order bit of _currentDepth is used to discern whether we are writing the first item in a list or not. + // if (_currentDepth >> 31) == 1, add a list separator before writing the item + // else, no list separator is needed since we are writing the first item. + private int _currentDepth; + + private int Indentation => CurrentDepth * 2; + + public int CurrentDepth => _currentDepth & JsonConstants.RemoveFlagsBitMask; + + public JsonWriterState CurrentState => new JsonWriterState + { + _bytesWritten = BytesWritten, + _bytesCommitted = BytesCommitted, + _inObject = _inObject, + _isNotPrimitive = _isNotPrimitive, + _tokenType = _tokenType, + _writerOptions = _writerOptions, + _bitStack = _bitStack, + }; + + /// + /// Constructs a JSON writer with a specified . + /// + /// An instance of used for writing bytes to an output channel. + /// Specifies whether to add whitespace to the output text for user readability. + public Utf8JsonWriter(IBufferWriter bufferWriter, JsonWriterState state = default) + { + _output = bufferWriter ?? throw new ArgumentNullException(nameof(bufferWriter)); + _buffered = 0; + BytesCommitted = 0; + _buffer = _output.GetSpan(); + + _inObject = state._inObject; + _isNotPrimitive = state._isNotPrimitive; + _tokenType = state._tokenType; + _writerOptions = state._writerOptions; + _bitStack = state._bitStack; + + _currentDepth = 0; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void Advance(int count) + { + Debug.Assert(count >= 0 && _buffered <= int.MaxValue - count); + + _buffered += count; + _buffer = _buffer.Slice(count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void CheckSizeAndGrow(int count) + { + Debug.Assert(count >= 0); + + if (_buffer.Length < count) + GrowSpan(count); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private void GrowSpan(int count) + { + Flush(); + + if (_output == null) + { + if (count < MinimumSizeThreshold) + { + throw new ArgumentException("The output span provided is too small."); + } + } + else + { + _buffer = _output.GetSpan(count); + + if (_buffer.Length < count && count < MinimumSizeThreshold) + { + throw new ArgumentException("The IBufferWriter could not provide a span that is large enough to continue."); + } + + Debug.Assert(_buffer.Length >= Math.Min(count, MinimumSizeThreshold)); + } + } + + public void Flush(bool isFinalBlock = true) + { + //TODO: Fix exception message and check other potential conditions for invalid end. + if (isFinalBlock && !_writerOptions.SkipValidation && CurrentDepth != 0) + ThrowHelper.ThrowJsonWriterException("Invalid end of JSON."); + + Flush(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void Flush() + { + BytesCommitted += _buffered; + if (_output == null) + { + Debug.Assert(_buffer.Length >= _buffered); + _buffer = _buffer.Slice(_buffered); + } + else + { + _output.Advance(_buffered); + } + _buffered = 0; + } + + public void WriteStartArray() + { + WriteStart(JsonConstants.OpenBracket); + _tokenType = JsonTokenType.StartArray; + } + + public void WriteStartObject() + { + WriteStart(JsonConstants.OpenBrace); + _tokenType = JsonTokenType.StartObject; + } + + private void WriteStart(byte token) + { + // TODO: Use throw helper with proper error messages + if (CurrentDepth >= JsonConstants.MaxWriterDepth) + ThrowHelper.ThrowJsonWriterException("Depth too large."); + + if (_writerOptions.SlowPath) + WriteStartSlow(token); + else + WriteStartMinimized(token); + + _currentDepth &= JsonConstants.RemoveFlagsBitMask; + _currentDepth++; + _isNotPrimitive = true; + } + + private void WriteStartMinimized(byte token) + { + // Calculated based on the following: ',[' OR ',{' + int bytesNeeded = 2; + while (_buffer.Length < bytesNeeded) + { + GrowAndEnsure(); + } + + if (_currentDepth < 0) + { + _buffer[0] = JsonConstants.ListSeperator; + _buffer[1] = token; + } + else + { + bytesNeeded--; + _buffer[0] = token; + } + Advance(bytesNeeded); + } + + private void WriteStartSlow(byte token) + { + Debug.Assert(_writerOptions.Indented || !_writerOptions.SkipValidation); + + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateStart(token); + UpdateBitStackOnStart(token); + } + WriteStartIndented(token); + } + else + { + Debug.Assert(!_writerOptions.SkipValidation); + ValidateStart(token); + UpdateBitStackOnStart(token); + WriteStartMinimized(token); + } + } + + private void ValidateStart(byte token) + { + if (_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); + ThrowHelper.ThrowJsonWriterException(token, _tokenType); + } + else + { + Debug.Assert(_tokenType != JsonTokenType.StartObject); + if (_tokenType != JsonTokenType.None && !_isNotPrimitive) + { + ThrowHelper.ThrowJsonWriterException(token, _tokenType); + } + } + } + + private void WriteStartIndented(byte token) + { + int idx = 0; + if (_currentDepth < 0) + { + while (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeperator; + } + + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = token; + + Advance(idx); + } + + public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) + { + ValidatePropertyNameAndDepth(ref propertyName); + + if (!suppressEscaping) + WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBracket); + else + WriteStartByOptions(ref propertyName, JsonConstants.OpenBracket); + + _currentDepth &= JsonConstants.RemoveFlagsBitMask; + _currentDepth++; + _isNotPrimitive = true; + _tokenType = JsonTokenType.StartArray; + } + + public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) + { + ValidatePropertyNameAndDepth(ref propertyName); + + if (!suppressEscaping) + WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBrace); + else + WriteStartByOptions(ref propertyName, JsonConstants.OpenBrace); + + _currentDepth &= JsonConstants.RemoveFlagsBitMask; + _currentDepth++; + _isNotPrimitive = true; + _tokenType = JsonTokenType.StartObject; + } + + private void WriteStartSuppressFalse(ref ReadOnlySpan propertyName, byte token) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStartEscapeProperty(ref propertyName, token, propertyIdx); + } + else + { + WriteStartByOptions(ref propertyName, token); + } + } + + private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token) + { + int idx; + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + UpdateBitStackOnStart(token); + } + idx = WritePropertyNameIndented(ref propertyName); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + UpdateBitStackOnStart(token); + } + idx = WritePropertyNameMinimized(ref propertyName); + } + + if (1 > _buffer.Length - idx) + { + AdvanceAndGrow(idx, 1); + idx = 0; + } + + _buffer[idx++] = token; + + Advance(idx); + } + + private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + byte[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + byte* ptr = stackalloc byte[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStartByOptions(ref propertyName, token); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + public void WriteStartArray(string propertyName, bool suppressEscaping = false) + => WriteStartArray(propertyName.AsSpan(), suppressEscaping); + + public void WriteStartObject(string propertyName, bool suppressEscaping = false) + => WriteStartObject(propertyName.AsSpan(), suppressEscaping); + + public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) + { + ValidatePropertyNameAndDepth(ref propertyName); + + if (!suppressEscaping) + WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBracket); + else + WriteStartByOptions(ref propertyName, JsonConstants.OpenBracket); + + _currentDepth &= JsonConstants.RemoveFlagsBitMask; + _currentDepth++; + _isNotPrimitive = true; + _tokenType = JsonTokenType.StartArray; + } + + public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) + { + ValidatePropertyNameAndDepth(ref propertyName); + + if (!suppressEscaping) + WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBrace); + else + WriteStartByOptions(ref propertyName, JsonConstants.OpenBrace); + + _currentDepth &= JsonConstants.RemoveFlagsBitMask; + _currentDepth++; + _isNotPrimitive = true; + _tokenType = JsonTokenType.StartObject; + } + + private void WriteStartSuppressFalse(ref ReadOnlySpan propertyName, byte token) + { + int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); + + if (propertyIdx != -1) + { + WriteStartEscapeProperty(ref propertyName, token, propertyIdx); + } + else + { + WriteStartByOptions(ref propertyName, token); + } + } + + private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token) + { + int idx; + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + UpdateBitStackOnStart(token); + } + idx = WritePropertyNameIndented(ref propertyName); + } + else + { + if (!_writerOptions.SkipValidation) + { + ValidateWritingProperty(); + UpdateBitStackOnStart(token); + } + idx = WritePropertyNameMinimized(ref propertyName); + } + + if (1 > _buffer.Length - idx) + { + AdvanceAndGrow(idx, 1); + idx = 0; + } + + _buffer[idx++] = token; + + Advance(idx); + } + + private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + { + Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + + char[] propertyArray = null; + + int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + Span span; + if (length > 256) + { + propertyArray = ArrayPool.Shared.Rent(length); + span = propertyArray; + } + else + { + // Cannot create a span directly since the span gets exposed outside this method. + unsafe + { + char* ptr = stackalloc char[length]; + span = new Span(ptr, length); + } + } + JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + propertyName = span.Slice(0, written); + + WriteStartByOptions(ref propertyName, token); + + if (propertyArray != null) + ArrayPool.Shared.Return(propertyArray); + } + + public void WriteEndArray() + { + WriteEnd(JsonConstants.CloseBracket); + _tokenType = JsonTokenType.EndArray; + } + + public void WriteEndObject() + { + WriteEnd(JsonConstants.CloseBrace); + _tokenType = JsonTokenType.EndObject; + } + + private void WriteEnd(byte token) + { + _currentDepth |= 1 << 31; + _currentDepth--; + + // Necessary if WriteEndX is called without a corresponding WriteStartX first. + // Checking for int.MaxValue because int.MinValue - 1 = int.MaxValue + if (_currentDepth == int.MaxValue) + { + _currentDepth = 0; + } + + if (_writerOptions.SlowPath) + WriteEndSlow(token); + else + WriteEndMinimized(token); + } + + private void WriteEndMinimized(byte token) + { + while (_buffer.Length < 1) + { + GrowAndEnsure(); + } + + _buffer[0] = token; + Advance(1); + } + + private void WriteEndSlow(byte token) + { + Debug.Assert(_writerOptions.Indented || !_writerOptions.SkipValidation); + + if (_writerOptions.Indented) + { + if (!_writerOptions.SkipValidation) + { + ValidateEnd(token); + } + WriteEndIndented(token); + } + else + { + Debug.Assert(!_writerOptions.SkipValidation); + ValidateEnd(token); + WriteEndMinimized(token); + } + } + + private void ValidateEnd(byte token) + { + if (_bitStack.CurrentDepth <= 0) + ThrowHelper.ThrowJsonWriterException(token); //TODO: Add resource message + + if (token == JsonConstants.CloseBracket) + { + if (_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.None); + ThrowHelper.ThrowJsonWriterException(token); //TODO: Add resource message + } + } + else + { + Debug.Assert(token == JsonConstants.CloseBrace); + + if (!_inObject) + { + ThrowHelper.ThrowJsonWriterException(token); //TODO: Add resource message + } + } + + _inObject = _bitStack.Pop(); + } + + private void WriteEndIndented(byte token) + { + // Do not format/indent empty JSON object/array. + if ((_tokenType == JsonTokenType.StartObject && token == JsonConstants.CloseBrace) + || (_tokenType == JsonTokenType.StartArray && token == JsonConstants.CloseBracket)) + { + WriteEndMinimized(token); + } + else + { + int idx = 0; + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(idx); + idx = 0; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = token; + + Advance(idx); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private Span GetSpan(int bytesNeeded) + { + CheckSizeAndGrow(bytesNeeded); + Debug.Assert(_buffer.Length >= bytesNeeded); + return _buffer; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void WriteNewLine(ref Span byteBuffer, ref int idx) + { + // Write '\r\n' OR '\n', depending on OS + if (JsonWriterHelper.s_newLineUtf8.Length == 2) + byteBuffer[idx++] = JsonConstants.CarriageReturn; + + byteBuffer[idx++] = JsonConstants.LineFeed; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void WriteNewLine(ref int idx) + { + // Write '\r\n' OR '\n', depending on OS + if (JsonWriterHelper.s_newLineUtf8.Length == 2) + { + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.CarriageReturn; + } + + while (_buffer.Length <= idx) + { + AdvanceAndGrow(idx); + idx = 0; + } + _buffer[idx++] = JsonConstants.LineFeed; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void UpdateBitStackOnStart(byte token) + { + if (token == JsonConstants.OpenBracket) + { + _bitStack.PushFalse(); + _inObject = false; + } + else + { + Debug.Assert(token == JsonConstants.OpenBrace); + _bitStack.PushTrue(); + _inObject = true; + } + } + + private void GrowAndEnsure() + { + int previousSpanLength = _buffer.Length; + GrowSpan(4096); + if (_buffer.Length <= previousSpanLength) + { + GrowSpan(4096); + if (_buffer.Length <= previousSpanLength) + { + //TODO: Use Throwhelper and fix message. + throw new OutOfMemoryException("Failed to get a larger buffer when growing."); + } + } + } + + private void GrowAndEnsure(int minimumSize) + { + GrowSpan(4096); + if (_buffer.Length <= minimumSize) + { + GrowSpan(4096); + if (_buffer.Length <= minimumSize) + { + //TODO: Use Throwhelper and fix message. + throw new OutOfMemoryException("Failed to get buffer larger than minimumSize when growing."); + } + } + } + + private void AdvanceAndGrow(int alreadyWritten) + { + Debug.Assert(alreadyWritten >= 0); + Advance(alreadyWritten); + GrowAndEnsure(); + } + + private void AdvanceAndGrow(int alreadyWritten, int minimumSize) + { + Debug.Assert(minimumSize > 6 && minimumSize <= 128); + Advance(alreadyWritten); + GrowAndEnsure(minimumSize); + } + + private void CopyLoop(ref ReadOnlySpan span, ref int idx) + { + while (true) + { + if (span.Length <= _buffer.Length - idx) + { + span.CopyTo(_buffer.Slice(idx)); + idx += span.Length; + break; + } + + span.Slice(0, _buffer.Length - idx).CopyTo(_buffer.Slice(idx)); + span = span.Slice(_buffer.Length - idx); + AdvanceAndGrow(_buffer.Length); + idx = 0; + } + } + + private void CopyLoop(ReadOnlySpan span, ref int idx) + { + while (true) + { + if (span.Length <= _buffer.Length - idx) + { + span.CopyTo(_buffer.Slice(idx)); + idx += span.Length; + break; + } + + span.Slice(0, _buffer.Length - idx).CopyTo(_buffer.Slice(idx)); + span = span.Slice(_buffer.Length - idx); + AdvanceAndGrow(_buffer.Length); + idx = 0; + } + } + } +} From 0e1a283d4d780ad9a19b5c95694af9776891966b Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 02:59:44 -0800 Subject: [PATCH 04/33] Auto-generate System.Text.Json ref to update the ordering for consistency. --- src/System.Text.Json/ref/System.Text.Json.cs | 186 +++++++++---------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index 9a083b938292..4c197b8ba8bd 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -20,21 +20,11 @@ public JsonReaderException(string message, long lineNumber, long bytePositionInL public long LineNumber { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } - public sealed partial class JsonWriterException : System.Exception - { - public JsonWriterException(string message) { } - } public partial struct JsonReaderOptions { private object _dummy; public System.Text.Json.JsonCommentHandling CommentHandling { get { throw null; } set { } } } - public partial struct JsonWriterOptions - { - private object _dummy; - public bool Indented { get { throw null; } set { } } - public bool SkipValidation { get { throw null; } set { } } - } public partial struct JsonReaderState { private object _dummy; @@ -44,14 +34,6 @@ public partial struct JsonReaderState public System.Text.Json.JsonReaderOptions Options { get { throw null; } } public System.SequencePosition Position { get { throw null; } } } - public partial struct JsonWriterState - { - private object _dummy; - public JsonWriterState(System.Text.Json.JsonWriterOptions options = default(System.Text.Json.JsonWriterOptions)) { throw null; } - public long BytesCommitted { get { throw null; } } - public long BytesWritten { get { throw null; } } - public System.Text.Json.JsonWriterOptions Options { get { throw null; } } - } public enum JsonTokenType : byte { Comment = (byte)11, @@ -67,6 +49,24 @@ public enum JsonTokenType : byte String = (byte)6, True = (byte)8, } + public sealed partial class JsonWriterException : System.Exception + { + public JsonWriterException(string message) { } + } + public partial struct JsonWriterOptions + { + private object _dummy; + public bool Indented { get { throw null; } set { } } + public bool SkipValidation { get { throw null; } set { } } + } + public partial struct JsonWriterState + { + private object _dummy; + public JsonWriterState(System.Text.Json.JsonWriterOptions options = default(System.Text.Json.JsonWriterOptions)) { throw null; } + public long BytesCommitted { get { throw null; } } + public long BytesWritten { get { throw null; } } + public System.Text.Json.JsonWriterOptions Options { get { throw null; } } + } public ref partial struct Utf8JsonReader { private object _dummy; @@ -92,92 +92,92 @@ public ref partial struct Utf8JsonReader public ref partial struct Utf8JsonWriter { private object _dummy; - public Utf8JsonWriter(System.Buffers.IBufferWriter bufferWriter, JsonWriterState state = default(System.Text.Json.JsonWriterState)) { throw null; } + public Utf8JsonWriter(System.Buffers.IBufferWriter bufferWriter, System.Text.Json.JsonWriterState state = default(System.Text.Json.JsonWriterState)) { throw null; } public long BytesCommitted { get { throw null; } } public long BytesWritten { get { throw null; } } public int CurrentDepth { get { throw null; } } public System.Text.Json.JsonWriterState CurrentState { get { throw null; } } - public void Flush(bool isFinalBlock = true) { throw null; } - public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { throw null; } - public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { throw null; } - public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { throw null; } - public void WriteBooleanValue(bool value) { throw null; } - public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) { throw null; } - public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) { throw null; } - public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) { throw null; } - public void WriteEndArray() { throw null; } - public void WriteEndObject() { throw null; } - public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } - public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } - public void WriteNull(string propertyName, bool suppressEscaping = false) { throw null; } - public void WriteNullValue() { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { throw null; } + public void Flush(bool isFinalBlock = true) { } + public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } + public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } + public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { } + public void WriteBooleanValue(bool value) { } + public void WriteCommentValue(System.ReadOnlySpan utf8Text, bool suppressEscaping = false) { } + public void WriteCommentValue(System.ReadOnlySpan utf16Text, bool suppressEscaping = false) { } + public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) { } + public void WriteEndArray() { } + public void WriteEndObject() { } + public void WriteNull(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } + public void WriteNull(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } + public void WriteNull(string propertyName, bool suppressEscaping = false) { } + public void WriteNullValue() { } + public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) { throw null; } - public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) { throw null; } + public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) { throw null; } - public void WriteNumberValue(decimal value) { throw null; } - public void WriteNumberValue(double value) { throw null; } - public void WriteNumberValue(int value) { throw null; } - public void WriteNumberValue(long value) { throw null; } - public void WriteNumberValue(float value) { throw null; } + public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) { } + public void WriteNumberValue(decimal value) { } + public void WriteNumberValue(double value) { } + public void WriteNumberValue(int value) { } + public void WriteNumberValue(long value) { } + public void WriteNumberValue(float value) { } [System.CLSCompliantAttribute(false)] - public void WriteNumberValue(uint value) { throw null; } + public void WriteNumberValue(uint value) { } [System.CLSCompliantAttribute(false)] - public void WriteNumberValue(ulong value) { throw null; } - public void WriteStartArray() { throw null; } - public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } - public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } - public void WriteStartArray(string propertyName, bool suppressEscaping = false) { throw null; } - public void WriteStartObject() { throw null; } - public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } - public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { throw null; } - public void WriteStartObject(string propertyName, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } - public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { throw null; } - public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) { throw null; } - public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) { throw null; } - public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) { throw null; } - public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } - public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) { throw null; } - public void WriteString(string propertyName, string value, bool suppressEscaping = false) { throw null; } - public void WriteStringValue(DateTime value) { throw null; } - public void WriteStringValue(DateTimeOffset value) { throw null; } - public void WriteStringValue(Guid value) { throw null; } - public void WriteStringValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) { throw null; } - public void WriteStringValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) { throw null; } - public void WriteStringValue(string utf16Text, bool suppressEscaping = false) { throw null; } + public void WriteNumberValue(ulong value) { } + public void WriteStartArray() { } + public void WriteStartArray(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } + public void WriteStartArray(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } + public void WriteStartArray(string propertyName, bool suppressEscaping = false) { } + public void WriteStartObject() { } + public void WriteStartObject(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } + public void WriteStartObject(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } + public void WriteStartObject(string propertyName, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteString(System.ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { } + public void WriteString(string propertyName, System.DateTime value, bool suppressEscaping = false) { } + public void WriteString(string propertyName, System.DateTimeOffset value, bool suppressEscaping = false) { } + public void WriteString(string propertyName, System.Guid value, bool suppressEscaping = false) { } + public void WriteString(string propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteString(string propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteString(string propertyName, string value, bool suppressEscaping = false) { } + public void WriteStringValue(System.DateTime value) { } + public void WriteStringValue(System.DateTimeOffset value) { } + public void WriteStringValue(System.Guid value) { } + public void WriteStringValue(System.ReadOnlySpan utf8Text, bool suppressEscaping = false) { } + public void WriteStringValue(System.ReadOnlySpan utf16Text, bool suppressEscaping = false) { } + public void WriteStringValue(string utf16Text, bool suppressEscaping = false) { } } } From fd8bd6d580048e0514d3efdd7cd859f28bb4aa66 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 03:23:48 -0800 Subject: [PATCH 05/33] Fixed some TODOs, delete dead code, and formatting cleanup. --- .../src/System/Text/Json/JsonConstants.cs | 6 +- .../Text/Json/Writer/JsonWriterException.cs | 18 +- .../Json/Writer/JsonWriterHelper.Escaping.cs | 8 - .../Text/Json/Writer/JsonWriterHelper.cs | 255 +----------------- .../Utf8JsonWriter.WriteProperties.Guid.cs | 2 +- .../Utf8JsonWriter.WriteValues.Comment.cs | 8 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 2 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 80 +----- 8 files changed, 35 insertions(+), 344 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 2237e11bf891..8a269ed3454e 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -44,9 +44,9 @@ internal static class JsonConstants public const int MaximumInt64Length = 20; // 19 + sign (i.e. -9223372036854775808) public const int MaximumUInt64Length = 20; // i.e. 18446744073709551615 - public const int MaximumDoubleLength = 32; // default (i.e. 'G') TODO: Should it be 22? - public const int MaximumSingleLength = 32; // default (i.e. 'G') TODO: Should it be 13? - public const int MaximumDecimalLength = 32; // default (i.e. 'G') TODO: Should it be 31? + public const int MaximumDoubleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. + public const int MaximumSingleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. + public const int MaximumDecimalLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. public const int MaximumGuidLength = 36; // default (i.e. 'D') 8 + 4 + 4 + 4 + 12 + 4 for the hyphens (e.g. 094ffa0a-0442-494d-b452-04003fa755cc) public const int MaximumDateTimeLength = 26; // default (i.e. 'G') e.g. 05/25/2017 10:30:15 -08:00 public const int MaximumDateTimeOffsetLength = 26; // default (i.e. 'G') e.g. 05/25/2017 10:30:15 -08:00 diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs index 912508bf5f46..b31d6ee0db39 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs @@ -2,13 +2,29 @@ // 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.Runtime.Serialization; + namespace System.Text.Json { - //TODO: Mark as serializable + /// + /// Defines a custom exception object that is thrown by the whenever it + /// tries to write invalid JSON text. This exception is also thrown whenever + /// you write past the pre-set maximum depth or if the you try to write invalid UTF-8 text. + /// + //TODO: Add a test? Do we need to override GetObjectData in this case? + [Serializable] public sealed class JsonWriterException : Exception { + /// + /// Creates a new exception object to relay error information to the user. + /// + /// The context specific error message. public JsonWriterException(string message) : base(message) { } + + private JsonWriterException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 54ca1a6dbbe0..1792fee1ec5b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -2,7 +2,6 @@ // 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.Buffers; using System.Buffers.Text; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -77,13 +76,6 @@ public static int NeedsEscaping(ReadOnlySpan value) return idx; } - // TODO: Remmove this - [MethodImpl(MethodImplOptions.NoInlining)] - public static OperationStatus EscapeString(ReadOnlySpan value, Span destination, out int consumed, out int bytesWritten) - { - throw new NotImplementedException(); - } - public static void EscapeString(ref ReadOnlySpan value, ref Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 87f775efa46f..36541e3bf93f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -4,10 +4,8 @@ using System.Buffers; using System.Diagnostics; -using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using Internal.Runtime.CompilerServices; namespace System.Text.Json { @@ -15,27 +13,6 @@ internal static partial class JsonWriterHelper { public static readonly byte[] s_newLineUtf8 = Encoding.UTF8.GetBytes(Environment.NewLine); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int WriteIndentation(Span buffer) - { - Debug.Assert(buffer.Length % 2 == 0); - - if (buffer.Length < 8) - { - int i = 0; - while (i < buffer.Length) - { - buffer[i++] = JsonConstants.Space; - buffer[i++] = JsonConstants.Space; - } - } - else - { - buffer.Fill(JsonConstants.Space); - } - return buffer.Length; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteIndentation(Span buffer, int indent, out int bytesWritten) { @@ -136,44 +113,6 @@ public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ThrowHelper.ThrowArgumentException(propertyName, value); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteDigitsUInt64D(ulong value, Span buffer) - { - // We can mutate the 'value' parameter since it's a copy-by-value local. - // It'll be used to represent the value left over after each division by 10. - - Debug.Assert(CountDigits(value) == buffer.Length); - - for (int i = buffer.Length - 1; i >= 1; i--) - { - ulong temp = '0' + value; - value /= 10; - buffer[i] = (byte)(temp - (value * 10)); - } - - Debug.Assert(value < 10); - buffer[0] = (byte)('0' + value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteDigitsUInt64D(ulong value, Span buffer) - { - // We can mutate the 'value' parameter since it's a copy-by-value local. - // It'll be used to represent the value left over after each division by 10. - - Debug.Assert(CountDigits(value) == buffer.Length); - - for (int i = buffer.Length - 1; i >= 1; i--) - { - ulong temp = '0' + value; - value /= 10; - buffer[i] = (char)(temp - (value * 10)); - } - - Debug.Assert(value < 10); - buffer[0] = (char)('0' + value); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDigits(ulong value) { @@ -248,7 +187,7 @@ public unsafe static OperationStatus ToUtf8(ReadOnlySpan source, Span buffer) buffer[0] = (byte)('0' + value); } - // https://tools.ietf.org/html/rfc8259 - // Escape '"', '\', '/', and all control characters (i.e. 0 to 31) - // IndexOfAny(34, 47, 92, < 32) - // Borrowed and modified from SpanHelpers.Byte: - // https://github.com/dotnet/corefx/blob/fc169cddedb6820aaabbdb8b7bece2a3df0fd1a5/src/Common/src/CoreLib/System/SpanHelpers.Byte.cs#L473-L604 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int IndexOfAnyEscape(this ReadOnlySpan span) - { - return IndexOfAny( - ref MemoryMarshal.GetReference(span), - JsonConstants.Quote, - JsonConstants.Slash, - JsonConstants.BackSlash, - JsonConstants.Space, - span.Length); - } - - private static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, byte lessThan, int length) - { - Debug.Assert(length >= 0); - - uint uValue0 = value0; // Use uint for comparisons to avoid unnecessary 8->32 extensions - uint uValue1 = value1; // Use uint for comparisons to avoid unnecessary 8->32 extensions - uint uValue2 = value2; // Use uint for comparisons to avoid unnecessary 8->32 extensions - uint uLessThan = lessThan; // Use uint for comparisons to avoid unnecessary 8->32 extensions - IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations - IntPtr nLength = (IntPtr)length; - - if (Vector.IsHardwareAccelerated && length >= Vector.Count * 2) - { - int unaligned = (int)Unsafe.AsPointer(ref searchSpace) & (Vector.Count - 1); - nLength = (IntPtr)((Vector.Count - unaligned) & (Vector.Count - 1)); - } - SequentialScan: - uint lookUp; - while ((byte*)nLength >= (byte*)8) - { - nLength -= 8; - - lookUp = Unsafe.AddByteOffset(ref searchSpace, index); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 1); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found1; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 2); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found2; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 3); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found3; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 4); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found4; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 5); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found5; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 6); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found6; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 7); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found7; - - index += 8; - } - - if ((byte*)nLength >= (byte*)4) - { - nLength -= 4; - - lookUp = Unsafe.AddByteOffset(ref searchSpace, index); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 1); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found1; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 2); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found2; - lookUp = Unsafe.AddByteOffset(ref searchSpace, index + 3); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found3; - - index += 4; - } - - while ((byte*)nLength > (byte*)0) - { - nLength -= 1; - - lookUp = Unsafe.AddByteOffset(ref searchSpace, index); - if (uValue0 == lookUp || uValue1 == lookUp || uValue2 == lookUp || uLessThan > lookUp) - goto Found; - - index += 1; - } - - if (Vector.IsHardwareAccelerated && ((int)(byte*)index < length)) - { - nLength = (IntPtr)((length - (int)(byte*)index) & ~(Vector.Count - 1)); - - // Get comparison Vector - Vector values0 = new Vector(value0); - Vector values1 = new Vector(value1); - Vector values2 = new Vector(value2); - Vector valuesLessThan = new Vector(lessThan); - - while ((byte*)nLength > (byte*)index) - { - Vector vData = Unsafe.ReadUnaligned>(ref Unsafe.AddByteOffset(ref searchSpace, index)); - - var vMatches = Vector.BitwiseOr( - Vector.BitwiseOr( - Vector.BitwiseOr( - Vector.Equals(vData, values0), - Vector.Equals(vData, values1)), - Vector.Equals(vData, values2)), - Vector.LessThan(vData, valuesLessThan)); - - if (Vector.Zero.Equals(vMatches)) - { - index += Vector.Count; - continue; - } - // Find offset of first match - return (int)(byte*)index + LocateFirstFoundByte(vMatches); - } - - if ((int)(byte*)index < length) - { - nLength = (IntPtr)(length - (int)(byte*)index); - goto SequentialScan; - } - } - return -1; - Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549 - return (int)(byte*)index; - Found1: - return (int)(byte*)(index + 1); - Found2: - return (int)(byte*)(index + 2); - Found3: - return (int)(byte*)(index + 3); - Found4: - return (int)(byte*)(index + 4); - Found5: - return (int)(byte*)(index + 5); - Found6: - return (int)(byte*)(index + 6); - Found7: - return (int)(byte*)(index + 7); - } - - // Vector sub-search adapted from https://github.com/aspnet/KestrelHttpServer/pull/1138 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int LocateFirstFoundByte(Vector match) - { - var vector64 = Vector.AsVectorUInt64(match); - ulong candidate = 0; - int i = 0; - // Pattern unrolled by jit https://github.com/dotnet/coreclr/pull/8001 - for (; i < Vector.Count; i++) - { - candidate = vector64[i]; - if (candidate != 0) - { - break; - } - } - - // Single LEA instruction with jitted const (using function result) - return i * 8 + LocateFirstFoundByte(candidate); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int LocateFirstFoundByte(ulong match) - { - // Flag least significant power of two bit - var powerOfTwoFlag = match ^ (match - 1); - // Shift all powers of two into the high byte and extract - return (int)((powerOfTwoFlag * XorPowerOfTwoToHighByte) >> 57); - } - - private const ulong XorPowerOfTwoToHighByte = (0x07ul | - 0x06ul << 8 | - 0x05ul << 16 | - 0x04ul << 24 | - 0x03ul << 32 | - 0x02ul << 40 | - 0x01ul << 48) + 1; - [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe static int PtrDiff(char* a, char* b) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index bc4e0ee304e4..9de2a9536ad5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -42,7 +42,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); - + Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 6762109b2214..b05c41e25ae3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -297,7 +297,7 @@ private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) AdvanceAndGrow(idx); idx = 0; } - _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + _buffer[idx++] = JsonConstants.Asterisk; ReadOnlySpan byteSpan = MemoryMarshal.AsBytes(escapedValue); int partialConsumed = 0; @@ -319,7 +319,7 @@ private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) AdvanceAndGrow(idx); idx = 0; } - _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + _buffer[idx++] = JsonConstants.Asterisk; while (_buffer.Length <= idx) { @@ -343,7 +343,7 @@ private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) AdvanceAndGrow(idx); idx = 0; } - _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + _buffer[idx++] = JsonConstants.Asterisk; CopyLoop(ref escapedValue, ref idx); @@ -352,7 +352,7 @@ private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) AdvanceAndGrow(idx); idx = 0; } - _buffer[idx++] = (byte)'*'; // TODO: Replace with JsonConstants.Asterisk + _buffer[idx++] = JsonConstants.Asterisk; while (_buffer.Length <= idx) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 911a44b3193c..c0335316945c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -35,7 +35,7 @@ public void WriteNumberValue(long value) private void WriteNumberValueMinimized(long value) { // Calculated based on the following: ',long.MaxValue' - int bytesNeeded = JsonConstants.MaximumInt64Length + 1; + int bytesNeeded = JsonConstants.MaximumInt64Length + 1; if (_buffer.Length < bytesNeeded) { GrowAndEnsure(bytesNeeded); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 1f32f8f81a0e..eb8c9caed2d6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -5,7 +5,6 @@ using System.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; namespace System.Text.Json { @@ -13,7 +12,7 @@ public ref partial struct Utf8JsonWriter { private const int MinimumSizeThreshold = 256; - private IBufferWriter _output; + private readonly IBufferWriter _output; private int _buffered; private Span _buffer; @@ -84,38 +83,19 @@ private void Advance(int count) _buffer = _buffer.Slice(count); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void CheckSizeAndGrow(int count) - { - Debug.Assert(count >= 0); - - if (_buffer.Length < count) - GrowSpan(count); - } - [MethodImpl(MethodImplOptions.NoInlining)] private void GrowSpan(int count) { Flush(); - if (_output == null) + _buffer = _output.GetSpan(count); + + if (_buffer.Length < count && count < MinimumSizeThreshold) { - if (count < MinimumSizeThreshold) - { - throw new ArgumentException("The output span provided is too small."); - } + throw new ArgumentException("The IBufferWriter could not provide a span that is large enough to continue."); } - else - { - _buffer = _output.GetSpan(count); - - if (_buffer.Length < count && count < MinimumSizeThreshold) - { - throw new ArgumentException("The IBufferWriter could not provide a span that is large enough to continue."); - } - Debug.Assert(_buffer.Length >= Math.Min(count, MinimumSizeThreshold)); - } + Debug.Assert(_buffer.Length >= Math.Min(count, MinimumSizeThreshold)); } public void Flush(bool isFinalBlock = true) @@ -131,15 +111,7 @@ public void Flush(bool isFinalBlock = true) private void Flush() { BytesCommitted += _buffered; - if (_output == null) - { - Debug.Assert(_buffer.Length >= _buffered); - _buffer = _buffer.Slice(_buffered); - } - else - { - _output.Advance(_buffered); - } + _output.Advance(_buffered); _buffered = 0; } @@ -533,7 +505,7 @@ private void WriteEndMinimized(byte token) { GrowAndEnsure(); } - + _buffer[0] = token; Advance(1); } @@ -622,24 +594,6 @@ private void WriteEndIndented(byte token) } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Span GetSpan(int bytesNeeded) - { - CheckSizeAndGrow(bytesNeeded); - Debug.Assert(_buffer.Length >= bytesNeeded); - return _buffer; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteNewLine(ref Span byteBuffer, ref int idx) - { - // Write '\r\n' OR '\n', depending on OS - if (JsonWriterHelper.s_newLineUtf8.Length == 2) - byteBuffer[idx++] = JsonConstants.CarriageReturn; - - byteBuffer[idx++] = JsonConstants.LineFeed; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private void WriteNewLine(ref int idx) { @@ -738,23 +692,5 @@ private void CopyLoop(ref ReadOnlySpan span, ref int idx) idx = 0; } } - - private void CopyLoop(ReadOnlySpan span, ref int idx) - { - while (true) - { - if (span.Length <= _buffer.Length - idx) - { - span.CopyTo(_buffer.Slice(idx)); - idx += span.Length; - break; - } - - span.Slice(0, _buffer.Length - idx).CopyTo(_buffer.Slice(idx)); - span = span.Slice(_buffer.Length - idx); - AdvanceAndGrow(_buffer.Length); - idx = 0; - } - } } } From 39fc64d3b83cbeec378b4d82ef1eafa2265e8d61 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 03:50:34 -0800 Subject: [PATCH 06/33] Make use of self-descriptive constants where possible. --- .../src/System/Text/Json/JsonConstants.cs | 10 +-- .../Json/Writer/JsonWriterHelper.Escaping.cs | 46 ++++++------- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 12 ++-- ...onWriter.WriteProperties.DateTimeOffset.cs | 12 ++-- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 12 ++-- .../Utf8JsonWriter.WriteProperties.Double.cs | 12 ++-- .../Utf8JsonWriter.WriteProperties.Float.cs | 12 ++-- .../Utf8JsonWriter.WriteProperties.Guid.cs | 12 ++-- .../Utf8JsonWriter.WriteProperties.Literal.cs | 12 ++-- ...JsonWriter.WriteProperties.SignedNumber.cs | 12 ++-- .../Utf8JsonWriter.WriteProperties.String.cs | 64 +++++++++---------- ...onWriter.WriteProperties.UnsignedNumber.cs | 12 ++-- .../Utf8JsonWriter.WriteValues.Comment.cs | 12 ++-- .../Utf8JsonWriter.WriteValues.String.cs | 12 ++-- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 28 ++++---- 15 files changed, 143 insertions(+), 137 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 8a269ed3454e..4fbff3bb0877 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -30,10 +30,6 @@ internal static class JsonConstants // Used to search for the end of a number public static ReadOnlySpan Delimiters => new byte[] { ListSeperator, CloseBrace, CloseBracket, Space, LineFeed, CarriageReturn, Tab, Slash }; - public static ReadOnlySpan WhiteSpace => new byte[] { Space, LineFeed, CarriageReturn, Tab }; - - public static ReadOnlySpan EndOfComment => new byte[] { Asterisk, Slash }; - // Explicitly skipping ReverseSolidus since that is handled separately public static ReadOnlySpan EscapableChars => new byte[] { Quote, (byte)'n', (byte)'r', (byte)'t', Slash, (byte)'u', (byte)'b', (byte)'f' }; @@ -56,5 +52,11 @@ internal static class JsonConstants public const char HighSurrogateEnd = '\udbff'; public const char LowSurrogateStart = '\udc00'; public const char LowSurrogateEnd = '\udfff'; + + public const int UnicodePlan01StartValue = 0x10000; + public const int HighSurrogateStartValue = 0xD800; + public const int HighSurrogateEndValue = 0xDBFF; + public const int LowSurrogateStartValue = 0xDC00; + public const int LowSurrogateEndValue = 0xDFFF; } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 1792fee1ec5b..f1390891eb86 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -15,7 +15,7 @@ internal static partial class JsonWriterHelper // and exclude characters that need to be escaped by adding a backslash: '\n', '\r', '\t', '\\', '/', '\b', '\f' // // non-zero = allowed, 0 = disallowed - private static ReadOnlySpan AllowList => new byte[256] { + private static ReadOnlySpan AllowList => new byte[byte.MaxValue + 1] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, @@ -38,7 +38,7 @@ internal static partial class JsonWriterHelper private static bool NeedsEscaping(byte value) => AllowList[value] == 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool NeedsEscaping(char value) => value > 255 || AllowList[value] == 0; + private static bool NeedsEscaping(char value) => value > byte.MaxValue || AllowList[value] == 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int NeedsEscaping(ReadOnlySpan value) @@ -110,38 +110,38 @@ private static int EscapeNextBytes(ReadOnlySpan value, ref Span dest int scalar = unicodeScalar.Value; switch (scalar) { - case '\n': + case JsonConstants.LineFeed: destination[written++] = (byte)'n'; break; - case '\r': + case JsonConstants.CarriageReturn: destination[written++] = (byte)'r'; break; - case '\t': + case JsonConstants.Tab: destination[written++] = (byte)'t'; break; - case '\\': + case JsonConstants.BackSlash: destination[written++] = (byte)'\\'; break; - case '/': + case JsonConstants.Slash: destination[written++] = (byte)'/'; break; - case '\b': + case JsonConstants.BackSpace: destination[written++] = (byte)'b'; break; - case '\f': + case JsonConstants.FormFeed: destination[written++] = (byte)'f'; break; default: destination[written++] = (byte)'u'; - if (scalar < 0x10000) + if (scalar < JsonConstants.UnicodePlan01StartValue) { WriteHex(scalar, ref destination, ref written); } else { - int quotient = DivMod(scalar - 0x10000, 0x400, out int remainder); - int firstChar = quotient + 0xD800; - int nextChar = remainder + 0xDC00; + int quotient = DivMod(scalar - JsonConstants.UnicodePlan01StartValue, 0x400, out int remainder); + int firstChar = quotient + JsonConstants.HighSurrogateStartValue; + int nextChar = remainder + JsonConstants.LowSurrogateStartValue; WriteHex(firstChar, ref destination, ref written); destination[written++] = (byte)'\\'; destination[written++] = (byte)'u'; @@ -401,16 +401,16 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, ref Span destination, ref int consumed, ref int written) { int nextChar = -1; - if (InRange(firstChar, 0xD800, 0xDFFF)) + if (InRange(firstChar, JsonConstants.HighSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) { consumed++; - if (value.Length <= consumed || firstChar >= 0xDC00) + if (value.Length <= consumed || firstChar >= JsonConstants.LowSurrogateStartValue) { ThrowHelper.ThrowJsonWriterException("Invalid UTF-16 string ending in an invalid surrogate pair."); } nextChar = value[consumed]; - if (!InRange(nextChar, 0xDC00, 0xDFFF)) + if (!InRange(nextChar, JsonConstants.LowSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) { ThrowHelper.ThrowJsonWriterException("Invalid UTF-16 string ending in an invalid surrogate pair."); } @@ -419,25 +419,25 @@ private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, destination[written++] = '\\'; switch (firstChar) { - case '\n': + case JsonConstants.LineFeed: destination[written++] = 'n'; break; - case '\r': + case JsonConstants.CarriageReturn: destination[written++] = 'r'; break; - case '\t': + case JsonConstants.Tab: destination[written++] = 't'; break; - case '\\': + case JsonConstants.BackSlash: destination[written++] = '\\'; break; - case '/': + case JsonConstants.Slash: destination[written++] = '/'; break; - case '\b': + case JsonConstants.BackSpace: destination[written++] = 'b'; break; - case '\f': + case JsonConstants.FormFeed: destination[written++] = 'f'; break; default: diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 9ff923dd7d1c..0f5b0451566f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -73,13 +73,13 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -104,13 +104,13 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 5025a91c20f1..10cd7c4f0a9f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -73,13 +73,13 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -104,13 +104,13 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 46a24121e8fb..f9a680e45e68 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -73,13 +73,13 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decim private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -104,13 +104,13 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 476f75f66994..039bcf318bb3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -73,13 +73,13 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, doubl private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -104,13 +104,13 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index aae5e1915097..25a5951c89f9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -73,13 +73,13 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -104,13 +104,13 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 9de2a9536ad5..6d908154f0a9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -73,13 +73,13 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -104,13 +104,13 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index cf2e6eb0d951..046610e87188 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -109,13 +109,13 @@ private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -140,13 +140,13 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index f65f25461101..096ed7ccbbd3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -81,13 +81,13 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -112,13 +112,13 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index baeee86e4ae4..8623dfdde02a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -136,9 +136,9 @@ private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -150,9 +150,9 @@ private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyNa private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -164,9 +164,9 @@ private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyNa private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -178,9 +178,9 @@ private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyNa private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + 6 * (value.Length - firstEscapeIndex)); + char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -268,18 +268,18 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref R private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] valueArray = null; char[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; @@ -299,9 +299,9 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -330,18 +330,18 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] valueArray = null; byte[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; @@ -361,9 +361,9 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -392,18 +392,18 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] valueArray = null; char[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; @@ -423,9 +423,9 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -454,18 +454,18 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] valueArray = null; byte[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; @@ -485,9 +485,9 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 05b21443e6fa..6b6dba100530 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -87,13 +87,13 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -118,13 +118,13 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index b05c41e25ae3..113a56802a87 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -115,16 +115,16 @@ private void WriteCommentIndented(ref ReadOnlySpan escapedValue) private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); char[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; @@ -250,16 +250,16 @@ private void WriteCommentIndented(ref ReadOnlySpan escapedValue) private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); byte[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 7cb27f53c904..f17cec65282c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -114,16 +114,16 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); char[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; @@ -249,16 +249,16 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / 6 >= value.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); byte[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + 6 * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; - if (length > 256) + if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); span = valueArray; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index eb8c9caed2d6..759e95b2489d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -11,6 +11,10 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { private const int MinimumSizeThreshold = 256; + private const int StackallocThreshold = 256; + private const int MaxExpansionFactorWhileEscaping = 6; + private const int SpacesPerIndent = 2; + private const int DefaultGrowthSize = 4096; private readonly IBufferWriter _output; private int _buffered; @@ -38,7 +42,7 @@ public long BytesWritten // else, no list separator is needed since we are writing the first item. private int _currentDepth; - private int Indentation => CurrentDepth * 2; + private int Indentation => CurrentDepth * SpacesPerIndent; public int CurrentDepth => _currentDepth & JsonConstants.RemoveFlagsBitMask; @@ -324,13 +328,13 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -440,13 +444,13 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / 6 >= propertyName.Length); + Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + 6 * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; - if (length > 256) + if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); span = propertyArray; @@ -635,10 +639,10 @@ private void UpdateBitStackOnStart(byte token) private void GrowAndEnsure() { int previousSpanLength = _buffer.Length; - GrowSpan(4096); + GrowSpan(DefaultGrowthSize); if (_buffer.Length <= previousSpanLength) { - GrowSpan(4096); + GrowSpan(DefaultGrowthSize); if (_buffer.Length <= previousSpanLength) { //TODO: Use Throwhelper and fix message. @@ -649,10 +653,10 @@ private void GrowAndEnsure() private void GrowAndEnsure(int minimumSize) { - GrowSpan(4096); + GrowSpan(DefaultGrowthSize); if (_buffer.Length <= minimumSize) { - GrowSpan(4096); + GrowSpan(DefaultGrowthSize); if (_buffer.Length <= minimumSize) { //TODO: Use Throwhelper and fix message. @@ -670,7 +674,7 @@ private void AdvanceAndGrow(int alreadyWritten) private void AdvanceAndGrow(int alreadyWritten, int minimumSize) { - Debug.Assert(minimumSize > 6 && minimumSize <= 128); + Debug.Assert(minimumSize >= 1 && minimumSize <= 128); Advance(alreadyWritten); GrowAndEnsure(minimumSize); } From 41b7b2cc82a4766164175412be98bdcb17a23e25 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 17:27:11 -0800 Subject: [PATCH 07/33] Fix leftover TODOs and update throw helper/exception messages. --- .../src/Resources/Strings.resx | 36 +++ .../src/System/Text/Json/ThrowHelper.cs | 219 +++++++++++------- .../Json/Writer/JsonWriterHelper.Escaping.cs | 6 +- .../Text/Json/Writer/JsonWriterHelper.cs | 16 +- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 4 +- .../Utf8JsonWriter.WriteValues.Helpers.cs | 4 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 57 ++--- 7 files changed, 200 insertions(+), 142 deletions(-) diff --git a/src/System.Text.Json/src/Resources/Strings.resx b/src/System.Text.Json/src/Resources/Strings.resx index c1c47799045b..ef23fa929761 100644 --- a/src/System.Text.Json/src/Resources/Strings.resx +++ b/src/System.Text.Json/src/Resources/Strings.resx @@ -120,6 +120,30 @@ CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON array. + + Cannot write the start of an object or array after a single JSON value. Current token type is '{0}'. + + + Cannot write the start of an object or array without a property name. Current token type is '{0}'. + + + Cannot write invalid UTF-16 text as JSON. Invalid surrogate pair: '{0}'. + + + Cannot write invalid UTF-8 text as JSON. Invalid input: '{0}'. + + + Cannot write a JSON property within an array or as the first JSON token. Current token type is '{0}'. + + + Cannot write a JSON value after a single JSON value. Current token type is '{0}'. + + + Cannot write a JSON value within an object without a property name. Current token type is '{0}'. + + + CurrentDepth ({0}) is equal to or larger than the maximum allowed depth of 1000. Cannot write the next JSON object or array. + Expected end of comment, but instead reached end of data. @@ -159,6 +183,12 @@ Expected a value, but instead reached end of data. + + The 'IBufferWriter' could not provide an output buffer that is large enough to continue writing. + + + The 'IBufferWriter' could not provide an output buffer that is large enough to continue writing. Need at least {0} bytes. + '{0}' is invalid after a value. Expected either ',', '}}', or ']'. @@ -186,6 +216,9 @@ CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON object. + + The JSON property name of length {0} is too large and not supported by the JSON writer. + '{0}' is invalid within a number, immediately after a decimal point ('.'). Expected a digit ('0'-'9'). @@ -195,6 +228,9 @@ Expected a digit ('0'-'9'), but instead reached end of data. + + The JSON value of length {0} is too large and not supported by the JSON writer. + Expected CurrentDepth ({0}) to be zero at the end of the JSON payload. There is an open JSON object or array that should be closed. diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index 6168adf16225..d27ba4bc1f59 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -25,117 +25,129 @@ public static void ThrowArgumentException(string message) throw GetArgumentException(message); } - public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength) { - GetArgumentException(propertyName, value); + throw GetArgumentException(SR.Format(SR.PropertyNameTooLarge, tokenLength)); } - public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException_ValueTooLarge(int tokenLength) { - GetArgumentException(propertyName, value); + throw GetArgumentException(SR.Format(SR.ValueTooLarge, tokenLength)); } - public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) - { - GetArgumentException(propertyName, value); - } - - public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException(ExceptionResource resource, int minimumSize = 0) { - GetArgumentException(propertyName, value); + if (resource == ExceptionResource.FailedToGetLargerSpan) + { + throw GetArgumentException(SR.FailedToGetLargerSpan); + } + else + { + Debug.Assert(resource == ExceptionResource.FailedToGetMinimumSizeSpan); + throw GetArgumentException(SR.Format(SR.FailedToGetMinimumSizeSpan, minimumSize)); + } } - [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxTokenSize) { - ThrowArgumentException("propertyName too large"); + ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length)); } else { Debug.Assert(value.Length > JsonConstants.MaxTokenSize); - ThrowArgumentException("value too large"); + ThrowArgumentException(SR.Format(SR.ValueTooLarge, value.Length)); } } - [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxTokenSize) { - ThrowArgumentException("propertyName too large"); + ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length)); } else { Debug.Assert(value.Length > JsonConstants.MaxCharacterTokenSize); - ThrowArgumentException("value too large"); + ThrowArgumentException(SR.Format(SR.ValueTooLarge, value.Length)); } } - [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) { - ThrowArgumentException("propertyName too large"); + ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length)); } else { Debug.Assert(value.Length > JsonConstants.MaxTokenSize); - ThrowArgumentException("value too large"); + ThrowArgumentException(SR.Format(SR.ValueTooLarge, value.Length)); } } - [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) + public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) { - ThrowArgumentException("propertyName too large"); + ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length)); } else { Debug.Assert(value.Length > JsonConstants.MaxCharacterTokenSize); - ThrowArgumentException("value too large"); + ThrowArgumentException(SR.Format(SR.ValueTooLarge, value.Length)); } } - public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { - GetJsonWriterOrArgumentException(propertyName, indent); + GetJsonWriterOrArgumentException(propertyName, currentDepth); + } + + public static void ThrowJsonWriterException(string message) + { + throw GetJsonWriterException(message); } [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + private static JsonWriterException GetJsonWriterException(string message) { - if ((indent & JsonConstants.RemoveFlagsBitMask) >= JsonConstants.MaxWriterDepth) + return new JsonWriterException(message); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) + { + currentDepth &= JsonConstants.RemoveFlagsBitMask; + if (currentDepth >= JsonConstants.MaxWriterDepth) { - ThrowJsonWriterException("Depth too large."); + ThrowJsonWriterException(SR.Format(SR.DepthTooLarge, currentDepth)); } else { Debug.Assert(propertyName.Length > JsonConstants.MaxCharacterTokenSize); - ThrowArgumentException("Argument too large."); + ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length)); } } - public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { - GetJsonWriterOrArgumentException(propertyName, indent); + GetJsonWriterOrArgumentException(propertyName, currentDepth); } [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int indent) + private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { - if ((indent & JsonConstants.RemoveFlagsBitMask) >= JsonConstants.MaxWriterDepth) + currentDepth &= JsonConstants.RemoveFlagsBitMask; + if (currentDepth >= JsonConstants.MaxWriterDepth) { - ThrowJsonWriterException("Depth too large."); + ThrowJsonWriterException(SR.Format(SR.DepthTooLarge, currentDepth)); } else { Debug.Assert(propertyName.Length > JsonConstants.MaxCharacterTokenSize); - ThrowArgumentException("Argument too large."); + ThrowArgumentException(SR.Format(SR.PropertyNameTooLarge, propertyName.Length)); } } @@ -160,52 +172,6 @@ private static InvalidOperationException GetInvalidOperationException(string mes return new InvalidOperationException(SR.Format(SR.InvalidCast, tokenType, message)); } - public static void ThrowJsonWriterException(string message) - { - throw GetJsonWriterException(message); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static JsonWriterException GetJsonWriterException(string message) - { - return new JsonWriterException(message); - } - - public static void ThrowJsonWriterException(byte token) - { - throw GetJsonWriterException(token); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static JsonWriterException GetJsonWriterException(byte token) - { - return new JsonWriterException(token.ToString()); - } - - public static void ThrowJsonWriterException(byte token, JsonTokenType tokenType) - { - throw GetJsonWriterException(token, tokenType); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static JsonWriterException GetJsonWriterException(byte token, JsonTokenType tokenType) - { - // TODO: Fix exception message - return new JsonWriterException(token.ToString()); - } - - public static void ThrowJsonWriterException(JsonTokenType tokenType) - { - throw GetJsonWriterException(tokenType); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static JsonWriterException GetJsonWriterException(JsonTokenType tokenType) - { - // TODO: Fix exception message - return new JsonWriterException(""); - } - public static void ThrowJsonReaderException(ref Utf8JsonReader json, ExceptionResource resource, byte nextByte = default, ReadOnlySpan bytes = default) { throw GetJsonReaderException(ref json, resource, nextByte, bytes); @@ -316,6 +282,81 @@ private static string GetResourceString(ref Utf8JsonReader json, ExceptionResour return message; } + + public static void ThrowJsonWriterException(ExceptionResource resource, int currentDepth = default, byte token = default, JsonTokenType tokenType = default) + { + throw GetJsonReaderException(resource, currentDepth, token, tokenType); + } + + public static void ThrowJsonWriterException_InvalidUTF8(ReadOnlySpan value) + { + var builder = new StringBuilder(); + + int printFirst10 = Math.Min(value.Length, 10); + + for (int i = 0; i < printFirst10; i++) + { + byte nextByte = value[i]; + if (IsPrintable(nextByte)) + { + builder.Append((char)nextByte); + } + else + { + builder.Append($"0x{nextByte:X2}"); + } + } + + throw new JsonWriterException(SR.Format(SR.CannotWriteInvalidUTF8, builder.ToString())); + } + + public static void ThrowJsonWriterException_InvalidUTF16(int charAsInt) + { + throw new JsonWriterException(SR.Format(SR.CannotWriteInvalidUTF16, $"0x{charAsInt:X2}")); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static JsonWriterException GetJsonReaderException(ExceptionResource resource, int currentDepth, byte token, JsonTokenType tokenType) + { + string message = GetResourceString(resource, currentDepth, token, tokenType); + return new JsonWriterException(message); + } + + // This function will convert an ExceptionResource enum value to the resource string. + [MethodImpl(MethodImplOptions.NoInlining)] + private static string GetResourceString(ExceptionResource resource, int currentDepth, byte token, JsonTokenType tokenType) + { + string message = ""; + switch (resource) + { + case ExceptionResource.MismatchedObjectArray: + message = SR.Format(SR.MismatchedObjectArray, token); + break; + case ExceptionResource.DepthTooLarge: + message = SR.Format(SR.DepthTooLarge, currentDepth & JsonConstants.RemoveFlagsBitMask); + break; + case ExceptionResource.ZeroDepthAtEnd: + message = SR.Format(SR.ZeroDepthAtEnd, currentDepth & JsonConstants.RemoveFlagsBitMask); + break; + case ExceptionResource.CannotStartObjectArrayWithoutProperty: + message = SR.Format(SR.CannotStartObjectArrayWithoutProperty, tokenType); + break; + case ExceptionResource.CannotStartObjectArrayAfterPrimitive: + message = SR.Format(SR.CannotStartObjectArrayAfterPrimitive, tokenType); + break; + case ExceptionResource.CannotWriteValueWithinObject: + message = SR.Format(SR.CannotWriteValueWithinObject, tokenType); + break; + case ExceptionResource.CannotWriteValueAfterPrimitive: + message = SR.Format(SR.CannotWriteValueAfterPrimitive, tokenType); + break; + default: + Debug.Fail($"The ExceptionResource enum value: {resource} is not part of the switch. Add the appropriate case and exception message."); + break; + } + + return message; + } } internal enum ExceptionResource @@ -345,5 +386,13 @@ internal enum ExceptionResource MismatchedObjectArray, ObjectDepthTooLarge, ZeroDepthAtEnd, + DepthTooLarge, + CannotStartObjectArrayWithoutProperty, + CannotStartObjectArrayAfterPrimitive, + CannotWriteValueWithinObject, + CannotWriteValueAfterPrimitive, + FailedToGetMinimumSizeSpan, + FailedToGetLargerSpan, + CannotWritePropertyWithinArray, } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index f1390891eb86..9f2a133763c4 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -104,7 +104,7 @@ private static int EscapeNextBytes(ReadOnlySpan value, ref Span dest { SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out UnicodeScalar unicodeScalar); if (status != SequenceValidity.WellFormed) - ThrowHelper.ThrowJsonWriterException("Invalid UTF-8 string."); + ThrowHelper.ThrowJsonWriterException_InvalidUTF8(value); destination[written++] = (byte)'\\'; int scalar = unicodeScalar.Value; @@ -406,13 +406,13 @@ private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, consumed++; if (value.Length <= consumed || firstChar >= JsonConstants.LowSurrogateStartValue) { - ThrowHelper.ThrowJsonWriterException("Invalid UTF-16 string ending in an invalid surrogate pair."); + ThrowHelper.ThrowJsonWriterException_InvalidUTF16(firstChar); } nextChar = value[consumed]; if (!InRange(nextChar, JsonConstants.LowSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) { - ThrowHelper.ThrowJsonWriterException("Invalid UTF-16 string ending in an invalid surrogate pair."); + ThrowHelper.ThrowJsonWriterException_InvalidUTF16(nextChar); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 36541e3bf93f..6a5525568a37 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -52,39 +52,34 @@ public static bool TryWriteIndentation(Span buffer, int indent, out int by [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateProperty(ref ReadOnlySpan propertyName) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxTokenSize) - ThrowHelper.ThrowArgumentException("Argument too large."); + ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateValue(ref ReadOnlySpan value) { - // TODO: Use throw helper with proper error messages if (value.Length > JsonConstants.MaxTokenSize) - ThrowHelper.ThrowArgumentException("Argument too large."); + ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateProperty(ref ReadOnlySpan propertyName) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) - ThrowHelper.ThrowArgumentException("Argument too large."); + ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateValue(ref ReadOnlySpan value) { - // TODO: Use throw helper with proper error messages if (value.Length > JsonConstants.MaxCharacterTokenSize) - ThrowHelper.ThrowArgumentException("Argument too large."); + ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } @@ -92,7 +87,6 @@ public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } @@ -100,7 +94,6 @@ public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } @@ -108,7 +101,6 @@ public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index dddc1e2dc2a5..4c5429badcd0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -14,7 +14,6 @@ public ref partial struct Utf8JsonWriter [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowJsonWriterOrArgumentException(propertyName, _currentDepth); } @@ -22,7 +21,6 @@ private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) { - // TODO: Use throw helper with proper error messages if (propertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowJsonWriterOrArgumentException(propertyName, _currentDepth); } @@ -32,7 +30,7 @@ private void ValidateWritingProperty() if (!_inObject) { Debug.Assert(_tokenType != JsonTokenType.StartObject); - ThrowHelper.ThrowJsonWriterException("Cannot add a property within an array or as the first JSON token."); //TODO: Add resouce message + ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotWritePropertyWithinArray, tokenType: _tokenType); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs index 26bb39ddc191..7ca5f91abcdb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -13,13 +13,13 @@ private void ValidateWritingValue() if (_inObject) { Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); - ThrowHelper.ThrowJsonWriterException(_tokenType); //TODO: Add resource message + ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotWriteValueWithinObject, tokenType: _tokenType); } else { if (!_isNotPrimitive && _tokenType != JsonTokenType.None) { - ThrowHelper.ThrowJsonWriterException(_tokenType); //TODO: Add resource message + ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotWriteValueAfterPrimitive, tokenType: _tokenType); } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 759e95b2489d..322074180cd1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -87,26 +87,10 @@ private void Advance(int count) _buffer = _buffer.Slice(count); } - [MethodImpl(MethodImplOptions.NoInlining)] - private void GrowSpan(int count) - { - Flush(); - - _buffer = _output.GetSpan(count); - - if (_buffer.Length < count && count < MinimumSizeThreshold) - { - throw new ArgumentException("The IBufferWriter could not provide a span that is large enough to continue."); - } - - Debug.Assert(_buffer.Length >= Math.Min(count, MinimumSizeThreshold)); - } - public void Flush(bool isFinalBlock = true) { - //TODO: Fix exception message and check other potential conditions for invalid end. if (isFinalBlock && !_writerOptions.SkipValidation && CurrentDepth != 0) - ThrowHelper.ThrowJsonWriterException("Invalid end of JSON."); + ThrowHelper.ThrowJsonWriterException(ExceptionResource.ZeroDepthAtEnd, _currentDepth); Flush(); } @@ -133,9 +117,8 @@ public void WriteStartObject() private void WriteStart(byte token) { - // TODO: Use throw helper with proper error messages if (CurrentDepth >= JsonConstants.MaxWriterDepth) - ThrowHelper.ThrowJsonWriterException("Depth too large."); + ThrowHelper.ThrowJsonWriterException(ExceptionResource.DepthTooLarge, _currentDepth); if (_writerOptions.SlowPath) WriteStartSlow(token); @@ -177,7 +160,7 @@ private void WriteStartSlow(byte token) { if (!_writerOptions.SkipValidation) { - ValidateStart(token); + ValidateStart(); UpdateBitStackOnStart(token); } WriteStartIndented(token); @@ -185,25 +168,25 @@ private void WriteStartSlow(byte token) else { Debug.Assert(!_writerOptions.SkipValidation); - ValidateStart(token); + ValidateStart(); UpdateBitStackOnStart(token); WriteStartMinimized(token); } } - private void ValidateStart(byte token) + private void ValidateStart() { if (_inObject) { Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); - ThrowHelper.ThrowJsonWriterException(token, _tokenType); + ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotStartObjectArrayWithoutProperty, tokenType: _tokenType); } else { Debug.Assert(_tokenType != JsonTokenType.StartObject); if (_tokenType != JsonTokenType.None && !_isNotPrimitive) { - ThrowHelper.ThrowJsonWriterException(token, _tokenType); + ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotStartObjectArrayAfterPrimitive, tokenType: _tokenType); } } } @@ -537,14 +520,14 @@ private void WriteEndSlow(byte token) private void ValidateEnd(byte token) { if (_bitStack.CurrentDepth <= 0) - ThrowHelper.ThrowJsonWriterException(token); //TODO: Add resource message + ThrowHelper.ThrowJsonWriterException(ExceptionResource.MismatchedObjectArray, token); if (token == JsonConstants.CloseBracket) { if (_inObject) { Debug.Assert(_tokenType != JsonTokenType.None); - ThrowHelper.ThrowJsonWriterException(token); //TODO: Add resource message + ThrowHelper.ThrowJsonWriterException(ExceptionResource.MismatchedObjectArray, token); } } else @@ -553,7 +536,7 @@ private void ValidateEnd(byte token) if (!_inObject) { - ThrowHelper.ThrowJsonWriterException(token); //TODO: Add resource message + ThrowHelper.ThrowJsonWriterException(ExceptionResource.MismatchedObjectArray, token); } } @@ -638,29 +621,29 @@ private void UpdateBitStackOnStart(byte token) private void GrowAndEnsure() { + Flush(); int previousSpanLength = _buffer.Length; - GrowSpan(DefaultGrowthSize); + _buffer = _output.GetSpan(DefaultGrowthSize); if (_buffer.Length <= previousSpanLength) { - GrowSpan(DefaultGrowthSize); + _buffer = _output.GetSpan(DefaultGrowthSize); if (_buffer.Length <= previousSpanLength) { - //TODO: Use Throwhelper and fix message. - throw new OutOfMemoryException("Failed to get a larger buffer when growing."); + ThrowHelper.ThrowArgumentException(ExceptionResource.FailedToGetLargerSpan); } } } private void GrowAndEnsure(int minimumSize) { - GrowSpan(DefaultGrowthSize); - if (_buffer.Length <= minimumSize) + Flush(); + _buffer = _output.GetSpan(DefaultGrowthSize); + if (_buffer.Length < minimumSize) { - GrowSpan(DefaultGrowthSize); - if (_buffer.Length <= minimumSize) + _buffer = _output.GetSpan(DefaultGrowthSize); + if (_buffer.Length < minimumSize) { - //TODO: Use Throwhelper and fix message. - throw new OutOfMemoryException("Failed to get buffer larger than minimumSize when growing."); + ThrowHelper.ThrowArgumentException(ExceptionResource.FailedToGetMinimumSizeSpan, minimumSize); } } } From 798844477b7afc28906fa3d811293953418664b0 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 7 Jan 2019 19:16:52 -0800 Subject: [PATCH 08/33] Add xml comments/docs to the public surface area. --- .../Text/Json/Writer/JsonWriterOptions.cs | 17 ++ .../Text/Json/Writer/JsonWriterState.cs | 33 ++++ ...Utf8JsonWriter.WriteProperties.DateTime.cs | 36 ++++ ...onWriter.WriteProperties.DateTimeOffset.cs | 40 ++++- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 36 ++++ .../Utf8JsonWriter.WriteProperties.Double.cs | 36 ++++ .../Utf8JsonWriter.WriteProperties.Float.cs | 36 ++++ .../Utf8JsonWriter.WriteProperties.Guid.cs | 36 ++++ .../Utf8JsonWriter.WriteProperties.Literal.cs | 69 ++++++++ ...JsonWriter.WriteProperties.SignedNumber.cs | 72 ++++++++ .../Utf8JsonWriter.WriteProperties.String.cs | 117 +++++++++++++ ...onWriter.WriteProperties.UnsignedNumber.cs | 72 ++++++++ .../Utf8JsonWriter.WriteValues.Comment.cs | 40 +++-- .../Utf8JsonWriter.WriteValues.DateTime.cs | 7 + ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 7 + .../Utf8JsonWriter.WriteValues.Decimal.cs | 7 + .../Utf8JsonWriter.WriteValues.Double.cs | 7 + .../Utf8JsonWriter.WriteValues.Float.cs | 7 + .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 7 + .../Utf8JsonWriter.WriteValues.Literal.cs | 13 ++ ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 14 ++ .../Utf8JsonWriter.WriteValues.String.cs | 33 ++++ ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 14 ++ .../System/Text/Json/Writer/Utf8JsonWriter.cs | 154 +++++++++++++++++- 24 files changed, 888 insertions(+), 22 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 32a664f0b12f..3596bf683fd5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -4,10 +4,21 @@ namespace System.Text.Json { + /// + /// Provides the ability for the user to define custom behavior when writing JSON + /// using the . By default, the JSON is written without + /// any indentation or extra white space. Also, the will + /// throw an exception if the user attempts to write structurally invalid JSON. + /// public struct JsonWriterOptions { private int _optionsMask; + /// + /// 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. + /// public bool Indented { get @@ -23,6 +34,12 @@ public bool Indented } } + /// + /// Defines whether the should skip structural validation and allow + /// the user to write invalid JSON. For example, if the user attempts to write a value within an object + /// without a property name, a is thrown. If the JSON being written is known to be correct + /// then skipping validation could improve performance. + /// public bool SkipValidation { get diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs index dd68d8d3f7a9..4b98dfff28d0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs @@ -4,6 +4,14 @@ namespace System.Text.Json { + /// + /// Defines an opaque type that holds and saves all the relevant state information which must be provided + /// to the to continue writing after completing a partial write. + /// This type is required to support reentrancy when writing incomplete data, and to continue + /// writing in chunks. Unlike the , which is a ref struct, + /// this type can survive across async/await boundaries and hence this type is required to provide + /// support for writing more JSON text asynchronously before continuing with a new instance of the . + /// public struct JsonWriterState { internal long _bytesWritten; @@ -14,10 +22,30 @@ public struct JsonWriterState internal JsonWriterOptions _writerOptions; internal BitStack _bitStack; + /// + /// Returns the total amount of bytes written by the so far. + /// This includes data that has been written beyond what has already been committed. + /// public long BytesWritten => _bytesWritten; + /// + /// Returns the total amount of bytes committed to the output by the so far. + /// This is how much the IBufferWriter has advanced. + /// public long BytesCommitted => _bytesCommitted; + /// + /// Constructs a new instance. + /// + /// Defines the customized behavior of the + /// By default, the writes JSON minimized (i.e. with no extra whitespace) + /// and validates that the JSON being written is structurally valid according to JSON RFC. + /// + /// An instance of this state must be passed to the ctor with the output destination. + /// Unlike the , which is a ref struct, the state can survive + /// across async/await boundaries and hence this type is required to provide support for reading + /// in more data asynchronously before continuing with a new instance of the . + /// public JsonWriterState(JsonWriterOptions options = default) { _bytesWritten = default; @@ -32,6 +60,11 @@ public JsonWriterState(JsonWriterOptions options = default) _bitStack = default; } + /// + /// Gets the custom behavior when writing JSON using + /// the which indicates whether to format the output + /// while writing and whether to skip structural JSON validation or not. + /// public JsonWriterOptions Options => _writerOptions; } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 0f5b0451566f..c800aceb8dc5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -10,9 +10,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -26,6 +50,18 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su _tokenType = JsonTokenType.String; } + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 10cd7c4f0a9f..6b4a02fd3916 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -10,9 +10,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value, suppressEscaping); - + => WriteString(propertyName.AsSpan(), value, suppressEscaping); + + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -26,6 +50,18 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b _tokenType = JsonTokenType.String; } + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index f9a680e45e68..220fa87a4f89 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -10,9 +10,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -26,6 +50,18 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 039bcf318bb3..437d57c56e15 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -10,9 +10,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -26,6 +50,18 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 25a5951c89f9..95adad643ea2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -10,9 +10,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -26,6 +50,18 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 6d908154f0a9..b5ee35572a01 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -10,9 +10,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -26,6 +50,18 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre _tokenType = JsonTokenType.String; } + /// + /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 046610e87188..9e5869f32138 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -9,9 +9,31 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNull(string propertyName, bool suppressEscaping = false) => WriteNull(propertyName.AsSpan(), suppressEscaping); + /// + /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -27,6 +49,17 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f _tokenType = JsonTokenType.Null; } + /// + /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -42,9 +75,33 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f _tokenType = JsonTokenType.Null; } + /// + /// Writes the property name and value (as a JSON literal "true" or "false") as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) => WriteBoolean(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON literal "true" or "false") as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -60,6 +117,18 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr _tokenType = value ? JsonTokenType.True : JsonTokenType.False; } + /// + /// Writes the property name and value (as a JSON literal "true" or "false") as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 096ed7ccbbd3..1a5621b1ec41 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -9,9 +9,33 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -25,6 +49,18 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); @@ -38,12 +74,48 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), (long)value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName, (long)value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName, (long)value, suppressEscaping); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 8623dfdde02a..ea4ca27894c6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -11,9 +11,35 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(string propertyName, string value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value.AsSpan(), suppressEscaping); + /// + /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); @@ -27,6 +53,19 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu _tokenType = JsonTokenType.String; } + /// + /// Writes the UTF-8 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); @@ -40,9 +79,35 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu _tokenType = JsonTokenType.String; } + /// + /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the UTF-8 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); @@ -56,9 +121,35 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu _tokenType = JsonTokenType.String; } + /// + /// Writes the UTF-16 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the UTF-16 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); @@ -72,9 +163,35 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu _tokenType = JsonTokenType.String; } + /// + /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) => WriteString(propertyName, value.AsSpan(), suppressEscaping); + /// + /// Writes the UTF-8 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// The value is always escaped + /// + /// Thrown when the specified property name or value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) => WriteString(propertyName, value.AsSpan(), suppressEscaping); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 6b6dba100530..c19d08de3858 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -9,10 +9,34 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { @@ -27,6 +51,18 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { @@ -41,14 +77,50 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr _tokenType = JsonTokenType.Number; } + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), (ulong)value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName, (ulong)value, suppressEscaping); + /// + /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// The value to be written as a JSON number as part of the name/value pair. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName, (ulong)value, suppressEscaping); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 113a56802a87..fcd9e24c10e3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -10,9 +10,25 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the UTF-16 text value (as a JSON comment). + /// + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. + /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// + /// Thrown when the specified value is too large. + /// public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) => WriteCommentValue(utf16Text.AsSpan(), suppressEscaping); + /// + /// Writes the UTF-16 text value (as a JSON comment). + /// + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. + /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// + /// Thrown when the specified value is too large. + /// public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) { JsonWriterHelper.ValidateValue(ref utf16Text); @@ -46,18 +62,10 @@ private void WriteCommentByOptions(ref ReadOnlySpan value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } WriteCommentIndented(ref value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } WriteCommentMinimized(ref value); } } @@ -148,6 +156,14 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca ArrayPool.Shared.Return(valueArray); } + /// + /// Writes the UTF-8 text value (as a JSON comment). + /// + /// The UTF-8 encoded value to be written as a JSON comment within /*..*/. + /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// + /// Thrown when the specified value is too large. + /// public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) { JsonWriterHelper.ValidateValue(ref utf8Text); @@ -181,18 +197,10 @@ private void WriteCommentByOptions(ref ReadOnlySpan value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } WriteCommentIndented(ref value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } WriteCommentMinimized(ref value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index aa09512a7cb9..f63035f05c36 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -8,6 +8,13 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON string) as an element of a JSON array. + /// + /// The value to be written as a JSON string as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStringValue(DateTime value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index fe8504d46d9c..a2d5ad5d6214 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -8,6 +8,13 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON string) as an element of a JSON array. + /// + /// The value to be written as a JSON string as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStringValue(DateTimeOffset value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index 8035d1264bf4..d509aaba9f23 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -6,6 +6,13 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumberValue(decimal value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 9346dbf70f35..6caa2f027fec 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -6,6 +6,13 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumberValue(double value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index e52a5064b4ed..ac6ae7456188 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -6,6 +6,13 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumberValue(float value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index c0f034b1c502..d00318feb81d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -8,6 +8,13 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON string) as an element of a JSON array. + /// + /// The value to be written as a JSON string as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStringValue(Guid value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 8e9ca1783062..5bc8def95a72 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -6,6 +6,12 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the JSON literal "null" as an element of a JSON array. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNullValue() { WriteLiteralByOptions(JsonConstants.NullValue); @@ -14,6 +20,13 @@ public void WriteNullValue() _tokenType = JsonTokenType.Null; } + /// + /// Writes the value (as a JSON literal "true" or "false") as an element of a JSON array. + /// + /// The value to be written as a JSON literal "true" or "false" as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteBooleanValue(bool value) { if (value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index c0335316945c..f556333be129 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -6,9 +6,23 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumberValue(int value) => WriteNumberValue((long)value); + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteNumberValue(long value) { if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index f17cec65282c..9aac5a73f8dc 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -9,9 +9,31 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the UTF-16 text value (as a JSON string) as an element of a JSON array. + /// + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. + /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// + /// Thrown when the specified value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStringValue(string utf16Text, bool suppressEscaping = false) => WriteStringValue(utf16Text.AsSpan(), suppressEscaping); + /// + /// Writes the UTF-16 text value (as a JSON string) as an element of a JSON array. + /// + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. + /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// + /// Thrown when the specified value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStringValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) { JsonWriterHelper.ValidateValue(ref utf16Text); @@ -147,6 +169,17 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap ArrayPool.Shared.Return(valueArray); } + /// + /// Writes the UTF-8 text value (as a JSON string) as an element of a JSON array. + /// + /// The UTF-8 encoded value to be written as a JSON string element of a JSON array. + /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// + /// Thrown when the specified value is too large. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStringValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) { JsonWriterHelper.ValidateValue(ref utf8Text); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 67f8f92df749..83d75329f0f7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -6,10 +6,24 @@ namespace System.Text.Json { public ref partial struct Utf8JsonWriter { + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumberValue(uint value) => WriteNumberValue((ulong)value); + /// + /// Writes the value (as a JSON number) as an element of a JSON array. + /// + /// The value to be written as a JSON number as an element of a JSON array. + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// [CLSCompliant(false)] public void WriteNumberValue(ulong value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 322074180cd1..7246bf2a5b84 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -8,9 +8,19 @@ namespace System.Text.Json { + /// + /// Provides a high-performance API for forward-only, non-cached writing of UTF-8 encoded JSON text. + /// It writes the text sequentially with no caching and adheres to the JSON RFC + /// by default (https://tools.ietf.org/html/rfc8259), with the exception of writing comments. + /// When the user attempts to write invalid JSON and validation is enabled, it throws + /// a JsonWriterException with a context specific error message. + /// Since this type is a ref struct, it does not directly support async. However, it does provide + /// support for reentrancy to write partial data, and continue writing in chunks. + /// To be able to format the output with indentation and whitespace OR to skip validation, create an instance of + /// and pass that in to the writer. + /// public ref partial struct Utf8JsonWriter { - private const int MinimumSizeThreshold = 256; private const int StackallocThreshold = 256; private const int MaxExpansionFactorWhileEscaping = 6; private const int SpacesPerIndent = 2; @@ -20,6 +30,11 @@ public ref partial struct Utf8JsonWriter private int _buffered; private Span _buffer; + /// + /// Returns the total amount of bytes written by the so far + /// for the current instance of the . + /// This includes data that has been written beyond what has already been committed. + /// public long BytesWritten { get @@ -29,6 +44,11 @@ public long BytesWritten } } + /// + /// Returns the total amount of bytes committed to the output by the so far + /// for the current instance of the . + /// This is how much the IBufferWriter has advanced. + /// public long BytesCommitted { get; private set; } private bool _inObject; @@ -44,8 +64,19 @@ public long BytesWritten private int Indentation => CurrentDepth * SpacesPerIndent; + /// + /// Tracks the recursive depth of the nested objects / arrays within the JSON text + /// written so far. This provides the depth of the current token. + /// public int CurrentDepth => _currentDepth & JsonConstants.RemoveFlagsBitMask; + /// + /// Returns the current snapshot of the state which must + /// be captured by the caller and passed back in to the ctor with more data. + /// Unlike the , which is a ref struct, the state can survive + /// across async/await boundaries and hence this type is required to provide support for reading + /// in more data asynchronously before continuing with a new instance of the . + /// public JsonWriterState CurrentState => new JsonWriterState { _bytesWritten = BytesWritten, @@ -58,10 +89,18 @@ public long BytesWritten }; /// - /// Constructs a JSON writer with a specified . + /// Constructs a new instance with a specified . /// - /// An instance of used for writing bytes to an output channel. - /// Specifies whether to add whitespace to the output text for user readability. + /// An instance of used as a destination for writing JSON text into. + /// If this is the first call to the ctor, pass in a default state. Otherwise, + /// capture the state from the previous instance of the and pass that back. + /// + /// Thrown when the instance of that is passed in is null. + /// + /// + /// Since this type is a ref struct, it is a stack-only type and all the limitations of ref structs apply to it. + /// This is the reason why the ctor accepts a . + /// public Utf8JsonWriter(IBufferWriter bufferWriter, JsonWriterState state = default) { _output = bufferWriter ?? throw new ArgumentNullException(nameof(bufferWriter)); @@ -87,6 +126,15 @@ private void Advance(int count) _buffer = _buffer.Slice(count); } + /// + /// Advances the underlying based on what has been written so far. + /// + /// Let's the writer know whether more data will be written. This is used to validate + /// that the JSON written sor far is structurally valid if no more data is to follow. + /// + /// Thrown when incomplete JSON has been written and is true. + /// (for example when an open object or array needs to be closed). + /// public void Flush(bool isFinalBlock = true) { if (isFinalBlock && !_writerOptions.SkipValidation && CurrentDepth != 0) @@ -103,12 +151,26 @@ private void Flush() _buffered = 0; } + /// + /// Writes the beginning of a JSON array. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartArray() { WriteStart(JsonConstants.OpenBracket); _tokenType = JsonTokenType.StartArray; } + /// + /// Writes the beginning of a JSON object. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartObject() { WriteStart(JsonConstants.OpenBrace); @@ -230,6 +292,18 @@ private void WriteStartIndented(byte token) Advance(idx); } + /// + /// Writes the beginning of a JSON array with a property name as the key. + /// + /// The UTF-8 encoded property name of the JSON array to be written. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { ValidatePropertyNameAndDepth(ref propertyName); @@ -245,6 +319,18 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi _tokenType = JsonTokenType.StartArray; } + /// + /// Writes the beginning of a JSON object with a property name as the key. + /// + /// The UTF-8 encoded property name of the JSON object to be written. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { ValidatePropertyNameAndDepth(ref propertyName); @@ -340,12 +426,48 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte ArrayPool.Shared.Return(propertyArray); } + /// + /// Writes the beginning of a JSON array with a property name as the key. + /// + /// The UTF-16 encoded property name of the JSON array to be transcoded and written as UTF-8. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartArray(string propertyName, bool suppressEscaping = false) => WriteStartArray(propertyName.AsSpan(), suppressEscaping); + /// + /// Writes the beginning of a JSON object with a property name as the key. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartObject(string propertyName, bool suppressEscaping = false) => WriteStartObject(propertyName.AsSpan(), suppressEscaping); + /// + /// Writes the beginning of a JSON array with a property name as the key. + /// + /// The UTF-16 encoded property name of the JSON array to be transcoded and written as UTF-8. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { ValidatePropertyNameAndDepth(ref propertyName); @@ -361,6 +483,18 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi _tokenType = JsonTokenType.StartArray; } + /// + /// Writes the beginning of a JSON object with a property name as the key. + /// + /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. + /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// + /// Thrown when the specified property name is too large. + /// + /// + /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 + /// OR if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { ValidatePropertyNameAndDepth(ref propertyName); @@ -456,12 +590,24 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte ArrayPool.Shared.Return(propertyArray); } + /// + /// Writes the end of a JSON array. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteEndArray() { WriteEnd(JsonConstants.CloseBracket); _tokenType = JsonTokenType.EndArray; } + /// + /// Writes the end of a JSON object. + /// + /// + /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). + /// public void WriteEndObject() { WriteEnd(JsonConstants.CloseBrace); From 8276f4cabb5c5da960e7770f09c2dfa5409ac894 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Tue, 8 Jan 2019 01:09:39 -0800 Subject: [PATCH 09/33] Add JsonWriter unit tests. --- .../tests/BinaryFormatterTestData.cs | 3 + .../tests/EqualityExtensions.cs | 10 + src/System.Text.Json/ref/System.Text.Json.cs | 2 +- .../src/Resources/Strings.resx | 6 + .../src/System/Text/Json/ThrowHelper.cs | 13 + .../Text/Json/Writer/JsonWriterException.cs | 1 - .../Text/Json/Writer/JsonWriterHelper.cs | 14 + .../Utf8JsonWriter.WriteProperties.Double.cs | 2 + .../Utf8JsonWriter.WriteProperties.Float.cs | 2 + .../Utf8JsonWriter.WriteValues.Comment.cs | 38 - .../Utf8JsonWriter.WriteValues.Double.cs | 2 + .../Utf8JsonWriter.WriteValues.Float.cs | 2 + .../System/Text/Json/Writer/Utf8JsonWriter.cs | 32 +- src/System.Text.Json/tests/ArrayFormatter.cs | 78 + src/System.Text.Json/tests/BitStackTests.cs | 5 +- .../tests/InvalidBufferWriter.cs | 26 + .../tests/JsonWriterStateTests.cs | 56 + src/System.Text.Json/tests/ResizableArray.cs | 43 + .../tests/System.Text.Json.Tests.csproj | 7 +- .../tests/Utf8JsonWriterTests.cs | 3116 +++++++++++++++++ 20 files changed, 3404 insertions(+), 54 deletions(-) create mode 100644 src/System.Text.Json/tests/ArrayFormatter.cs create mode 100644 src/System.Text.Json/tests/InvalidBufferWriter.cs create mode 100644 src/System.Text.Json/tests/JsonWriterStateTests.cs create mode 100644 src/System.Text.Json/tests/ResizableArray.cs create mode 100644 src/System.Text.Json/tests/Utf8JsonWriterTests.cs diff --git a/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index 52e263f60703..cc8c400e51e0 100644 --- a/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -474,6 +474,9 @@ private static IEnumerable SerializableObjects() #if netcoreapp var jsonReaderException = new JsonReaderException("message", lineNumber: 0, bytePositionInLine: 0); yield return new object[] { PopulateException(jsonReaderException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAJFN5c3RlbS5UZXh0Lkpzb24uSnNvblJlYWRlckV4Y2VwdGlvbg4AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lAQEDAwEBAQABAAEHAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgkJAgAAAAYDAAAAJFN5c3RlbS5UZXh0Lkpzb24uSnNvblJlYWRlckV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAoGBgAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBgcAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCAAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCQAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoAAAAAAAAAAAAAAAAAAAAABAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQoAAAACAAAAAgAAAAQKAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYLAAAABnNlY3JldAgBAQkMAAAAAQwAAAAKAAAACAgBAAAABg0AAAADb25lCgs=", TargetFrameworkMoniker.netcoreapp30) } }; + + var jsonWriterException = new JsonWriterException("message"); + yield return new object[] { PopulateException(jsonWriterException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAJFN5c3RlbS5UZXh0Lkpzb24uSnNvbldyaXRlckV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAkU3lzdGVtLlRleHQuSnNvbi5Kc29uV3JpdGVyRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACgYGAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GBwAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYIAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYJAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkKAAAAAgAAAAIAAAAECgAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGCwAAAAZzZWNyZXQIAQEJDAAAAAEMAAAACgAAAAgIAQAAAAYNAAAAA29uZQoL", TargetFrameworkMoniker.netcoreapp30) } }; #endif var keyNotFoundException = new KeyNotFoundException("message", exception); diff --git a/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs b/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs index 9b5386156c19..a3b2ddbc9b35 100644 --- a/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs +++ b/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs @@ -1213,6 +1213,16 @@ public static void IsEqual(this JsonReaderException @this, JsonReaderException o Assert.Equal(@this.LineNumber, other.LineNumber); Assert.Equal(@this.BytePositionInLine, other.BytePositionInLine); } + + public static void IsEqual(this JsonWriterException @this, JsonWriterException other, bool isSamePlatform) + { + if (@this == null && other == null) + return; + + Assert.NotNull(@this); + Assert.NotNull(other); + IsEqual(@this as Exception, other as Exception, isSamePlatform); + } #endif public static void IsEqual(this EventArgs @this, EventArgs other, bool isSamePlatform) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index 4c197b8ba8bd..2e8076419221 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -96,8 +96,8 @@ public ref partial struct Utf8JsonWriter public long BytesCommitted { get { throw null; } } public long BytesWritten { get { throw null; } } public int CurrentDepth { get { throw null; } } - public System.Text.Json.JsonWriterState CurrentState { get { throw null; } } public void Flush(bool isFinalBlock = true) { } + public System.Text.Json.JsonWriterState GetCurrentState() { throw null; } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { } diff --git a/src/System.Text.Json/src/Resources/Strings.resx b/src/System.Text.Json/src/Resources/Strings.resx index ef23fa929761..76d0c7b48aa9 100644 --- a/src/System.Text.Json/src/Resources/Strings.resx +++ b/src/System.Text.Json/src/Resources/Strings.resx @@ -120,6 +120,9 @@ CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON array. + + The JSON writer needs to be flushed before getting the current state. There are {0} bytes that have not been committed to the output. + Cannot write the start of an object or array after a single JSON value. Current token type is '{0}'. @@ -228,6 +231,9 @@ Expected a digit ('0'-'9'), but instead reached end of data. + + .NET number values such as positive and negative infinity cannot be written as valid JSON. + The JSON value of length {0} is too large and not supported by the JSON writer. diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index d27ba4bc1f59..a16a9bc195ba 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -25,6 +25,11 @@ public static void ThrowArgumentException(string message) throw GetArgumentException(message); } + public static InvalidOperationException GetInvalidOperationException_CallFlushFirst(int _buffered) + { + return new InvalidOperationException(SR.Format(SR.CallFlushToAvoidDataLoss, _buffered)); + } + public static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength) { throw GetArgumentException(SR.Format(SR.PropertyNameTooLarge, tokenLength)); @@ -35,6 +40,11 @@ public static void ThrowArgumentException_ValueTooLarge(int tokenLength) throw GetArgumentException(SR.Format(SR.ValueTooLarge, tokenLength)); } + public static void ThrowArgumentException_ValueNotSupported() + { + throw GetArgumentException(SR.SpecialNumberValuesNotSupported); + } + public static void ThrowArgumentException(ExceptionResource resource, int minimumSize = 0) { if (resource == ExceptionResource.FailedToGetLargerSpan) @@ -347,6 +357,9 @@ private static string GetResourceString(ExceptionResource resource, int currentD case ExceptionResource.CannotWriteValueWithinObject: message = SR.Format(SR.CannotWriteValueWithinObject, tokenType); break; + case ExceptionResource.CannotWritePropertyWithinArray: + message = SR.Format(SR.CannotWritePropertyWithinArray, tokenType); + break; case ExceptionResource.CannotWriteValueAfterPrimitive: message = SR.Format(SR.CannotWriteValueAfterPrimitive, tokenType); break; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs index b31d6ee0db39..b0a5c6320186 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs @@ -11,7 +11,6 @@ namespace System.Text.Json /// tries to write invalid JSON text. This exception is also thrown whenever /// you write past the pre-set maximum depth or if the you try to write invalid UTF-8 text. /// - //TODO: Add a test? Do we need to override GetObjectData in this case? [Serializable] public sealed class JsonWriterException : Exception { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 6a5525568a37..4250f290ed42 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -63,6 +63,20 @@ public static void ValidateValue(ref ReadOnlySpan value) ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateDouble(double value) + { + if (double.IsPositiveInfinity(value) || double.IsNegativeInfinity(value) || double.IsNaN(value)) + ThrowHelper.ThrowArgumentException_ValueNotSupported(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateSingle(float value) + { + if (float.IsPositiveInfinity(value) || float.IsNegativeInfinity(value) || float.IsNaN(value)) + ThrowHelper.ThrowArgumentException_ValueNotSupported(); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateProperty(ref ReadOnlySpan propertyName) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 437d57c56e15..94be69e7b0f1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -40,6 +40,7 @@ public void WriteNumber(string propertyName, double value, bool suppressEscaping public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateDouble(value); if (!suppressEscaping) WriteNumberSuppressFalse(ref propertyName, value); @@ -65,6 +66,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateDouble(value); if (!suppressEscaping) WriteNumberSuppressFalse(ref propertyName, value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 95adad643ea2..31893a5ff764 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -40,6 +40,7 @@ public void WriteNumber(string propertyName, float value, bool suppressEscaping public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateSingle(value); if (!suppressEscaping) WriteNumberSuppressFalse(ref propertyName, value); @@ -65,6 +66,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateSingle(value); if (!suppressEscaping) WriteNumberSuppressFalse(ref propertyName, value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index fcd9e24c10e3..2c7ddbad6c33 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -37,9 +37,6 @@ public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscapin WriteCommentSuppressFalse(ref utf16Text); else WriteCommentByOptions(ref utf16Text); - - _currentDepth |= 1 << 31; - _tokenType = JsonTokenType.String; } private void WriteCommentSuppressFalse(ref ReadOnlySpan value) @@ -73,14 +70,6 @@ private void WriteCommentByOptions(ref ReadOnlySpan value) private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) { int idx = 0; - if (_currentDepth < 0) - { - while (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeperator; - } WriteCommentValue(ref escapedValue, ref idx); @@ -90,14 +79,6 @@ private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) private void WriteCommentIndented(ref ReadOnlySpan escapedValue) { int idx = 0; - if (_currentDepth < 0) - { - while (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeperator; - } if (_tokenType != JsonTokenType.None) WriteNewLine(ref idx); @@ -172,9 +153,6 @@ public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping WriteCommentSuppressFalse(ref utf8Text); else WriteCommentByOptions(ref utf8Text); - - _currentDepth |= 1 << 31; - _tokenType = JsonTokenType.String; } private void WriteCommentSuppressFalse(ref ReadOnlySpan value) @@ -208,14 +186,6 @@ private void WriteCommentByOptions(ref ReadOnlySpan value) private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) { int idx = 0; - if (_currentDepth < 0) - { - while (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeperator; - } WriteCommentValue(ref escapedValue, ref idx); @@ -225,14 +195,6 @@ private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) private void WriteCommentIndented(ref ReadOnlySpan escapedValue) { int idx = 0; - if (_currentDepth < 0) - { - while (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeperator; - } if (_tokenType != JsonTokenType.None) WriteNewLine(ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 6caa2f027fec..98dfb149aa27 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -15,6 +15,8 @@ public ref partial struct Utf8JsonWriter /// public void WriteNumberValue(double value) { + JsonWriterHelper.ValidateDouble(value); + if (_writerOptions.Indented) { if (!_writerOptions.SkipValidation) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index ac6ae7456188..dd4286a7ba67 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -15,6 +15,8 @@ public ref partial struct Utf8JsonWriter /// public void WriteNumberValue(float value) { + JsonWriterHelper.ValidateSingle(value); + if (_writerOptions.Indented) { if (!_writerOptions.SkipValidation) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 7246bf2a5b84..16a8e91734dd 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -77,16 +77,28 @@ public long BytesWritten /// across async/await boundaries and hence this type is required to provide support for reading /// in more data asynchronously before continuing with a new instance of the . /// - public JsonWriterState CurrentState => new JsonWriterState - { - _bytesWritten = BytesWritten, - _bytesCommitted = BytesCommitted, - _inObject = _inObject, - _isNotPrimitive = _isNotPrimitive, - _tokenType = _tokenType, - _writerOptions = _writerOptions, - _bitStack = _bitStack, - }; + /// + /// Thrown when there is JSON data that has been written and buffered but not yet flushed to the . + /// Getting the state for creating a new without first committing the data that has been written + /// would result in an inconsistent state. Call Flush before getting the current state. + /// + public JsonWriterState GetCurrentState() + { + if (_buffered != 0) + { + throw ThrowHelper.GetInvalidOperationException_CallFlushFirst(_buffered); + } + return new JsonWriterState + { + _bytesWritten = BytesWritten, + _bytesCommitted = BytesCommitted, + _inObject = _inObject, + _isNotPrimitive = _isNotPrimitive, + _tokenType = _tokenType, + _writerOptions = _writerOptions, + _bitStack = _bitStack, + }; + } /// /// Constructs a new instance with a specified . diff --git a/src/System.Text.Json/tests/ArrayFormatter.cs b/src/System.Text.Json/tests/ArrayFormatter.cs new file mode 100644 index 000000000000..d757dd4c9b97 --- /dev/null +++ b/src/System.Text.Json/tests/ArrayFormatter.cs @@ -0,0 +1,78 @@ +// 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. + +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace System.Text.Json.Tests +{ + internal class ArrayFormatter : IBufferWriter, IDisposable + { + ResizableArray _buffer; + + public ArrayFormatter(int capacity) + { + _buffer = new ResizableArray(ArrayPool.Shared.Rent(capacity)); + } + + public int CommitedByteCount => _buffer.Count; + + public void Clear() + { + _buffer.Count = 0; + } + + public ArraySegment Free => _buffer.Free; + + public ArraySegment Formatted => _buffer.Full; + + public Memory GetMemory(int minimumLength = 0) + { + if (minimumLength < 1) + minimumLength = 1; + if (minimumLength > _buffer.FreeCount) + { + int doubleCount = _buffer.FreeCount * 2; + int newSize = minimumLength > doubleCount ? minimumLength : doubleCount; + byte[] newArray = ArrayPool.Shared.Rent(newSize + _buffer.Count); + byte[] oldArray = _buffer.Resize(newArray); + ArrayPool.Shared.Return(oldArray); + } + return _buffer.FreeMemory; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span GetSpan(int minimumLength = 0) + { + if (minimumLength < 1) + minimumLength = 1; + if (minimumLength > _buffer.FreeCount) + { + int doubleCount = _buffer.FreeCount * 2; + int newSize = minimumLength > doubleCount ? minimumLength : doubleCount; + byte[] newArray = ArrayPool.Shared.Rent(newSize + _buffer.Count); + byte[] oldArray = _buffer.Resize(newArray); + ArrayPool.Shared.Return(oldArray); + } + return _buffer.FreeSpan; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int bytes) + { + _buffer.Count += bytes; + if (_buffer.Count > _buffer.Capacity) + { + throw new InvalidOperationException("More bytes commited than returned from FreeBuffer"); + } + } + + public void Dispose() + { + byte[] array = _buffer.Array; + _buffer.Array = null; + ArrayPool.Shared.Return(array); + } + } +} diff --git a/src/System.Text.Json/tests/BitStackTests.cs b/src/System.Text.Json/tests/BitStackTests.cs index c4391473a191..41cff4a48964 100644 --- a/src/System.Text.Json/tests/BitStackTests.cs +++ b/src/System.Text.Json/tests/BitStackTests.cs @@ -2,14 +2,13 @@ // 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.Json; using Xunit; -namespace System.Text.JsonTests +namespace System.Text.Json.Tests { public static partial class BitStackTests { - private static Random s_random = new Random(42); + private static readonly Random s_random = new Random(42); [Fact] public static void DefaultBitStack() diff --git a/src/System.Text.Json/tests/InvalidBufferWriter.cs b/src/System.Text.Json/tests/InvalidBufferWriter.cs new file mode 100644 index 000000000000..2a92ccb90ec5 --- /dev/null +++ b/src/System.Text.Json/tests/InvalidBufferWriter.cs @@ -0,0 +1,26 @@ +// 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. + +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace System.Text.Json.Tests +{ + internal class InvalidBufferWriter : IBufferWriter + { + public InvalidBufferWriter() + { + } + + public Memory GetMemory(int minimumLength = 0) => new byte[10]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span GetSpan(int minimumLength = 0) => new byte[10]; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int bytes) + { + } + } +} diff --git a/src/System.Text.Json/tests/JsonWriterStateTests.cs b/src/System.Text.Json/tests/JsonWriterStateTests.cs new file mode 100644 index 000000000000..87a167008f0e --- /dev/null +++ b/src/System.Text.Json/tests/JsonWriterStateTests.cs @@ -0,0 +1,56 @@ +// 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. + +using Xunit; + +namespace System.Text.Json.Tests +{ + public static partial class JsonWriterStateTests + { + [Fact] + public static void DefaultJsonWriterState() + { + JsonWriterState state = default; + Assert.Equal(0, state.BytesCommitted); + Assert.Equal(0, state.BytesWritten); + + var expectedOption = new JsonWriterOptions + { + Indented = false, + SkipValidation = false + }; + Assert.Equal(expectedOption, state.Options); + } + + [Fact] + public static void JsonWriterStateDefaultCtor() + { + var state = new JsonWriterState(); + Assert.Equal(0, state.BytesCommitted); + Assert.Equal(0, state.BytesWritten); + + var expectedOption = new JsonWriterOptions + { + Indented = false, + SkipValidation = false + }; + Assert.Equal(expectedOption, state.Options); + } + + [Fact] + public static void JsonWriterStateCtor() + { + var state = new JsonWriterState(options: default); + Assert.Equal(0, state.BytesCommitted); + Assert.Equal(0, state.BytesWritten); + + var expectedOption = new JsonWriterOptions + { + Indented = false, + SkipValidation = false + }; + Assert.Equal(expectedOption, state.Options); + } + } +} diff --git a/src/System.Text.Json/tests/ResizableArray.cs b/src/System.Text.Json/tests/ResizableArray.cs new file mode 100644 index 000000000000..b02d6b4c4b12 --- /dev/null +++ b/src/System.Text.Json/tests/ResizableArray.cs @@ -0,0 +1,43 @@ +// 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. + +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace System.Text.Json.Tests +{ + // a List like type designed to be embeded in other types + internal struct ResizableArray + { + public ResizableArray(T[] array, int count = 0) + { + Array = array; + Count = count; + } + + public T[] Array { get; set; } + + public int Count { get; set; } + + public int Capacity => Array.Length; + + public T[] Resize(T[] newArray) + { + T[] oldArray = Array; + Array.AsSpan(0, Count).CopyTo(newArray); // CopyTo will throw if newArray.Length < _count + Array = newArray; + return oldArray; + } + + public ArraySegment Full => new ArraySegment(Array, 0, Count); + + public ArraySegment Free => new ArraySegment(Array, Count, Array.Length - Count); + + public Span FreeSpan => new Span(Array, Count, Array.Length - Count); + + public Memory FreeMemory => new Memory(Array, Count, Array.Length - Count); + + public int FreeCount => Array.Length - Count; + } +} diff --git a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj index 3a181eddcf74..06e661adc656 100644 --- a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -4,18 +4,23 @@ netcoreapp-Debug;netcoreapp-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release + + + + + - + diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs new file mode 100644 index 000000000000..181cdda2664f --- /dev/null +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -0,0 +1,3116 @@ +// 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. + +using Xunit; +using System.IO; +using Newtonsoft.Json; + +namespace System.Text.Json.Tests +{ + public class Utf8JsonWriterTests + { + [Fact] + public void NullCtor() + { + try + { + var jsonUtf8 = new Utf8JsonWriter(null); + Assert.True(false, "Expected ArgumentNullException to be thrown when null IBufferWriter is passed in."); + } + catch (ArgumentNullException) { } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void InvalidBufferWriter(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new InvalidBufferWriter(); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteNumberValue((ulong)12345678901); + Assert.True(false, "Expected ArgumentException to be thrown when IBufferWriter doesn't have enough space."); + } + catch (ArgumentException) { } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void InvalidJsonMismatch(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray("property at start", suppressEscaping: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject("property at start", suppressEscaping: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartArray("property inside array", suppressEscaping: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStringValue("key"); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteString("key", "value"); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteEndObject(); + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteEndObject(); + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartArray("test array", suppressEscaping: true); + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndObject(); + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartObject("test object", suppressEscaping: true); + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void InvalidJsonIncomplete(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.Flush(isFinalBlock: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.Flush(isFinalBlock: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(isFinalBlock: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.Flush(isFinalBlock: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(isFinalBlock: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartArray("test array", suppressEscaping: true); + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(isFinalBlock: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void InvalidJsonPrimitive(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteNumberValue(12345); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteStartArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteStartObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteStartArray("property name", suppressEscaping: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteStartObject("property name", suppressEscaping: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteString("property name", "value", suppressEscaping: true); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(12345); + jsonUtf8.WriteEndObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void InvalidNumbersJson(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(double.NegativeInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(double.PositiveInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(double.NaN); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(float.PositiveInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(float.NegativeInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteNumberValue(float.NaN); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteNumber("name", double.NegativeInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteNumber("name", double.PositiveInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteNumber("name", double.NaN); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteNumber("name", float.PositiveInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteNumber("name", float.NegativeInfinity); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteNumber("name", float.NaN); + Assert.True(false, "Expected ArgumentException to be thrown for unsupported number values."); + } + catch (ArgumentException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true)] + [InlineData(false)] + public void InvalidJsonContinueShouldSucceed(bool formatted) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = true }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + for (int i = 0; i < 100; i++) + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + var sb = new StringBuilder(); + for (int i = 0; i < 100; i++) + { + if (formatted) + sb.Append(Environment.NewLine); + sb.Append("]"); + } + if (formatted) + sb.Append(Environment.NewLine); + sb.Append("[]"); + + Assert.Equal(sb.ToString(), actualStr); + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WritingTooDeep(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + try + { + for (int i = 0; i < 1001; i++) + { + jsonUtf8.WriteStartArray(); + } + Assert.True(false, "Expected JsonWriterException to be thrown for depth >= 1000."); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WritingTooDeepProperty(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStartObject(); + for (int i = 0; i < 1000; i++) + { + jsonUtf8.WriteStartArray("name"); + } + Assert.True(false, "Expected JsonWriterException to be thrown for depth >= 1000."); + } + catch (JsonWriterException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStartObject(); + for (int i = 0; i < 1000; i++) + { + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("name")); + } + Assert.True(false, "Expected JsonWriterException to be thrown for depth >= 1000."); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + [Theory] + [OuterLoop] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WritingTooLargeProperty(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + Span key = new byte[1_000_000_000]; + key.Fill((byte)'a'); + + var keyChars = new char[1_000_000_000]; + keyChars.AsSpan().Fill('a'); + + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartArray(keyChars); + Assert.True(false, "Expected ArgumentException to be thrown for depth >= 1000."); + } + catch (ArgumentException) { } + + jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteStartArray(key); + Assert.True(false, "Expected ArgumentException to be thrown for depth >= 1000."); + } + catch (ArgumentException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteSingleValue(bool formatted, bool skipValidation) + { + string expectedStr = "123456789012345"; + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 3; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteNumberValue(123456789012345); + + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteHelloWorld(bool formatted, bool skipValidation) + { + string expectedStr = GetHelloWorldExpectedString(prettyPrint: formatted); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 9; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString("message", "Hello, World!", suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteString("message", "Hello, World!".AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteString("message", Encoding.UTF8.GetBytes("Hello, World!"), suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteString("message".AsSpan(), "Hello, World!", suppressEscaping: true); + break; + case 4: + jsonUtf8.WriteString("message".AsSpan(), "Hello, World!".AsSpan(), suppressEscaping: true); + break; + case 5: + jsonUtf8.WriteString("message".AsSpan(), Encoding.UTF8.GetBytes("Hello, World!"), suppressEscaping: true); + break; + case 6: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), "Hello, World!", suppressEscaping: true); + break; + case 7: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), "Hello, World!".AsSpan(), suppressEscaping: true); + break; + case 8: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), Encoding.UTF8.GetBytes("Hello, World!"), suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WritePartialHelloWorld(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + Assert.Equal(0, jsonUtf8.BytesCommitted); + Assert.Equal(1, jsonUtf8.BytesWritten); + + jsonUtf8.WriteString("message", "Hello, World!"); + + Assert.Equal(16, jsonUtf8.BytesCommitted); + if (formatted) + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesWritten); + else + Assert.Equal(26, jsonUtf8.BytesWritten); + + jsonUtf8.Flush(isFinalBlock: false); + + if (formatted) + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); // new lines, indentation, white space + else + Assert.Equal(26, jsonUtf8.BytesCommitted); + + Assert.Equal(jsonUtf8.BytesCommitted, jsonUtf8.BytesWritten); + + jsonUtf8.WriteString("message", "Hello, World!"); + jsonUtf8.WriteEndObject(); + + if (formatted) + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); + else + Assert.Equal(26, jsonUtf8.BytesCommitted); + + if (formatted) + Assert.Equal(53 + (2 * 2) + (3 * Environment.NewLine.Length) + (1 * 2), jsonUtf8.BytesWritten); // new lines, indentation, white space + else + Assert.Equal(53, jsonUtf8.BytesWritten); + + jsonUtf8.Flush(isFinalBlock: true); + + if (formatted) + Assert.Equal(53 + (2 * 2) + (3 * Environment.NewLine.Length) + (1 * 2), jsonUtf8.BytesCommitted); // new lines, indentation, white space + else + Assert.Equal(53, jsonUtf8.BytesCommitted); + + Assert.Equal(jsonUtf8.BytesCommitted, jsonUtf8.BytesWritten); + + Assert.Equal(0, state.BytesCommitted); + Assert.Equal(0, state.BytesWritten); + + state = jsonUtf8.GetCurrentState(); + Assert.Equal(jsonUtf8.BytesCommitted, state.BytesCommitted); + Assert.Equal(jsonUtf8.BytesWritten, state.BytesWritten); + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + Assert.Equal(0, jsonUtf8.CurrentDepth); + jsonUtf8.WriteStartObject(); + Assert.Equal(1, jsonUtf8.CurrentDepth); + jsonUtf8.Flush(isFinalBlock: false); + + state = jsonUtf8.GetCurrentState(); + + Assert.Equal(1, state.BytesCommitted); + Assert.Equal(1, state.BytesWritten); + + jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteString("message", "Hello, World!"); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + Assert.Equal(jsonUtf8.BytesCommitted, jsonUtf8.BytesWritten); + + if (formatted) + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); + else + Assert.Equal(26, jsonUtf8.BytesCommitted); + + Assert.Equal(1, state.BytesCommitted); + Assert.Equal(1, state.BytesWritten); + + state = jsonUtf8.GetCurrentState(); + + if (formatted) + { + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, state.BytesCommitted); + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, state.BytesWritten); + } + else + { + Assert.Equal(26, state.BytesCommitted); + Assert.Equal(26, state.BytesWritten); + } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteInvalidPartialJson(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + Assert.Equal(0, state.BytesCommitted); + Assert.Equal(0, state.BytesWritten); + + jsonUtf8.Flush(isFinalBlock: false); + + state = jsonUtf8.GetCurrentState(); + + Assert.Equal(1, state.BytesCommitted); + Assert.Equal(1, state.BytesWritten); + + jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStringValue("Hello, World!"); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + try + { + jsonUtf8.WriteEndArray(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WritePartialJsonSkipFlush(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteString("message", "Hello, World!"); + + Assert.Equal(1, jsonUtf8.CurrentDepth); + + try + { + state = jsonUtf8.GetCurrentState(); + } + catch (InvalidOperationException) + { + } + finally + { + jsonUtf8.Flush(isFinalBlock: false); + } + + state = jsonUtf8.GetCurrentState(); + + jsonUtf8 = new Utf8JsonWriter(output, state); + Assert.Equal(0, jsonUtf8.CurrentDepth); + Assert.Equal(0, jsonUtf8.BytesWritten); + Assert.Equal(0, jsonUtf8.BytesCommitted); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + output.Dispose(); + } + + [Theory] + [InlineData(true, true, "comment")] + [InlineData(true, false, "comment")] + [InlineData(false, true, "comment")] + [InlineData(false, false, "comment")] + [InlineData(true, true, "comm>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteComments(bool formatted, bool skipValidation, string comment) + { + string expectedStr = GetCommentExpectedString(prettyPrint: formatted, comment); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 3; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartArray(); + + for (int j = 0; j < 10; j++) + { + WriteCommentValue(ref jsonUtf8, i, comment); + } + + switch (i) + { + case 0: + jsonUtf8.WriteStringValue(comment); + break; + case 1: + jsonUtf8.WriteStringValue(comment.AsSpan()); + break; + case 2: + jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(comment)); + break; + } + + WriteCommentValue(ref jsonUtf8, i, comment); + + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + private static void WriteCommentValue(ref Utf8JsonWriter jsonUtf8, int i, string comment) + { + switch (i) + { + case 0: + jsonUtf8.WriteCommentValue(comment, suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteCommentValue(comment.AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteCommentValue(Encoding.UTF8.GetBytes(comment), suppressEscaping: true); + break; + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteStrings(bool formatted, bool skipValidation) + { + string value = "temp"; + string expectedStr = GetStringsExpectedString(prettyPrint: formatted, value); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartArray(); + + for (int j = 0; j < 10; j++) + { + switch (i) + { + case 0: + jsonUtf8.WriteStringValue(value); + break; + case 1: + jsonUtf8.WriteStringValue(value.AsSpan()); + break; + case 2: + jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value)); + break; + case 3: + jsonUtf8.WriteStringValue(value, suppressEscaping: true); + break; + case 4: + jsonUtf8.WriteStringValue(value.AsSpan(), suppressEscaping: true); + break; + case 5: + jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + } + } + + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, "mess\nage", "Hello, \nWorld!")] + [InlineData(true, false, "mess\nage", "Hello, \nWorld!")] + [InlineData(false, true, "mess\nage", "Hello, \nWorld!")] + [InlineData(false, false, "mess\nage", "Hello, \nWorld!")] + [InlineData(true, true, "message", "Hello, \nWorld!")] + [InlineData(true, false, "message", "Hello, \nWorld!")] + [InlineData(false, true, "message", "Hello, \nWorld!")] + [InlineData(false, false, "message", "Hello, \nWorld!")] + [InlineData(true, true, "mess\nage", "Hello, World!")] + [InlineData(true, false, "mess\nage", "Hello, World!")] + [InlineData(false, true, "mess\nage", "Hello, World!")] + [InlineData(false, false, "mess\nage", "Hello, World!")] + [InlineData(true, true, "message", "Hello, World!")] + [InlineData(true, false, "message", "Hello, World!")] + [InlineData(false, true, "message", "Hello, World!")] + [InlineData(false, false, "message", "Hello, World!")] + [InlineData(true, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] + public void WriteHelloWorldEscaped(bool formatted, bool skipValidation, string key, string value) + { + string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, key, value, StringEscapeHandling.EscapeHtml); + string expectedStrNoEscape = GetEscapedExpectedString(prettyPrint: formatted, key, value, StringEscapeHandling.EscapeHtml, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 18; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString(key, value, suppressEscaping: false); + break; + case 1: + jsonUtf8.WriteString(key.AsSpan(), value.AsSpan(), suppressEscaping: false); + break; + case 2: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + break; + case 3: + jsonUtf8.WriteString(key, value.AsSpan(), suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteString(key, Encoding.UTF8.GetBytes(value), suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteString(key.AsSpan(), value, suppressEscaping: false); + break; + case 6: + jsonUtf8.WriteString(key.AsSpan(), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + break; + case 7: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value, suppressEscaping: false); + break; + case 8: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value.AsSpan(), suppressEscaping: false); + break; + case 9: + jsonUtf8.WriteString(key, value, suppressEscaping: true); + break; + case 10: + jsonUtf8.WriteString(key.AsSpan(), value.AsSpan(), suppressEscaping: true); + break; + case 11: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + case 12: + jsonUtf8.WriteString(key, value.AsSpan(), suppressEscaping: true); + break; + case 13: + jsonUtf8.WriteString(key, Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + case 14: + jsonUtf8.WriteString(key.AsSpan(), value, suppressEscaping: true); + break; + case 15: + jsonUtf8.WriteString(key.AsSpan(), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + case 16: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value, suppressEscaping: true); + break; + case 17: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value.AsSpan(), suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i >= 9) + Assert.True(expectedStrNoEscape == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + else + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void EscapeAsciiCharacters(bool formatted, bool skipValidation) + { + var propertyArray = new char[128]; + + char[] specialCases = { '+', '`', (char)0x7F }; + for (int i = 0; i < propertyArray.Length; i++) + { + if (Array.IndexOf(specialCases, (char)i) != -1) + { + propertyArray[i] = (char)0; + } + else + { + propertyArray[i] = (char)i; + } + } + + string propertyName = new string(propertyArray); + string value = new string(propertyArray); + + string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + for (int i = 0; i < 4; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString(propertyName, value, suppressEscaping: false); + break; + case 1: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + break; + case 2: + expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml, escape: false); + jsonUtf8.WriteString(propertyName, value, suppressEscaping: true); + break; + case 3: + expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml, escape: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void EscapeCharacters(bool formatted, bool skipValidation) + { + // Do not include surrogate pairs. + var propertyArray = new char[0xD800 + (0xFFFF - 0xE000) + 1]; + + for (int i = 128; i < propertyArray.Length; i++) + { + if (i < 0xD800 || i > 0xDFFF) + { + propertyArray[i] = (char)i; + } + } + + string propertyName = new string(propertyArray); + string value = new string(propertyArray); + + string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + for (int i = 0; i < 4; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString(propertyName, value, suppressEscaping: false); + break; + case 1: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + break; + case 2: + expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); + jsonUtf8.WriteString(propertyName, value, suppressEscaping: true); + break; + case 3: + expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void EscapeSurrogatePairs(bool formatted, bool skipValidation) + { + var propertyArray = new char[10] { 'a', (char)0xD800, (char)0xDC00, (char)0xD803, (char)0xDE6D, (char)0xD834, (char)0xDD1E, (char)0xDBFF, (char)0xDFFF, 'a' }; + + string propertyName = new string(propertyArray); + string value = new string(propertyArray); + + string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + for (int i = 0; i < 4; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString(propertyName, value, suppressEscaping: false); + break; + case 1: + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + break; + case 2: + expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); + jsonUtf8.WriteString(propertyName, value, suppressEscaping: true); + break; + case 3: + expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void InvalidUTF8(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + for (int i = 0; i < 8; i++) + { + try + { + switch (i) + { + case 0: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: true); + AssertWriterThrow(noThrow: false); + break; + case 1: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: true); + AssertWriterThrow(noThrow: true); + break; + case 2: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: true); + AssertWriterThrow(noThrow: false); + break; + case 3: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: true); + AssertWriterThrow(noThrow: true); + break; + case 4: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: false); + AssertWriterThrow(noThrow: false); + break; + case 5: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: false); + AssertWriterThrow(noThrow: false); + break; + case 6: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: false); + AssertWriterThrow(noThrow: false); + break; + case 7: + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: false); + AssertWriterThrow(noThrow: true); + break; + } + } + catch (JsonWriterException) { } + } + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteCustomStrings(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + for (int i = 0; i < 1_000; i++) + jsonUtf8.WriteString("message", "Hello, World!", suppressEscaping: true); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(GetCustomExpectedString(formatted), actualStr); + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteStartEnd(bool formatted, bool skipValidation) + { + string expectedStr = GetStartEndExpectedString(prettyPrint: formatted); + + var output = new ArrayFormatter(1024); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndObject(); + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidation) + { + string expectedStr = GetStartEndWithPropertyArrayExpectedString(prettyPrint: formatted); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteStartArray("property name", suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteStartArray("property name".AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("property name"), suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteStartArray("property name", suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteStartArray("property name".AsSpan(), suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("property name"), suppressEscaping: false); + break; + } + + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, 10)] + [InlineData(true, false, 10)] + [InlineData(false, true, 10)] + [InlineData(false, false, 10)] + [InlineData(true, true, 100)] + [InlineData(true, false, 100)] + [InlineData(false, true, 100)] + [InlineData(false, false, 100)] + public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidation, int keyLength) + { + var keyChars = new char[keyLength]; + for (int i = 0; i < keyChars.Length; i++) + { + keyChars[i] = '<'; + } + var key = new string(keyChars); + + string expectedStr = GetStartEndWithPropertyArrayExpectedString(key, prettyPrint: formatted, escape: true); + string expectedStrNoEscape = GetStartEndWithPropertyArrayExpectedString(key, prettyPrint: formatted, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteStartArray(key, suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteStartArray(key.AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes(key), suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteStartArray(key, suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteStartArray(key.AsSpan(), suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes(key), suppressEscaping: false); + break; + } + + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.Equal(expectedStrNoEscape, actualStr); + else + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidation) + { + string expectedStr = GetStartEndWithPropertyObjectExpectedString(prettyPrint: formatted); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteStartObject("property name", suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteStartObject("property name".AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes("property name"), suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteStartObject("property name", suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteStartObject("property name".AsSpan(), suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes("property name"), suppressEscaping: false); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, 10)] + [InlineData(true, false, 10)] + [InlineData(false, true, 10)] + [InlineData(false, false, 10)] + [InlineData(true, true, 100)] + [InlineData(true, false, 100)] + [InlineData(false, true, 100)] + [InlineData(false, false, 100)] + public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidation, int keyLength) + { + var keyChars = new char[keyLength]; + for (int i = 0; i < keyChars.Length; i++) + { + keyChars[i] = '<'; + } + var key = new string(keyChars); + + string expectedStr = GetStartEndWithPropertyObjectExpectedString(key, prettyPrint: formatted, escape: true); + string expectedStrNoEscape = GetStartEndWithPropertyObjectExpectedString(key, prettyPrint: formatted, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteStartObject(key, suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteStartObject(key.AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes(key), suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteStartObject(key, suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteStartObject(key.AsSpan(), suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes(key), suppressEscaping: false); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.Equal(expectedStrNoEscape, actualStr); + else + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteArrayWithProperty(bool formatted, bool skipValidation) + { + string expectedStr = GetArrayWithPropertyExpectedString(prettyPrint: formatted); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 3; i++) + { + var output = new ArrayFormatter(1024); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteStartArray("message", suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteStartArray("message".AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("message"), suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndArray(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, true, "message")] + [InlineData(true, false, true, "message")] + [InlineData(false, true, true, "message")] + [InlineData(false, false, true, "message")] + [InlineData(true, true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, true, false, "message")] + [InlineData(true, false, false, "message")] + [InlineData(false, true, false, "message")] + [InlineData(false, false, false, "message")] + [InlineData(true, true, false, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteBooleanValue(bool formatted, bool skipValidation, bool value, string keyString) + { + string expectedStr = GetBooleanExpectedString(prettyPrint: formatted, keyString, value, escape: true); + string expectedStrNoEscape = GetBooleanExpectedString(prettyPrint: formatted, keyString, value, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteBoolean(keyString, value, suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteBoolean(keyString.AsSpan(), value, suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value, suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteBoolean(keyString, value, suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteBoolean(keyString.AsSpan(), value, suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value, suppressEscaping: false); + break; + } + + jsonUtf8.WriteStartArray("temp"); + jsonUtf8.WriteBooleanValue(true); + jsonUtf8.WriteBooleanValue(true); + jsonUtf8.WriteBooleanValue(false); + jsonUtf8.WriteBooleanValue(false); + jsonUtf8.WriteEndArray(); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.True(expectedStrNoEscape == actualStr, $"Case: {i}, | Expected: {expectedStrNoEscape}, | Actual: {actualStr}, | Value: {value}"); + else + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}, | Value: {value}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, "message")] + [InlineData(true, false, "message")] + [InlineData(false, true, "message")] + [InlineData(false, false, "message")] + [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteNullValue(bool formatted, bool skipValidation, string keyString) + { + string expectedStr = GetNullExpectedString(prettyPrint: formatted, keyString, escape: true); + string expectedStrNoEscape = GetNullExpectedString(prettyPrint: formatted, keyString, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteNull(keyString, suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteNull(keyString.AsSpan(), suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString), suppressEscaping: true); + break; + case 3: + jsonUtf8.WriteNull(keyString, suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteNull(keyString.AsSpan(), suppressEscaping: false); + break; + case 5: + jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString), suppressEscaping: false); + break; + } + + jsonUtf8.WriteStartArray("temp"); + jsonUtf8.WriteNullValue(); + jsonUtf8.WriteNullValue(); + jsonUtf8.WriteEndArray(); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.True(expectedStrNoEscape == actualStr, $"Case: {i}, | Expected: {expectedStrNoEscape}, | Actual: {actualStr}"); + else + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, 0)] + [InlineData(true, false, 0)] + [InlineData(false, true, 0)] + [InlineData(false, false, 0)] + [InlineData(true, true, -1)] + [InlineData(true, false, -1)] + [InlineData(false, true, -1)] + [InlineData(false, false, -1)] + [InlineData(true, true, 1)] + [InlineData(true, false, 1)] + [InlineData(false, true, 1)] + [InlineData(false, false, 1)] + [InlineData(true, true, int.MaxValue)] + [InlineData(true, false, int.MaxValue)] + [InlineData(false, true, int.MaxValue)] + [InlineData(false, false, int.MaxValue)] + [InlineData(true, true, int.MinValue)] + [InlineData(true, false, int.MinValue)] + [InlineData(false, true, int.MinValue)] + [InlineData(false, false, int.MinValue)] + [InlineData(true, true, 12345)] + [InlineData(true, false, 12345)] + [InlineData(false, true, 12345)] + [InlineData(false, false, 12345)] + public void WriteIntegerValue(bool formatted, bool skipValidation, int value) + { + string expectedStr = GetIntegerExpectedString(prettyPrint: formatted, value); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 3; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteNumber("message", value, suppressEscaping: true); + break; + case 1: + jsonUtf8.WriteNumber("message".AsSpan(), value, suppressEscaping: true); + break; + case 2: + jsonUtf8.WriteNumber(Encoding.UTF8.GetBytes("message"), value, suppressEscaping: true); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.True(expectedStr == actualStr, $"Case: {i}, | Expected: {expectedStr}, | Actual: {actualStr}, | Value: {value}"); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, "message")] + [InlineData(true, false, "message")] + [InlineData(false, true, "message")] + [InlineData(false, false, "message")] + [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteNumbers(bool formatted, bool skipValidation, string keyString) + { + var random = new Random(42); + const int numberOfItems = 1_000; + + var ints = new int[numberOfItems]; + ints[0] = 0; + ints[1] = int.MaxValue; + ints[2] = int.MinValue; + ints[3] = 12345; + ints[4] = -12345; + for (int i = 5; i < numberOfItems; i++) + { + ints[i] = random.Next(int.MinValue, int.MaxValue); + } + + var uints = new uint[numberOfItems]; + uints[0] = uint.MaxValue; + uints[1] = uint.MinValue; + uints[2] = 3294967295; + for (int i = 3; i < numberOfItems; i++) + { + uint thirtyBits = (uint)random.Next(1 << 30); + uint twoBits = (uint)random.Next(1 << 2); + uint fullRange = (thirtyBits << 2) | twoBits; + uints[i] = fullRange; + } + + var longs = new long[numberOfItems]; + longs[0] = 0; + longs[1] = long.MaxValue; + longs[2] = long.MinValue; + longs[3] = 12345678901; + longs[4] = -12345678901; + for (int i = 5; i < numberOfItems; i++) + { + long value = random.Next(int.MinValue, int.MaxValue); + value += value < 0 ? int.MinValue : int.MaxValue; + longs[i] = value; + } + + var ulongs = new ulong[numberOfItems]; + ulongs[0] = ulong.MaxValue; + ulongs[1] = ulong.MinValue; + ulongs[2] = 10446744073709551615; + for (int i = 3; i < numberOfItems; i++) + { + + } + + var doubles = new double[numberOfItems * 2]; + doubles[0] = 0.00; + doubles[1] = double.MaxValue; + doubles[2] = double.MinValue; + doubles[3] = 12.345e1; + doubles[4] = -123.45e1; + for (int i = 5; i < numberOfItems; i++) + { + var value = random.NextDouble(); + if (value < 0.5) + { + doubles[i] = random.NextDouble() * double.MinValue; + } + else + { + doubles[i] = random.NextDouble() * double.MaxValue; + } + } + + for (int i = numberOfItems; i < numberOfItems * 2; i++) + { + var value = random.NextDouble(); + if (value < 0.5) + { + doubles[i] = random.NextDouble() * -1_000_000; + } + else + { + doubles[i] = random.NextDouble() * 1_000_000; + } + } + + var floats = new float[numberOfItems]; + floats[0] = 0.00f; + floats[1] = float.MaxValue; + floats[2] = float.MinValue; + floats[3] = 12.345e1f; + floats[4] = -123.45e1f; + for (int i = 5; i < numberOfItems; i++) + { + double mantissa = (random.NextDouble() * 2.0) - 1.0; + double exponent = Math.Pow(2.0, random.Next(-126, 128)); + floats[i] = (float)(mantissa * exponent); + } + + var decimals = new decimal[numberOfItems * 2]; + decimals[0] = (decimal)0.00; + decimals[1] = decimal.MaxValue; + decimals[2] = decimal.MinValue; + decimals[3] = (decimal)12.345e1; + decimals[4] = (decimal)-123.45e1; + for (int i = 5; i < numberOfItems; i++) + { + var value = random.NextDouble(); + if (value < 0.5) + { + decimals[i] = (decimal)(random.NextDouble() * -78E14); + } + else + { + decimals[i] = (decimal)(random.NextDouble() * 78E14); + } + } + + for (int i = numberOfItems; i < numberOfItems * 2; i++) + { + var value = random.NextDouble(); + if (value < 0.5) + { + decimals[i] = (decimal)(random.NextDouble() * -1_000_000); + } + else + { + decimals[i] = (decimal)(random.NextDouble() * 1_000_000); + } + } + + string expectedStr = GetNumbersExpectedString(prettyPrint: formatted, keyString, ints, uints, longs, ulongs, floats, doubles, decimals, escape: false); + string expectedStrNoEscape = GetNumbersExpectedString(prettyPrint: formatted, keyString, ints, uints, longs, ulongs, floats, doubles, decimals, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int j = 0; j < 6; j++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + ReadOnlySpan keyUtf16 = keyString; + ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); + + jsonUtf8.WriteStartObject(); + + switch (j) + { + case 0: + for (int i = 0; i < floats.Length; i++) + jsonUtf8.WriteNumber(keyString, floats[i], suppressEscaping: true); + for (int i = 0; i < ints.Length; i++) + jsonUtf8.WriteNumber(keyString, ints[i], suppressEscaping: true); + for (int i = 0; i < uints.Length; i++) + jsonUtf8.WriteNumber(keyString, uints[i], suppressEscaping: true); + for (int i = 0; i < doubles.Length; i++) + jsonUtf8.WriteNumber(keyString, doubles[i], suppressEscaping: true); + for (int i = 0; i < longs.Length; i++) + jsonUtf8.WriteNumber(keyString, longs[i], suppressEscaping: true); + for (int i = 0; i < ulongs.Length; i++) + jsonUtf8.WriteNumber(keyString, ulongs[i], suppressEscaping: true); + for (int i = 0; i < decimals.Length; i++) + jsonUtf8.WriteNumber(keyString, decimals[i], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + break; + case 1: + for (int i = 0; i < floats.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, floats[i], suppressEscaping: true); + for (int i = 0; i < ints.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, ints[i], suppressEscaping: true); + for (int i = 0; i < uints.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, uints[i], suppressEscaping: true); + for (int i = 0; i < doubles.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, doubles[i], suppressEscaping: true); + for (int i = 0; i < longs.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, longs[i], suppressEscaping: true); + for (int i = 0; i < ulongs.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, ulongs[i], suppressEscaping: true); + for (int i = 0; i < decimals.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, decimals[i], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + break; + case 2: + for (int i = 0; i < floats.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, floats[i], suppressEscaping: true); + for (int i = 0; i < ints.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, ints[i], suppressEscaping: true); + for (int i = 0; i < uints.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, uints[i], suppressEscaping: true); + for (int i = 0; i < doubles.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, doubles[i], suppressEscaping: true); + for (int i = 0; i < longs.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, longs[i], suppressEscaping: true); + for (int i = 0; i < ulongs.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, ulongs[i], suppressEscaping: true); + for (int i = 0; i < decimals.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, decimals[i], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + break; + case 3: + for (int i = 0; i < floats.Length; i++) + jsonUtf8.WriteNumber(keyString, floats[i], suppressEscaping: false); + for (int i = 0; i < ints.Length; i++) + jsonUtf8.WriteNumber(keyString, ints[i], suppressEscaping: false); + for (int i = 0; i < uints.Length; i++) + jsonUtf8.WriteNumber(keyString, uints[i], suppressEscaping: false); + for (int i = 0; i < doubles.Length; i++) + jsonUtf8.WriteNumber(keyString, doubles[i], suppressEscaping: false); + for (int i = 0; i < longs.Length; i++) + jsonUtf8.WriteNumber(keyString, longs[i], suppressEscaping: false); + for (int i = 0; i < ulongs.Length; i++) + jsonUtf8.WriteNumber(keyString, ulongs[i], suppressEscaping: false); + for (int i = 0; i < decimals.Length; i++) + jsonUtf8.WriteNumber(keyString, decimals[i], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + break; + case 4: + for (int i = 0; i < floats.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, floats[i], suppressEscaping: false); + for (int i = 0; i < ints.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, ints[i], suppressEscaping: false); + for (int i = 0; i < uints.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, uints[i], suppressEscaping: false); + for (int i = 0; i < doubles.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, doubles[i], suppressEscaping: false); + for (int i = 0; i < longs.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, longs[i], suppressEscaping: false); + for (int i = 0; i < ulongs.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, ulongs[i], suppressEscaping: false); + for (int i = 0; i < decimals.Length; i++) + jsonUtf8.WriteNumber(keyUtf16, decimals[i], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + break; + case 5: + for (int i = 0; i < floats.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, floats[i], suppressEscaping: false); + for (int i = 0; i < ints.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, ints[i], suppressEscaping: false); + for (int i = 0; i < uints.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, uints[i], suppressEscaping: false); + for (int i = 0; i < doubles.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, doubles[i], suppressEscaping: false); + for (int i = 0; i < longs.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, longs[i], suppressEscaping: false); + for (int i = 0; i < ulongs.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, ulongs[i], suppressEscaping: false); + for (int i = 0; i < decimals.Length; i++) + jsonUtf8.WriteNumber(keyUtf8, decimals[i], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + break; + } + + jsonUtf8.WriteNumberValue(floats[0]); + jsonUtf8.WriteNumberValue(ints[0]); + jsonUtf8.WriteNumberValue(uints[0]); + jsonUtf8.WriteNumberValue(doubles[0]); + jsonUtf8.WriteNumberValue(longs[0]); + jsonUtf8.WriteNumberValue(ulongs[0]); + jsonUtf8.WriteNumberValue(decimals[0]); + jsonUtf8.WriteEndArray(); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + // TODO: The output doesn't match what JSON.NET does (different rounding/e-notation). + //if (j < 3) + // Assert.Equal(expectedStrNoEscape, actualStr); + //else + // Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, "message")] + [InlineData(true, false, "message")] + [InlineData(false, true, "message")] + [InlineData(false, false, "message")] + [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteGuidsValue(bool formatted, bool skipValidation, string keyString) + { + const int numberOfItems = 1_000; + + var guids = new Guid[numberOfItems]; + for (int i = 0; i < numberOfItems; i++) + guids[i] = Guid.NewGuid(); + + string expectedStr = GetGuidsExpectedString(prettyPrint: formatted, keyString, guids, escape: true); + string expectedStrNoEscape = GetGuidsExpectedString(prettyPrint: formatted, keyString, guids, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + ReadOnlySpan keyUtf16 = keyString; + ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyString, guids[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + break; + case 1: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf16, guids[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + break; + case 2: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf8, guids[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + break; + case 3: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyString, guids[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + break; + case 4: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf16, guids[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + break; + case 5: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf8, guids[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + break; + } + + jsonUtf8.WriteStringValue(guids[0]); + jsonUtf8.WriteStringValue(guids[1]); + jsonUtf8.WriteEndArray(); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.Equal(expectedStrNoEscape, actualStr); + else + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, "message")] + [InlineData(true, false, "message")] + [InlineData(false, true, "message")] + [InlineData(false, false, "message")] + [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteDateTimesValue(bool formatted, bool skipValidation, string keyString) + { + var random = new Random(42); + const int numberOfItems = 1_000; + + var start = new DateTime(1995, 1, 1); + int range = (DateTime.Today - start).Days; + + var dates = new DateTime[numberOfItems]; + for (int i = 0; i < numberOfItems; i++) + dates[i] = start.AddDays(random.Next(range)); + + string expectedStr = GetDatesExpectedString(prettyPrint: formatted, keyString, dates, escape: true); + string expectedStrNoEscape = GetDatesExpectedString(prettyPrint: formatted, keyString, dates, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + ReadOnlySpan keyUtf16 = keyString; + ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + break; + case 1: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + break; + case 2: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + break; + case 3: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + break; + case 4: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + break; + case 5: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + break; + } + + jsonUtf8.WriteStringValue(dates[0]); + jsonUtf8.WriteStringValue(dates[1]); + jsonUtf8.WriteEndArray(); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.Equal(expectedStrNoEscape, actualStr); + else + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [InlineData(true, true, "message")] + [InlineData(true, false, "message")] + [InlineData(false, true, "message")] + [InlineData(false, false, "message")] + [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] + public void WriteDateTimeOffsetsValue(bool formatted, bool skipValidation, string keyString) + { + var random = new Random(42); + const int numberOfItems = 1_000; + + var start = new DateTime(1995, 1, 1); + int range = (DateTime.Today - start).Days; + + var dates = new DateTimeOffset[numberOfItems]; + for (int i = 0; i < numberOfItems; i++) + dates[i] = new DateTimeOffset(start.AddDays(random.Next(range))); + + string expectedStr = GetDatesExpectedString(prettyPrint: formatted, keyString, dates, escape: true); + string expectedStrNoEscape = GetDatesExpectedString(prettyPrint: formatted, keyString, dates, escape: false); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + ReadOnlySpan keyUtf16 = keyString; + ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); + + for (int i = 0; i < 6; i++) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + break; + case 1: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + break; + case 2: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: true); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + break; + case 3: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + break; + case 4: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + break; + case 5: + for (int j = 0; j < numberOfItems; j++) + jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: false); + jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + break; + } + + jsonUtf8.WriteStringValue(dates[0]); + jsonUtf8.WriteStringValue(dates[1]); + jsonUtf8.WriteEndArray(); + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + if (i < 3) + Assert.Equal(expectedStrNoEscape, actualStr); + else + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + + [Theory] + [OuterLoop] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + Span key = new byte[1_000_000_001]; + key.Fill((byte)'a'); + Span value = new byte[1_000_000_001]; + value.Fill((byte)'b'); + + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteString(key, DateTime.Now, suppressEscaping: true); + Assert.True(false, $"Expected ArgumentException for data too large wasn't thrown. KeyLength: {key.Length}"); + } + catch (ArgumentException) { } + + try + { + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteStringValue(value, suppressEscaping: true); + Assert.True(false, $"Expected ArgumentException for data too large wasn't thrown. ValueLength: {value.Length}"); + } + catch (ArgumentException) { } + + output.Dispose(); + } + + [Theory] + [OuterLoop] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteLargeKeyValue(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + Span key = new byte[1_000_000_001]; + key.Fill((byte)'a'); + Span value = new byte[1_000_000_001]; + value.Fill((byte)'b'); + + WriteTooLargeHelper(state, key, value); + WriteTooLargeHelper(state, key.Slice(0, 1_000_000_000), value); + WriteTooLargeHelper(state, key, value.Slice(0, 1_000_000_000)); + WriteTooLargeHelper(state, key.Slice(0, 10_000_000 / 3), value.Slice(0, 10_000_000 / 3), noThrow: true); + } + + private static void WriteTooLargeHelper(JsonWriterState state, ReadOnlySpan key, ReadOnlySpan value, bool noThrow = false) + { + var output = new ArrayFormatter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + try + { + jsonUtf8.WriteString(key, value, suppressEscaping: true); + + if (!noThrow) + { + Assert.True(false, $"Expected ArgumentException for data too large wasn't thrown. KeyLength: {key.Length} | ValueLength: {value.Length}"); + } + } + catch (ArgumentException) + { + if (noThrow) + { + Assert.True(false, $"Expected writing large key/value to succeed. KeyLength: {key.Length} | ValueLength: {value.Length}"); + } + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + output.Dispose(); + } + + private static void WriterDidNotThrow(bool skipValidation) + { + if (skipValidation) + Assert.True(true, "Did not expect JsonWriterException to be thrown since validation was skipped."); + else + Assert.True(false, "Expected JsonWriterException to be thrown when validation is enabled."); + } + + private static void AssertWriterThrow(bool noThrow) + { + if (noThrow) + Assert.True(true, "Did not expect JsonWriterException to be thrown since input was valid (or suppressEscaping was true)."); + else + Assert.True(false, "Expected JsonWriterException to be thrown when user passes invalid UTF-8."); + } + + private static string GetHelloWorldExpectedString(bool prettyPrint) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + json.WritePropertyName("message"); + json.WriteValue("Hello, World!"); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetCommentExpectedString(bool prettyPrint, string comment) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + }; + + json.WriteStartArray(); + for (int j = 0; j < 10; j++) + json.WriteComment(comment); + json.WriteValue(comment); + json.WriteComment(comment); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetStringsExpectedString(bool prettyPrint, string value) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartArray(); + for (int j = 0; j < 10; j++) + json.WriteValue(value); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetEscapedExpectedString(bool prettyPrint, string propertyName, string value, StringEscapeHandling escaping, bool escape = true) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = escaping + }; + + json.WriteStartObject(); + json.WritePropertyName(propertyName, escape); + json.WriteValue(value); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetCustomExpectedString(bool prettyPrint) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + for (int i = 0; i < 1_000; i++) + { + json.WritePropertyName("message"); + json.WriteValue("Hello, World!"); + } + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetStartEndExpectedString(bool prettyPrint) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartArray(); + json.WriteStartObject(); + json.WriteEnd(); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetStartEndWithPropertyArrayExpectedString(bool prettyPrint) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + json.WritePropertyName("property name"); + json.WriteStartArray(); + json.WriteEnd(); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetStartEndWithPropertyArrayExpectedString(string key, bool prettyPrint, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml + }; + + json.WriteStartObject(); + json.WritePropertyName(key, escape); + json.WriteStartArray(); + json.WriteEnd(); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetStartEndWithPropertyObjectExpectedString(bool prettyPrint) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + json.WritePropertyName("property name"); + json.WriteStartObject(); + json.WriteEnd(); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetStartEndWithPropertyObjectExpectedString(string key, bool prettyPrint, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml + }; + + json.WriteStartObject(); + json.WritePropertyName(key, escape); + json.WriteStartObject(); + json.WriteEnd(); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetArrayWithPropertyExpectedString(bool prettyPrint) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + json.WritePropertyName("message"); + json.WriteStartArray(); + json.WriteEndArray(); + json.WriteEndObject(); + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetBooleanExpectedString(bool prettyPrint, string keyString, bool value, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + }; + + json.WriteStartObject(); + json.WritePropertyName(keyString, escape); + json.WriteValue(value); + + json.WritePropertyName("temp"); + json.WriteStartArray(); + json.WriteValue(true); + json.WriteValue(true); + json.WriteValue(false); + json.WriteValue(false); + json.WriteEnd(); + + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetNullExpectedString(bool prettyPrint, string keyString, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + }; + + json.WriteStartObject(); + json.WritePropertyName(keyString, escape); + json.WriteNull(); + + json.WritePropertyName("temp"); + json.WriteStartArray(); + json.WriteValue((string)null); + json.WriteValue((string)null); + json.WriteEnd(); + + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetIntegerExpectedString(bool prettyPrint, int value) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + json.WritePropertyName("message"); + json.WriteValue(value); + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetNumbersExpectedString(bool prettyPrint, string keyString, int[] ints, uint[] uints, long[] longs, ulong[] ulongs, float[] floats, double[] doubles, decimal[] decimals, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None + }; + + json.WriteStartObject(); + + for (int i = 0; i < floats.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(floats[i]); + } + for (int i = 0; i < ints.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(ints[i]); + } + for (int i = 0; i < uints.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(uints[i]); + } + for (int i = 0; i < doubles.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(doubles[i]); + } + for (int i = 0; i < longs.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(longs[i]); + } + for (int i = 0; i < ulongs.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(ulongs[i]); + } + for (int i = 0; i < decimals.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(decimals[i]); + } + + json.WritePropertyName(keyString, escape); + json.WriteStartArray(); + json.WriteValue(floats[0]); + json.WriteValue(ints[0]); + json.WriteValue(uints[0]); + json.WriteValue(doubles[0]); + json.WriteValue(longs[0]); + json.WriteValue(ulongs[0]); + json.WriteValue(decimals[0]); + json.WriteEndArray(); + + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetGuidsExpectedString(bool prettyPrint, string keyString, Guid[] guids, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml + }; + + json.WriteStartObject(); + + for (int i = 0; i < guids.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(guids[i]); + } + + json.WritePropertyName(keyString, escape); + json.WriteStartArray(); + json.WriteValue(guids[0]); + json.WriteValue(guids[1]); + json.WriteEnd(); + + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetDatesExpectedString(bool prettyPrint, string keyString, DateTime[] dates, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + DateFormatString = "G" + }; + + json.WriteStartObject(); + + for (int i = 0; i < dates.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(dates[i]); + } + + json.WritePropertyName(keyString, escape); + json.WriteStartArray(); + json.WriteValue(dates[0]); + json.WriteValue(dates[1]); + json.WriteEnd(); + + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + + private static string GetDatesExpectedString(bool prettyPrint, string keyString, DateTimeOffset[] dates, bool escape = false) + { + MemoryStream ms = new MemoryStream(); + TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); + + var json = new JsonTextWriter(streamWriter) + { + Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + DateFormatString = "MM/dd/yyyy HH:mm:ss zzz" + }; + + json.WriteStartObject(); + + for (int i = 0; i < dates.Length; i++) + { + json.WritePropertyName(keyString, escape); + json.WriteValue(dates[i]); + } + + json.WritePropertyName(keyString, escape); + json.WriteStartArray(); + json.WriteValue(dates[0]); + json.WriteValue(dates[1]); + json.WriteEnd(); + + json.WriteEnd(); + + json.Flush(); + + return Encoding.UTF8.GetString(ms.ToArray()); + } + } +} From 9bec4782491ea4d782d0385956de723930e8b5a6 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Tue, 8 Jan 2019 01:20:57 -0800 Subject: [PATCH 10/33] Change GetCurrentState back to a property and explicitly Flush on the callers behalf instead of throwing. --- src/System.Text.Json/ref/System.Text.Json.cs | 2 +- .../src/Resources/Strings.resx | 3 -- .../src/System/Text/Json/ThrowHelper.cs | 5 --- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 36 +++++++++---------- .../tests/Utf8JsonWriterTests.cs | 27 ++++++-------- 5 files changed, 30 insertions(+), 43 deletions(-) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index 2e8076419221..4c197b8ba8bd 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -96,8 +96,8 @@ public ref partial struct Utf8JsonWriter public long BytesCommitted { get { throw null; } } public long BytesWritten { get { throw null; } } public int CurrentDepth { get { throw null; } } + public System.Text.Json.JsonWriterState CurrentState { get { throw null; } } public void Flush(bool isFinalBlock = true) { } - public System.Text.Json.JsonWriterState GetCurrentState() { throw null; } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { } diff --git a/src/System.Text.Json/src/Resources/Strings.resx b/src/System.Text.Json/src/Resources/Strings.resx index 76d0c7b48aa9..66e20d59e480 100644 --- a/src/System.Text.Json/src/Resources/Strings.resx +++ b/src/System.Text.Json/src/Resources/Strings.resx @@ -120,9 +120,6 @@ CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON array. - - The JSON writer needs to be flushed before getting the current state. There are {0} bytes that have not been committed to the output. - Cannot write the start of an object or array after a single JSON value. Current token type is '{0}'. diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index a16a9bc195ba..7e4e88b25ac7 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -25,11 +25,6 @@ public static void ThrowArgumentException(string message) throw GetArgumentException(message); } - public static InvalidOperationException GetInvalidOperationException_CallFlushFirst(int _buffered) - { - return new InvalidOperationException(SR.Format(SR.CallFlushToAvoidDataLoss, _buffered)); - } - public static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength) { throw GetArgumentException(SR.Format(SR.PropertyNameTooLarge, tokenLength)); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 16a8e91734dd..32d8d0dcfae6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -77,27 +77,27 @@ public long BytesWritten /// across async/await boundaries and hence this type is required to provide support for reading /// in more data asynchronously before continuing with a new instance of the . /// - /// - /// Thrown when there is JSON data that has been written and buffered but not yet flushed to the . - /// Getting the state for creating a new without first committing the data that has been written - /// would result in an inconsistent state. Call Flush before getting the current state. - /// - public JsonWriterState GetCurrentState() + public JsonWriterState CurrentState { - if (_buffered != 0) + get { - throw ThrowHelper.GetInvalidOperationException_CallFlushFirst(_buffered); + // Getting the state for creating a new Utf8JsonWriter without first committing the data that has been written + // would result in an inconsistent state. Therefore, calling Flush before getting the current state. + if (_buffered != 0) + { + Flush(); + } + return new JsonWriterState + { + _bytesWritten = BytesWritten, + _bytesCommitted = BytesCommitted, + _inObject = _inObject, + _isNotPrimitive = _isNotPrimitive, + _tokenType = _tokenType, + _writerOptions = _writerOptions, + _bitStack = _bitStack, + }; } - return new JsonWriterState - { - _bytesWritten = BytesWritten, - _bytesCommitted = BytesCommitted, - _inObject = _inObject, - _isNotPrimitive = _isNotPrimitive, - _tokenType = _tokenType, - _writerOptions = _writerOptions, - _bitStack = _bitStack, - }; } /// diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 181cdda2664f..21d60113cfe3 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -794,7 +794,7 @@ public void WritePartialHelloWorld(bool formatted, bool skipValidation) Assert.Equal(0, state.BytesCommitted); Assert.Equal(0, state.BytesWritten); - state = jsonUtf8.GetCurrentState(); + state = jsonUtf8.CurrentState; Assert.Equal(jsonUtf8.BytesCommitted, state.BytesCommitted); Assert.Equal(jsonUtf8.BytesWritten, state.BytesWritten); @@ -818,7 +818,7 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.CurrentDepth); jsonUtf8.Flush(isFinalBlock: false); - state = jsonUtf8.GetCurrentState(); + state = jsonUtf8.CurrentState; Assert.Equal(1, state.BytesCommitted); Assert.Equal(1, state.BytesWritten); @@ -839,7 +839,7 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) Assert.Equal(1, state.BytesCommitted); Assert.Equal(1, state.BytesWritten); - state = jsonUtf8.GetCurrentState(); + state = jsonUtf8.CurrentState; if (formatted) { @@ -874,7 +874,7 @@ public void WriteInvalidPartialJson(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: false); - state = jsonUtf8.GetCurrentState(); + state = jsonUtf8.CurrentState; Assert.Equal(1, state.BytesCommitted); Assert.Equal(1, state.BytesWritten); @@ -914,19 +914,14 @@ public void WritePartialJsonSkipFlush(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.CurrentDepth); - try - { - state = jsonUtf8.GetCurrentState(); - } - catch (InvalidOperationException) - { - } - finally - { - jsonUtf8.Flush(isFinalBlock: false); - } + state = jsonUtf8.CurrentState; + + if (formatted) + Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, state.BytesWritten); + else + Assert.Equal(26, state.BytesWritten); - state = jsonUtf8.GetCurrentState(); + Assert.Equal(jsonUtf8.BytesWritten, jsonUtf8.BytesCommitted); jsonUtf8 = new Utf8JsonWriter(output, state); Assert.Equal(0, jsonUtf8.CurrentDepth); From 53855742bedf6970a9f0779abf9794f188b87192 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Tue, 8 Jan 2019 02:22:28 -0800 Subject: [PATCH 11/33] Save current depth as part of state and update tests. --- .../src/Resources/Strings.resx | 4 +- .../src/System/Text/Json/ThrowHelper.cs | 6 +- .../Text/Json/Writer/JsonWriterState.cs | 2 + .../System/Text/Json/Writer/Utf8JsonWriter.cs | 7 +- .../tests/Utf8JsonWriterTests.cs | 66 +++++++++++++++++-- 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/System.Text.Json/src/Resources/Strings.resx b/src/System.Text.Json/src/Resources/Strings.resx index 66e20d59e480..fb87f557a5ed 100644 --- a/src/System.Text.Json/src/Resources/Strings.resx +++ b/src/System.Text.Json/src/Resources/Strings.resx @@ -120,8 +120,8 @@ CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON array. - - Cannot write the start of an object or array after a single JSON value. Current token type is '{0}'. + + Cannot write the start of an object/array after a single JSON value or outside of an existing closed object/array. Current token type is '{0}'. Cannot write the start of an object or array without a property name. Current token type is '{0}'. diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index 7e4e88b25ac7..ef6bc4b9bb23 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -346,8 +346,8 @@ private static string GetResourceString(ExceptionResource resource, int currentD case ExceptionResource.CannotStartObjectArrayWithoutProperty: message = SR.Format(SR.CannotStartObjectArrayWithoutProperty, tokenType); break; - case ExceptionResource.CannotStartObjectArrayAfterPrimitive: - message = SR.Format(SR.CannotStartObjectArrayAfterPrimitive, tokenType); + case ExceptionResource.CannotStartObjectArrayAfterPrimitiveOrClose: + message = SR.Format(SR.CannotStartObjectArrayAfterPrimitiveOrClose, tokenType); break; case ExceptionResource.CannotWriteValueWithinObject: message = SR.Format(SR.CannotWriteValueWithinObject, tokenType); @@ -396,7 +396,7 @@ internal enum ExceptionResource ZeroDepthAtEnd, DepthTooLarge, CannotStartObjectArrayWithoutProperty, - CannotStartObjectArrayAfterPrimitive, + CannotStartObjectArrayAfterPrimitiveOrClose, CannotWriteValueWithinObject, CannotWriteValueAfterPrimitive, FailedToGetMinimumSizeSpan, diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs index 4b98dfff28d0..c9420aaf143d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs @@ -19,6 +19,7 @@ public struct JsonWriterState internal bool _inObject; internal bool _isNotPrimitive; internal JsonTokenType _tokenType; + internal int _currentDepth; internal JsonWriterOptions _writerOptions; internal BitStack _bitStack; @@ -53,6 +54,7 @@ public JsonWriterState(JsonWriterOptions options = default) _inObject = default; _isNotPrimitive = default; _tokenType = default; + _currentDepth = default; _writerOptions = options; // Only allocate if the user writes a JSON payload beyond the depth that the _allocationFreeContainer can handle. diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 32d8d0dcfae6..05199f30f819 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -94,6 +94,7 @@ public JsonWriterState CurrentState _inObject = _inObject, _isNotPrimitive = _isNotPrimitive, _tokenType = _tokenType, + _currentDepth = _currentDepth, _writerOptions = _writerOptions, _bitStack = _bitStack, }; @@ -126,7 +127,7 @@ public Utf8JsonWriter(IBufferWriter bufferWriter, JsonWriterState state = _writerOptions = state._writerOptions; _bitStack = state._bitStack; - _currentDepth = 0; + _currentDepth = state._currentDepth; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -258,9 +259,9 @@ private void ValidateStart() else { Debug.Assert(_tokenType != JsonTokenType.StartObject); - if (_tokenType != JsonTokenType.None && !_isNotPrimitive) + if (_tokenType != JsonTokenType.None && (!_isNotPrimitive || CurrentDepth == 0)) { - ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotStartObjectArrayAfterPrimitive, tokenType: _tokenType); + ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotStartObjectArrayAfterPrimitiveOrClose, tokenType: _tokenType); } } } diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 21d60113cfe3..eaf34a985a14 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -825,6 +825,8 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) jsonUtf8 = new Utf8JsonWriter(output, state); + Assert.Equal(1, jsonUtf8.CurrentDepth); + jsonUtf8.WriteString("message", "Hello, World!"); jsonUtf8.WriteEndObject(); jsonUtf8.Flush(); @@ -832,7 +834,7 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) Assert.Equal(jsonUtf8.BytesCommitted, jsonUtf8.BytesWritten); if (formatted) - Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); + Assert.Equal(26 + 2 + (2 * Environment.NewLine.Length) + 1, jsonUtf8.BytesCommitted); else Assert.Equal(26, jsonUtf8.BytesCommitted); @@ -843,8 +845,8 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) if (formatted) { - Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, state.BytesCommitted); - Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, state.BytesWritten); + Assert.Equal(26 + 2 + (2 * Environment.NewLine.Length) + 1, state.BytesCommitted); + Assert.Equal(26 + 2 + (2 * Environment.NewLine.Length) + 1, state.BytesWritten); } else { @@ -924,7 +926,7 @@ public void WritePartialJsonSkipFlush(bool formatted, bool skipValidation) Assert.Equal(jsonUtf8.BytesWritten, jsonUtf8.BytesCommitted); jsonUtf8 = new Utf8JsonWriter(output, state); - Assert.Equal(0, jsonUtf8.CurrentDepth); + Assert.Equal(1, jsonUtf8.CurrentDepth); Assert.Equal(0, jsonUtf8.BytesWritten); Assert.Equal(0, jsonUtf8.BytesCommitted); jsonUtf8.WriteEndObject(); @@ -933,6 +935,62 @@ public void WritePartialJsonSkipFlush(bool formatted, bool skipValidation) output.Dispose(); } + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) + { + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndObject(); + + Assert.Equal(0, jsonUtf8.CurrentDepth); + state = jsonUtf8.CurrentState; + + jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStartObject(); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new ArrayFormatter(10); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndObject(); + + Assert.Equal(0, jsonUtf8.CurrentDepth); + state = jsonUtf8.CurrentState; + + jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteStartObject("name"); + WriterDidNotThrow(skipValidation); + } + catch (JsonWriterException) { } + + output.Dispose(); + } + } + [Theory] [InlineData(true, true, "comment")] [InlineData(true, false, "comment")] From a9f99befc0e5e9f24bb7ea83574cd4180b4c6c42 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Wed, 9 Jan 2019 18:27:52 -0800 Subject: [PATCH 12/33] Fix constant names, account for quotes in bytes needed, and add fixed buffer writer tests. --- src/System.Text.Json/ref/System.Text.Json.cs | 2 +- .../src/Resources/Strings.resx | 6 + .../src/System/Text/Json/JsonConstants.cs | 18 +- .../src/System/Text/Json/ThrowHelper.cs | 27 ++- .../Json/Writer/JsonWriterHelper.Escaping.cs | 4 +- .../Text/Json/Writer/JsonWriterOptions.cs | 7 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 2 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 2 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 2 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 2 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 2 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 2 +- ...JsonWriter.WriteProperties.SignedNumber.cs | 2 +- ...onWriter.WriteProperties.UnsignedNumber.cs | 2 +- .../Utf8JsonWriter.WriteValues.DateTime.cs | 2 +- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 2 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 2 +- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 2 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 42 ++-- .../tests/FixedSizedBufferWriter.cs | 44 ++++ .../tests/System.Text.Json.Tests.csproj | 1 + .../tests/Utf8JsonWriterTests.cs | 199 +++++++++++++++++- 23 files changed, 315 insertions(+), 61 deletions(-) create mode 100644 src/System.Text.Json/tests/FixedSizedBufferWriter.cs diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index 4c197b8ba8bd..2e8076419221 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -96,8 +96,8 @@ public ref partial struct Utf8JsonWriter public long BytesCommitted { get { throw null; } } public long BytesWritten { get { throw null; } } public int CurrentDepth { get { throw null; } } - public System.Text.Json.JsonWriterState CurrentState { get { throw null; } } public void Flush(bool isFinalBlock = true) { } + public System.Text.Json.JsonWriterState GetCurrentState() { throw null; } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { } diff --git a/src/System.Text.Json/src/Resources/Strings.resx b/src/System.Text.Json/src/Resources/Strings.resx index fb87f557a5ed..1332e9402cc1 100644 --- a/src/System.Text.Json/src/Resources/Strings.resx +++ b/src/System.Text.Json/src/Resources/Strings.resx @@ -120,6 +120,9 @@ CurrentDepth ({0}) is larger than the maximum configured depth of {1}. Cannot read next JSON array. + + The JSON writer needs to be flushed before getting the current state. There are {0} bytes that have not been committed to the output. + Cannot write the start of an object/array after a single JSON value or outside of an existing closed object/array. Current token type is '{0}'. @@ -144,6 +147,9 @@ CurrentDepth ({0}) is equal to or larger than the maximum allowed depth of 1000. Cannot write the next JSON object or array. + + Writing an empty JSON payload (excluding comments) is invalid. + Expected end of comment, but instead reached end of data. diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 4fbff3bb0877..6c47c84f2114 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -38,14 +38,14 @@ internal static class JsonConstants public const int MaxTokenSize = 2_000_000_000 / 6; // 357_913_941 bytes public const int MaxCharacterTokenSize = 2_000_000_000 / 6; // 357_913_941 characters - public const int MaximumInt64Length = 20; // 19 + sign (i.e. -9223372036854775808) - public const int MaximumUInt64Length = 20; // i.e. 18446744073709551615 - public const int MaximumDoubleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. - public const int MaximumSingleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. - public const int MaximumDecimalLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. - public const int MaximumGuidLength = 36; // default (i.e. 'D') 8 + 4 + 4 + 4 + 12 + 4 for the hyphens (e.g. 094ffa0a-0442-494d-b452-04003fa755cc) - public const int MaximumDateTimeLength = 26; // default (i.e. 'G') e.g. 05/25/2017 10:30:15 -08:00 - public const int MaximumDateTimeOffsetLength = 26; // default (i.e. 'G') e.g. 05/25/2017 10:30:15 -08:00 + public const int MaximumFormatInt64Length = 20; // 19 + sign (i.e. -9223372036854775808) + public const int MaximumFormatUInt64Length = 20; // i.e. 18446744073709551615 + public const int MaximumFormatDoubleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. + public const int MaximumFormatSingleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. + public const int MaximumFormatDecimalLength = 29; // default (i.e. 'G') + public const int MaximumFormatGuidLength = 36; // default (i.e. 'D'), 8 + 4 + 4 + 4 + 12 + 4 for the hyphens (e.g. 094ffa0a-0442-494d-b452-04003fa755cc) + public const int MaximumFormatDateTimeLength = 19; // default (i.e. 'G'), e.g. 05/25/2017 10:30:15 + public const int MaximumFormatDateTimeOffsetLength = 26; // default (i.e. 'G'), e.g. 05/25/2017 10:30:15 -08:00 // Encoding Helpers public const char HighSurrogateStart = '\ud800'; @@ -53,7 +53,7 @@ internal static class JsonConstants public const char LowSurrogateStart = '\udc00'; public const char LowSurrogateEnd = '\udfff'; - public const int UnicodePlan01StartValue = 0x10000; + public const int UnicodePlane01StartValue = 0x10000; public const int HighSurrogateStartValue = 0xD800; public const int HighSurrogateEndValue = 0xDBFF; public const int LowSurrogateStartValue = 0xDC00; diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index ef6bc4b9bb23..04707e411f8f 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -25,6 +25,11 @@ public static void ThrowArgumentException(string message) throw GetArgumentException(message); } + public static InvalidOperationException GetInvalidOperationException_CallFlushFirst(int _buffered) + { + return new InvalidOperationException(SR.Format(SR.CallFlushToAvoidDataLoss, _buffered)); + } + public static void ThrowArgumentException_PropertyNameTooLarge(int tokenLength) { throw GetArgumentException(SR.Format(SR.PropertyNameTooLarge, tokenLength)); @@ -136,6 +141,25 @@ private static void GetJsonWriterOrArgumentException(ReadOnlySpan property } } + public static void ThrowJsonWriterException_DepthNonZeroOrEmptyJson(int currentDepth) + { + throw GetJsonWriterException(currentDepth); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static JsonWriterException GetJsonWriterException(int currentDepth) + { + currentDepth &= JsonConstants.RemoveFlagsBitMask; + if (currentDepth != 0) + { + return new JsonWriterException(SR.Format(SR.ZeroDepthAtEnd, currentDepth)); + } + else + { + return new JsonWriterException(SR.Format(SR.EmptyJsonIsInvalid)); + } + } + public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { GetJsonWriterOrArgumentException(propertyName, currentDepth); @@ -340,9 +364,6 @@ private static string GetResourceString(ExceptionResource resource, int currentD case ExceptionResource.DepthTooLarge: message = SR.Format(SR.DepthTooLarge, currentDepth & JsonConstants.RemoveFlagsBitMask); break; - case ExceptionResource.ZeroDepthAtEnd: - message = SR.Format(SR.ZeroDepthAtEnd, currentDepth & JsonConstants.RemoveFlagsBitMask); - break; case ExceptionResource.CannotStartObjectArrayWithoutProperty: message = SR.Format(SR.CannotStartObjectArrayWithoutProperty, tokenType); break; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 9f2a133763c4..4d9438b66ac9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -133,13 +133,13 @@ private static int EscapeNextBytes(ReadOnlySpan value, ref Span dest break; default: destination[written++] = (byte)'u'; - if (scalar < JsonConstants.UnicodePlan01StartValue) + if (scalar < JsonConstants.UnicodePlane01StartValue) { WriteHex(scalar, ref destination, ref written); } else { - int quotient = DivMod(scalar - JsonConstants.UnicodePlan01StartValue, 0x400, out int remainder); + int quotient = DivMod(scalar - JsonConstants.UnicodePlane01StartValue, 0x400, out int remainder); int firstChar = quotient + JsonConstants.HighSurrogateStartValue; int nextChar = remainder + JsonConstants.LowSurrogateStartValue; WriteHex(firstChar, ref destination, ref written); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 3596bf683fd5..40ee2a27f786 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -36,9 +36,10 @@ public bool Indented /// /// Defines whether the should skip structural validation and allow - /// the user to write invalid JSON. For example, if the user attempts to write a value within an object - /// without a property name, a is thrown. If the JSON being written is known to be correct - /// then skipping validation could improve performance. + /// the user to write invalid JSON, when set to true. If set to false, any attempts to write invalid JSON will result in + /// a to be thrown (for example, writing a value within an object + /// without a property name). If the JSON being written is known to be correct + /// then skipping validation (by setting it to true) could improve performance. /// public bool SkipValidation { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index c800aceb8dc5..9a875c16c87a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -269,7 +269,7 @@ private void FormatLoop(DateTime value, ref int idx) int bytesWritten; while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumDateTimeLength); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatDateTimeLength); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 6b4a02fd3916..1592a9f5349c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -269,7 +269,7 @@ private void FormatLoop(DateTimeOffset value, ref int idx) int bytesWritten; while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumDateTimeOffsetLength); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatDateTimeOffsetLength); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 220fa87a4f89..3e58bd0a5596 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -250,7 +250,7 @@ private void WriteNumberValueFormatLoop(decimal value, ref int idx) int bytesWritten; while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumDecimalLength); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatDecimalLength); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 94be69e7b0f1..0f1b16195fac 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -252,7 +252,7 @@ private void WriteNumberValueFormatLoop(double value, ref int idx) int bytesWritten; while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumDoubleLength); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatDoubleLength); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 31893a5ff764..da9ea2267bdf 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -252,7 +252,7 @@ private void WriteNumberValueFormatLoop(float value, ref int idx) int bytesWritten; while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumSingleLength); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatSingleLength); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index b5ee35572a01..f2fe006799b3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -269,7 +269,7 @@ private void FormatLoop(Guid value, ref int idx) int bytesWritten; while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumGuidLength); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatGuidLength); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 1a5621b1ec41..42d505ea7d97 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -297,7 +297,7 @@ private void WriteNumberValueFormatLoop(long value, ref int idx) // Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten); while (!JsonWriterHelper.TryFormatInt64Default(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumInt64Length); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatInt64Length); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index c19d08de3858..a163aa992e01 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -303,7 +303,7 @@ private void WriteNumberValueFormatLoop(ulong value, ref int idx) // Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten); while (!JsonWriterHelper.TryFormatUInt64Default(value, _buffer.Slice(idx), out bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumUInt64Length); + AdvanceAndGrow(idx, JsonConstants.MaximumFormatUInt64Length); idx = 0; } idx += bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index f63035f05c36..2d14641b4a7a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -41,7 +41,7 @@ public void WriteStringValue(DateTime value) private void WriteStringValueMinimized(DateTime value) { // Calculated based on the following: ',"DateTime value"' - int bytesNeeded = JsonConstants.MaximumDateTimeLength + 1; + int bytesNeeded = JsonConstants.MaximumFormatDateTimeLength + 3; if (_buffer.Length < bytesNeeded) { GrowAndEnsure(bytesNeeded); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index a2d5ad5d6214..23a5ceb883af 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -41,7 +41,7 @@ public void WriteStringValue(DateTimeOffset value) private void WriteStringValueMinimized(DateTimeOffset value) { // Calculated based on the following: ',"DateTimeOffset value"' - int bytesNeeded = JsonConstants.MaximumDateTimeOffsetLength + 1; + int bytesNeeded = JsonConstants.MaximumFormatDateTimeOffsetLength + 3; if (_buffer.Length < bytesNeeded) { GrowAndEnsure(bytesNeeded); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index d00318feb81d..051ab349d507 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -41,7 +41,7 @@ public void WriteStringValue(Guid value) private void WriteStringValueMinimized(Guid value) { // Calculated based on the following: ',"Guid value"' - int bytesNeeded = JsonConstants.MaximumGuidLength + 1; + int bytesNeeded = JsonConstants.MaximumFormatGuidLength + 3; if (_buffer.Length < bytesNeeded) { GrowAndEnsure(bytesNeeded); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index f556333be129..8592c8403768 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -49,7 +49,7 @@ public void WriteNumberValue(long value) private void WriteNumberValueMinimized(long value) { // Calculated based on the following: ',long.MaxValue' - int bytesNeeded = JsonConstants.MaximumInt64Length + 1; + int bytesNeeded = JsonConstants.MaximumFormatInt64Length + 1; if (_buffer.Length < bytesNeeded) { GrowAndEnsure(bytesNeeded); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 83d75329f0f7..7b94ceac18f7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -51,7 +51,7 @@ public void WriteNumberValue(ulong value) private void WriteNumberValueMinimized(ulong value) { // Calculated based on the following: ',ulong.MaxValue' - int bytesNeeded = JsonConstants.MaximumUInt64Length + 1; + int bytesNeeded = JsonConstants.MaximumFormatUInt64Length + 1; if (_buffer.Length < bytesNeeded) { GrowAndEnsure(bytesNeeded); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 05199f30f819..43edfb1551f1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -77,28 +77,28 @@ public long BytesWritten /// across async/await boundaries and hence this type is required to provide support for reading /// in more data asynchronously before continuing with a new instance of the . /// - public JsonWriterState CurrentState + /// + /// Thrown when there is JSON data that has been written and buffered but not yet flushed to the . + /// Getting the state for creating a new without first committing the data that has been written + /// would result in an inconsistent state. Call Flush before getting the current state. + /// + public JsonWriterState GetCurrentState() { - get + if (_buffered != 0) { - // Getting the state for creating a new Utf8JsonWriter without first committing the data that has been written - // would result in an inconsistent state. Therefore, calling Flush before getting the current state. - if (_buffered != 0) - { - Flush(); - } - return new JsonWriterState - { - _bytesWritten = BytesWritten, - _bytesCommitted = BytesCommitted, - _inObject = _inObject, - _isNotPrimitive = _isNotPrimitive, - _tokenType = _tokenType, - _currentDepth = _currentDepth, - _writerOptions = _writerOptions, - _bitStack = _bitStack, - }; + throw ThrowHelper.GetInvalidOperationException_CallFlushFirst(_buffered); } + return new JsonWriterState + { + _bytesWritten = BytesWritten, + _bytesCommitted = BytesCommitted, + _inObject = _inObject, + _isNotPrimitive = _isNotPrimitive, + _tokenType = _tokenType, + _currentDepth = _currentDepth, + _writerOptions = _writerOptions, + _bitStack = _bitStack, + }; } /// @@ -150,8 +150,8 @@ private void Advance(int count) /// public void Flush(bool isFinalBlock = true) { - if (isFinalBlock && !_writerOptions.SkipValidation && CurrentDepth != 0) - ThrowHelper.ThrowJsonWriterException(ExceptionResource.ZeroDepthAtEnd, _currentDepth); + if (isFinalBlock && !_writerOptions.SkipValidation && (CurrentDepth != 0 || _tokenType == JsonTokenType.None)) + ThrowHelper.ThrowJsonWriterException_DepthNonZeroOrEmptyJson(_currentDepth); Flush(); } diff --git a/src/System.Text.Json/tests/FixedSizedBufferWriter.cs b/src/System.Text.Json/tests/FixedSizedBufferWriter.cs new file mode 100644 index 000000000000..22f29ad7b18f --- /dev/null +++ b/src/System.Text.Json/tests/FixedSizedBufferWriter.cs @@ -0,0 +1,44 @@ +// 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. + +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace System.Text.Json.Tests +{ + internal class FixedSizedBufferWriter : IBufferWriter + { + private readonly byte[] _buffer; + private int _count; + + public FixedSizedBufferWriter(int capacity) + { + _buffer = new byte[capacity]; + } + + public void Clear() + { + _count = 0; + } + + public Span Free => _buffer.AsSpan(_count); + + public Span Formatted => _buffer.AsSpan(0, _count); + + public Memory GetMemory(int minimumLength = 0) => _buffer.AsMemory(_count); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Span GetSpan(int minimumLength = 0) => _buffer.AsSpan(_count); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Advance(int bytes) + { + _count += bytes; + if (_count > _buffer.Length) + { + throw new InvalidOperationException("Cannot advance past the end of the buffer."); + } + } + } +} diff --git a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj index 06e661adc656..a8c9c4036196 100644 --- a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -8,6 +8,7 @@ + diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index eaf34a985a14..8ca23b924a52 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -5,20 +5,81 @@ using Xunit; using System.IO; using Newtonsoft.Json; +using System.Globalization; namespace System.Text.Json.Tests { public class Utf8JsonWriterTests { - [Fact] - public void NullCtor() + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void NullCtor(bool formatted, bool skipValidation) { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + try { var jsonUtf8 = new Utf8JsonWriter(null); Assert.True(false, "Expected ArgumentNullException to be thrown when null IBufferWriter is passed in."); } catch (ArgumentNullException) { } + + try + { + var jsonUtf8 = new Utf8JsonWriter(null, state); + Assert.True(false, "Expected ArgumentNullException to be thrown when null IBufferWriter is passed in."); + } + catch (ArgumentNullException) { } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void FlushEmpty(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var output = new FixedSizedBufferWriter(0); + try + { + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.Flush(); + WriterDidNotThrow(skipValidation, "Expected JsonWriterException to be thrown when calling Flush on an empty JSON payload."); + } + catch (JsonWriterException) { } + + output = new FixedSizedBufferWriter(10); + try + { + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteCommentValue("hi"); + jsonUtf8.Flush(); + WriterDidNotThrow(skipValidation, "Expected JsonWriterException to be thrown when calling Flush on an empty JSON payload."); + } + catch (JsonWriterException) { } + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void FlushMultipleTimes(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var output = new FixedSizedBufferWriter(10); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + Assert.Equal(2, jsonUtf8.BytesCommitted); + jsonUtf8.Flush(); + Assert.Equal(2, jsonUtf8.BytesCommitted); } [Theory] @@ -42,6 +103,102 @@ public void InvalidBufferWriter(bool formatted, bool skipValidation) catch (ArgumentException) { } } + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void FixedSizeBufferWriter_Guid(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new FixedSizedBufferWriter(37); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + Guid guid = Guid.NewGuid(); + + try + { + jsonUtf8.WriteStringValue(guid); + Assert.True(false, "Expected ArgumentException to be thrown when IBufferWriter doesn't have enough space."); + } + catch (ArgumentException) { } + + output = new FixedSizedBufferWriter(39); + jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteStringValue(guid); + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.Equal(38, output.Formatted.Length); + Assert.Equal($"\"{guid.ToString()}\"", actualStr); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new FixedSizedBufferWriter(20); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + var date = new DateTime(2019, 1, 1); + + try + { + jsonUtf8.WriteStringValue(date); + Assert.True(false, "Expected ArgumentException to be thrown when IBufferWriter doesn't have enough space."); + } + catch (ArgumentException) { } + + output = new FixedSizedBufferWriter(30); + jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteStringValue(date); + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.Equal(21, output.Formatted.Length); + Assert.Equal($"\"{date.ToString("G", DateTimeFormatInfo.InvariantInfo)}\"", actualStr); + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValidation) + { + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + var output = new FixedSizedBufferWriter(27); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + DateTimeOffset date = new DateTime(2019, 1, 1); + + try + { + jsonUtf8.WriteStringValue(date); + Assert.True(false, "Expected ArgumentException to be thrown when IBufferWriter doesn't have enough space."); + } + catch (ArgumentException) { } + + output = new FixedSizedBufferWriter(30); + jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteStringValue(date); + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.Equal(28, output.Formatted.Length); + Assert.Equal($"\"{date.ToString("MM/dd/yyyy HH:mm:ss zzz")}\"", actualStr); + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] @@ -794,7 +951,7 @@ public void WritePartialHelloWorld(bool formatted, bool skipValidation) Assert.Equal(0, state.BytesCommitted); Assert.Equal(0, state.BytesWritten); - state = jsonUtf8.CurrentState; + state = jsonUtf8.GetCurrentState(); Assert.Equal(jsonUtf8.BytesCommitted, state.BytesCommitted); Assert.Equal(jsonUtf8.BytesWritten, state.BytesWritten); @@ -818,7 +975,7 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.CurrentDepth); jsonUtf8.Flush(isFinalBlock: false); - state = jsonUtf8.CurrentState; + state = jsonUtf8.GetCurrentState(); Assert.Equal(1, state.BytesCommitted); Assert.Equal(1, state.BytesWritten); @@ -841,7 +998,7 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) Assert.Equal(1, state.BytesCommitted); Assert.Equal(1, state.BytesWritten); - state = jsonUtf8.CurrentState; + state = jsonUtf8.GetCurrentState(); if (formatted) { @@ -876,7 +1033,7 @@ public void WriteInvalidPartialJson(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: false); - state = jsonUtf8.CurrentState; + state = jsonUtf8.GetCurrentState(); Assert.Equal(1, state.BytesCommitted); Assert.Equal(1, state.BytesWritten); @@ -916,7 +1073,20 @@ public void WritePartialJsonSkipFlush(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.CurrentDepth); - state = jsonUtf8.CurrentState; + try + { + state = jsonUtf8.GetCurrentState(); + Assert.True(false, "Expected InvalidOperationException when trying to get current state without flushing first."); + } + catch (InvalidOperationException) + { + + } + finally + { + jsonUtf8.Flush(isFinalBlock: false); + state = jsonUtf8.GetCurrentState(); + } if (formatted) Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, state.BytesWritten); @@ -950,9 +1120,11 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); Assert.Equal(0, jsonUtf8.CurrentDepth); - state = jsonUtf8.CurrentState; + + state = jsonUtf8.GetCurrentState(); jsonUtf8 = new Utf8JsonWriter(output, state); @@ -974,9 +1146,10 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); Assert.Equal(0, jsonUtf8.CurrentDepth); - state = jsonUtf8.CurrentState; + state = jsonUtf8.GetCurrentState(); jsonUtf8 = new Utf8JsonWriter(output, state); @@ -2683,6 +2856,14 @@ private static void WriterDidNotThrow(bool skipValidation) Assert.True(false, "Expected JsonWriterException to be thrown when validation is enabled."); } + private static void WriterDidNotThrow(bool skipValidation, string message) + { + if (skipValidation) + Assert.True(true, message); + else + Assert.True(false, message); + } + private static void AssertWriterThrow(bool noThrow) { if (noThrow) From 65b38cb1c287ae2655bf52e0eaeed519f74d3832 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Wed, 9 Jan 2019 18:50:46 -0800 Subject: [PATCH 13/33] Fix inconsistent use of braces by adding them for single line ifs --- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 12 +++++++ ...onWriter.WriteProperties.DateTimeOffset.cs | 12 +++++++ .../Utf8JsonWriter.WriteProperties.Decimal.cs | 12 +++++++ .../Utf8JsonWriter.WriteProperties.Double.cs | 12 +++++++ .../Utf8JsonWriter.WriteProperties.Float.cs | 12 +++++++ .../Utf8JsonWriter.WriteProperties.Guid.cs | 12 +++++++ .../Utf8JsonWriter.WriteProperties.Literal.cs | 20 ++++++++++++ ...JsonWriter.WriteProperties.SignedNumber.cs | 12 +++++++ .../Utf8JsonWriter.WriteProperties.String.cs | 32 +++++++++++++++++++ ...onWriter.WriteProperties.UnsignedNumber.cs | 12 +++++++ .../Utf8JsonWriter.WriteValues.Comment.cs | 12 +++++++ .../Utf8JsonWriter.WriteValues.String.cs | 12 +++++++ .../System/Text/Json/Writer/Utf8JsonWriter.cs | 28 ++++++++++++++++ 13 files changed, 200 insertions(+) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 9a875c16c87a..84b1262ab9f5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -42,9 +42,13 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, value); + } else + { WriteStringByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -67,9 +71,13 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, value); + } else + { WriteStringByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -135,7 +143,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date WriteStringByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) @@ -166,7 +176,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date WriteStringByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 1592a9f5349c..fcc1d1995223 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -42,9 +42,13 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, value); + } else + { WriteStringByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -67,9 +71,13 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, value); + } else + { WriteStringByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -135,7 +143,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date WriteStringByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) @@ -166,7 +176,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date WriteStringByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeOffset value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 3e58bd0a5596..c9096d6a7eaa 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -42,9 +42,13 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -67,9 +71,13 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -135,7 +143,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) @@ -166,7 +176,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 0f1b16195fac..b0a08a8d18ce 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -43,9 +43,13 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp JsonWriterHelper.ValidateDouble(value); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -69,9 +73,13 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp JsonWriterHelper.ValidateDouble(value); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -137,7 +145,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) @@ -168,7 +178,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index da9ea2267bdf..62da700c2b06 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -43,9 +43,13 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr JsonWriterHelper.ValidateSingle(value); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -69,9 +73,13 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr JsonWriterHelper.ValidateSingle(value); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -137,7 +145,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) @@ -168,7 +178,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index f2fe006799b3..808e980ac8be 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -42,9 +42,13 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, value); + } else + { WriteStringByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -67,9 +71,13 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, value); + } else + { WriteStringByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -135,7 +143,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid WriteStringByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) @@ -166,7 +176,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid WriteStringByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 9e5869f32138..31eb87e3081a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -41,9 +41,13 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f ReadOnlySpan span = JsonConstants.NullValue; if (!suppressEscaping) + { WriteLiteralSuppressFalse(ref propertyName, ref span); + } else + { WriteLiteralByOptions(ref propertyName, ref span); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Null; @@ -67,9 +71,13 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f ReadOnlySpan span = JsonConstants.NullValue; if (!suppressEscaping) + { WriteLiteralSuppressFalse(ref propertyName, ref span); + } else + { WriteLiteralByOptions(ref propertyName, ref span); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Null; @@ -109,9 +117,13 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; if (!suppressEscaping) + { WriteLiteralSuppressFalse(ref propertyName, ref span); + } else + { WriteLiteralByOptions(ref propertyName, ref span); + } _currentDepth |= 1 << 31; _tokenType = value ? JsonTokenType.True : JsonTokenType.False; @@ -136,9 +148,13 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; if (!suppressEscaping) + { WriteLiteralSuppressFalse(ref propertyName, ref span); + } else + { WriteLiteralByOptions(ref propertyName, ref span); + } _currentDepth |= 1 << 31; _tokenType = value ? JsonTokenType.True : JsonTokenType.False; @@ -204,7 +220,9 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref WriteLiteralByOptions(ref propertyName, ref value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) @@ -235,7 +253,9 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref WriteLiteralByOptions(ref propertyName, ref value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 42d505ea7d97..6d3954e73cae 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -41,9 +41,13 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -66,9 +70,13 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -179,7 +187,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) @@ -210,7 +220,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index ea4ca27894c6..73367abc08ee 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -45,9 +45,13 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, ref value); + } else + { WriteStringSuppressTrue(ref propertyName, ref value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -71,9 +75,13 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, ref value); + } else + { WriteStringSuppressTrue(ref propertyName, ref value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -113,9 +121,13 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, ref value); + } else + { WriteStringSuppressTrue(ref propertyName, ref value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -155,9 +167,13 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); if (!suppressEscaping) + { WriteStringSuppressFalse(ref propertyName, ref value); + } else + { WriteStringSuppressTrue(ref propertyName, ref value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -439,10 +455,14 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam WriteStringByOptions(ref propertyName, ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) @@ -501,10 +521,14 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam WriteStringByOptions(ref propertyName, ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) @@ -563,10 +587,14 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam WriteStringByOptions(ref propertyName, ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) @@ -625,10 +653,14 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam WriteStringByOptions(ref propertyName, ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index a163aa992e01..afdf5680ea34 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -43,9 +43,13 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -69,9 +73,13 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr JsonWriterHelper.ValidateProperty(ref propertyName); if (!suppressEscaping) + { WriteNumberSuppressFalse(ref propertyName, value); + } else + { WriteNumberByOptions(ref propertyName, value); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; @@ -185,7 +193,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) @@ -216,7 +226,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon WriteNumberByOptions(ref propertyName, value); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 2c7ddbad6c33..9a0b11b4c699 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -34,9 +34,13 @@ public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscapin JsonWriterHelper.ValidateValue(ref utf16Text); if (!suppressEscaping) + { WriteCommentSuppressFalse(ref utf16Text); + } else + { WriteCommentByOptions(ref utf16Text); + } } private void WriteCommentSuppressFalse(ref ReadOnlySpan value) @@ -134,7 +138,9 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca WriteCommentByOptions(ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } } /// @@ -150,9 +156,13 @@ public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping JsonWriterHelper.ValidateValue(ref utf8Text); if (!suppressEscaping) + { WriteCommentSuppressFalse(ref utf8Text); + } else + { WriteCommentByOptions(ref utf8Text); + } } private void WriteCommentSuppressFalse(ref ReadOnlySpan value) @@ -250,7 +260,9 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca WriteCommentByOptions(ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } } private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 9aac5a73f8dc..58eeb12c15d9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -39,9 +39,13 @@ public void WriteStringValue(ReadOnlySpan utf16Text, bool suppressEscaping JsonWriterHelper.ValidateValue(ref utf16Text); if (!suppressEscaping) + { WriteStringSuppressFalse(ref utf16Text); + } else + { WriteStringByOptions(ref utf16Text); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -166,7 +170,9 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap WriteStringByOptions(ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } } /// @@ -185,9 +191,13 @@ public void WriteStringValue(ReadOnlySpan utf8Text, bool suppressEscaping JsonWriterHelper.ValidateValue(ref utf8Text); if (!suppressEscaping) + { WriteStringSuppressFalse(ref utf8Text); + } else + { WriteStringByOptions(ref utf8Text); + } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; @@ -312,7 +322,9 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap WriteStringByOptions(ref value); if (valueArray != null) + { ArrayPool.Shared.Return(valueArray); + } } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 43edfb1551f1..c3093ded14b5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -196,9 +196,13 @@ private void WriteStart(byte token) ThrowHelper.ThrowJsonWriterException(ExceptionResource.DepthTooLarge, _currentDepth); if (_writerOptions.SlowPath) + { WriteStartSlow(token); + } else + { WriteStartMinimized(token); + } _currentDepth &= JsonConstants.RemoveFlagsBitMask; _currentDepth++; @@ -322,9 +326,13 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi ValidatePropertyNameAndDepth(ref propertyName); if (!suppressEscaping) + { WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBracket); + } else + { WriteStartByOptions(ref propertyName, JsonConstants.OpenBracket); + } _currentDepth &= JsonConstants.RemoveFlagsBitMask; _currentDepth++; @@ -349,9 +357,13 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap ValidatePropertyNameAndDepth(ref propertyName); if (!suppressEscaping) + { WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBrace); + } else + { WriteStartByOptions(ref propertyName, JsonConstants.OpenBrace); + } _currentDepth &= JsonConstants.RemoveFlagsBitMask; _currentDepth++; @@ -436,7 +448,9 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte WriteStartByOptions(ref propertyName, token); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } /// @@ -486,9 +500,13 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi ValidatePropertyNameAndDepth(ref propertyName); if (!suppressEscaping) + { WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBracket); + } else + { WriteStartByOptions(ref propertyName, JsonConstants.OpenBracket); + } _currentDepth &= JsonConstants.RemoveFlagsBitMask; _currentDepth++; @@ -513,9 +531,13 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap ValidatePropertyNameAndDepth(ref propertyName); if (!suppressEscaping) + { WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBrace); + } else + { WriteStartByOptions(ref propertyName, JsonConstants.OpenBrace); + } _currentDepth &= JsonConstants.RemoveFlagsBitMask; _currentDepth++; @@ -600,7 +622,9 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte WriteStartByOptions(ref propertyName, token); if (propertyArray != null) + { ArrayPool.Shared.Return(propertyArray); + } } /// @@ -640,9 +664,13 @@ private void WriteEnd(byte token) } if (_writerOptions.SlowPath) + { WriteEndSlow(token); + } else + { WriteEndMinimized(token); + } } private void WriteEndMinimized(byte token) From 8d62b8a1ca3e85b3a78a1a4b22461b51156ed4f2 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Wed, 9 Jan 2019 19:02:15 -0800 Subject: [PATCH 14/33] Update parameter name to exclude encoding. --- src/System.Text.Json/ref/System.Text.Json.cs | 12 ++++---- .../Text/Json/Writer/JsonWriterHelper.cs | 30 ++++++++++--------- .../Utf8JsonWriter.WriteValues.Comment.cs | 26 ++++++++-------- .../Utf8JsonWriter.WriteValues.String.cs | 26 ++++++++-------- 4 files changed, 48 insertions(+), 46 deletions(-) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index 2e8076419221..d93eaac458e2 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -102,9 +102,9 @@ public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, boo public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { } public void WriteBooleanValue(bool value) { } - public void WriteCommentValue(System.ReadOnlySpan utf8Text, bool suppressEscaping = false) { } - public void WriteCommentValue(System.ReadOnlySpan utf16Text, bool suppressEscaping = false) { } - public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) { } + public void WriteCommentValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteCommentValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteCommentValue(string value, bool suppressEscaping = false) { } public void WriteEndArray() { } public void WriteEndObject() { } public void WriteNull(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } @@ -176,8 +176,8 @@ public void WriteString(string propertyName, string value, bool suppressEscaping public void WriteStringValue(System.DateTime value) { } public void WriteStringValue(System.DateTimeOffset value) { } public void WriteStringValue(System.Guid value) { } - public void WriteStringValue(System.ReadOnlySpan utf8Text, bool suppressEscaping = false) { } - public void WriteStringValue(System.ReadOnlySpan utf16Text, bool suppressEscaping = false) { } - public void WriteStringValue(string utf16Text, bool suppressEscaping = false) { } + public void WriteStringValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteStringValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } + public void WriteStringValue(string value, bool suppressEscaping = false) { } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 4250f290ed42..df608126a2de 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -66,14 +66,14 @@ public static void ValidateValue(ref ReadOnlySpan value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateDouble(double value) { - if (double.IsPositiveInfinity(value) || double.IsNegativeInfinity(value) || double.IsNaN(value)) + if (!double.IsFinite(value)) ThrowHelper.ThrowArgumentException_ValueNotSupported(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateSingle(float value) { - if (float.IsPositiveInfinity(value) || float.IsNegativeInfinity(value) || float.IsNaN(value)) + if (!float.IsFinite(value)) ThrowHelper.ThrowArgumentException_ValueNotSupported(); } @@ -175,35 +175,37 @@ public static int CountDigits(ulong value) return digits; } + // TODO: Replace this with publicly shipping implementation: https://github.com/dotnet/corefx/issues/34094 + /// /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes. /// /// This method will consume as many of the input bytes as possible. /// /// On successful exit, the entire input was consumed and encoded successfully. In this case, will be - /// equal to the length of the and will equal the total number of bytes written to - /// the . + /// equal to the length of the and will equal the total number of bytes written to + /// the . /// - /// A span containing a sequence of UTF-16 bytes. - /// A span to write the UTF-8 bytes into. - /// On exit, contains the number of bytes that were consumed from the . - /// On exit, contains the number of bytes written to + /// A span containing a sequence of UTF-16 bytes. + /// A span to write the UTF-8 bytes into. + /// On exit, contains the number of bytes that were consumed from the . + /// On exit, contains the number of bytes written to /// A value representing the state of the conversion. - public unsafe static OperationStatus ToUtf8(ReadOnlySpan source, Span destination, out int bytesConsumed, out int bytesWritten) + public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span utf8Destination, out int bytesConsumed, out int bytesWritten) { // // - // KEEP THIS IMPLEMENTATION IN SYNC WITH https://github.com/dotnet/corert/blob/8f8922888687236cc5614bc3d06663ea5986dcb7/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs#L841 + // KEEP THIS IMPLEMENTATION IN SYNC WITH https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs#L841 // // - fixed (byte* chars = &MemoryMarshal.GetReference(source)) - fixed (byte* bytes = &MemoryMarshal.GetReference(destination)) + fixed (byte* chars = &MemoryMarshal.GetReference(utf16Source)) + fixed (byte* bytes = &MemoryMarshal.GetReference(utf8Destination)) { char* pSrc = (char*)chars; byte* pTarget = bytes; - char* pEnd = (char*)(chars + source.Length); - byte* pAllocatedBufferEnd = pTarget + destination.Length; + char* pEnd = (char*)(chars + utf16Source.Length); + byte* pAllocatedBufferEnd = pTarget + utf8Destination.Length; // assume that JIT will enregister pSrc, pTarget and ch diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 9a0b11b4c699..230002931f71 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -13,33 +13,33 @@ public ref partial struct Utf8JsonWriter /// /// Writes the UTF-16 text value (as a JSON comment). /// - /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(string utf16Text, bool suppressEscaping = false) - => WriteCommentValue(utf16Text.AsSpan(), suppressEscaping); + public void WriteCommentValue(string value, bool suppressEscaping = false) + => WriteCommentValue(value.AsSpan(), suppressEscaping); /// /// Writes the UTF-16 text value (as a JSON comment). /// - /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) + public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref utf16Text); + JsonWriterHelper.ValidateValue(ref value); if (!suppressEscaping) { - WriteCommentSuppressFalse(ref utf16Text); + WriteCommentSuppressFalse(ref value); } else { - WriteCommentByOptions(ref utf16Text); + WriteCommentByOptions(ref value); } } @@ -146,22 +146,22 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca /// /// Writes the UTF-8 text value (as a JSON comment). /// - /// The UTF-8 encoded value to be written as a JSON comment within /*..*/. + /// The UTF-8 encoded value to be written as a JSON comment within /*..*/. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) + public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref utf8Text); + JsonWriterHelper.ValidateValue(ref value); if (!suppressEscaping) { - WriteCommentSuppressFalse(ref utf8Text); + WriteCommentSuppressFalse(ref value); } else { - WriteCommentByOptions(ref utf8Text); + WriteCommentByOptions(ref value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 58eeb12c15d9..2636bd9f268e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -12,7 +12,7 @@ public ref partial struct Utf8JsonWriter /// /// Writes the UTF-16 text value (as a JSON string) as an element of a JSON array. /// - /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. @@ -20,13 +20,13 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(string utf16Text, bool suppressEscaping = false) - => WriteStringValue(utf16Text.AsSpan(), suppressEscaping); + public void WriteStringValue(string value, bool suppressEscaping = false) + => WriteStringValue(value.AsSpan(), suppressEscaping); /// /// Writes the UTF-16 text value (as a JSON string) as an element of a JSON array. /// - /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. + /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. @@ -34,17 +34,17 @@ public void WriteStringValue(string utf16Text, bool suppressEscaping = false) /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(ReadOnlySpan utf16Text, bool suppressEscaping = false) + public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref utf16Text); + JsonWriterHelper.ValidateValue(ref value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref utf16Text); + WriteStringSuppressFalse(ref value); } else { - WriteStringByOptions(ref utf16Text); + WriteStringByOptions(ref value); } _currentDepth |= 1 << 31; @@ -178,7 +178,7 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap /// /// Writes the UTF-8 text value (as a JSON string) as an element of a JSON array. /// - /// The UTF-8 encoded value to be written as a JSON string element of a JSON array. + /// The UTF-8 encoded value to be written as a JSON string element of a JSON array. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. @@ -186,17 +186,17 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(ReadOnlySpan utf8Text, bool suppressEscaping = false) + public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref utf8Text); + JsonWriterHelper.ValidateValue(ref value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref utf8Text); + WriteStringSuppressFalse(ref value); } else { - WriteStringByOptions(ref utf8Text); + WriteStringByOptions(ref value); } _currentDepth |= 1 << 31; From c4fc141f066a3aba7acf2dee360ed7da27916c0b Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Wed, 9 Jan 2019 20:06:21 -0800 Subject: [PATCH 15/33] Remove JsonWriterException and use InvalidOperationException instead. --- .../tests/BinaryFormatterTestData.cs | 3 - .../tests/EqualityExtensions.cs | 10 -- src/System.Text.Json/ref/System.Text.Json.cs | 4 - .../src/System.Text.Json.csproj | 1 - .../src/System/Text/Json/ThrowHelper.cs | 68 +++++------- .../Text/Json/Writer/JsonWriterException.cs | 29 ----- .../Json/Writer/JsonWriterHelper.Escaping.cs | 6 +- .../Text/Json/Writer/JsonWriterOptions.cs | 2 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 6 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 12 +-- ...JsonWriter.WriteProperties.SignedNumber.cs | 12 +-- .../Utf8JsonWriter.WriteProperties.String.cs | 18 ++-- ...onWriter.WriteProperties.UnsignedNumber.cs | 12 +-- .../Utf8JsonWriter.WriteValues.DateTime.cs | 2 +- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 2 +- .../Utf8JsonWriter.WriteValues.Decimal.cs | 2 +- .../Utf8JsonWriter.WriteValues.Double.cs | 2 +- .../Utf8JsonWriter.WriteValues.Float.cs | 2 +- .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 2 +- .../Utf8JsonWriter.WriteValues.Helpers.cs | 4 +- .../Utf8JsonWriter.WriteValues.Literal.cs | 4 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteValues.String.cs | 6 +- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 4 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 38 +++---- .../tests/Utf8JsonWriterTests.cs | 102 +++++++++--------- 32 files changed, 167 insertions(+), 226 deletions(-) delete mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs diff --git a/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs b/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs index cc8c400e51e0..52e263f60703 100644 --- a/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs +++ b/src/System.Runtime.Serialization.Formatters/tests/BinaryFormatterTestData.cs @@ -474,9 +474,6 @@ private static IEnumerable SerializableObjects() #if netcoreapp var jsonReaderException = new JsonReaderException("message", lineNumber: 0, bytePositionInLine: 0); yield return new object[] { PopulateException(jsonReaderException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAJFN5c3RlbS5UZXh0Lkpzb24uSnNvblJlYWRlckV4Y2VwdGlvbg4AAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzCkxpbmVOdW1iZXISQnl0ZVBvc2l0aW9uSW5MaW5lAQEDAwEBAQABAAEHAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwQU3lzdGVtLkV4Y2VwdGlvbggIAgkJAgAAAAYDAAAAJFN5c3RlbS5UZXh0Lkpzb24uSnNvblJlYWRlckV4Y2VwdGlvbgYEAAAAB21lc3NhZ2UJBQAAAAoGBgAAABlodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tBgcAAAAUU3RhY2tUcmFjZSBzdHJpbmcuLi4GCAAAABtSZW1vdGUgU3RhY2tUcmFjZSBzdHJpbmcuLi4AAAAACugDAAAGCQAAABdFeGNlcHRpb25fQ2xhc3NfU2FtcGxlcwoAAAAAAAAAAAAAAAAAAAAABAUAAAApU3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwDAAAABGhlYWQHdmVyc2lvbgVjb3VudAMAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQgICQoAAAACAAAAAgAAAAQKAAAAOFN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsK0RpY3Rpb25hcnlOb2RlAwAAAANrZXkFdmFsdWUEbmV4dAICAzhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQYLAAAABnNlY3JldAgBAQkMAAAAAQwAAAAKAAAACAgBAAAABg0AAAADb25lCgs=", TargetFrameworkMoniker.netcoreapp30) } }; - - var jsonWriterException = new JsonWriterException("message"); - yield return new object[] { PopulateException(jsonWriterException), new TypeSerializableValue[] { new TypeSerializableValue("AAEAAAD/////AQAAAAAAAAAMAgAAAFNTeXN0ZW0uVGV4dC5Kc29uLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Y2M3YjEzZmZjZDJkZGQ1MQUBAAAAJFN5c3RlbS5UZXh0Lkpzb24uSnNvbldyaXRlckV4Y2VwdGlvbgwAAAAJQ2xhc3NOYW1lB01lc3NhZ2UERGF0YQ5Jbm5lckV4Y2VwdGlvbgdIZWxwVVJMEFN0YWNrVHJhY2VTdHJpbmcWUmVtb3RlU3RhY2tUcmFjZVN0cmluZxBSZW1vdGVTdGFja0luZGV4D0V4Y2VwdGlvbk1ldGhvZAdIUmVzdWx0BlNvdXJjZQ1XYXRzb25CdWNrZXRzAQEDAwEBAQABAAEHKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsEFN5c3RlbS5FeGNlcHRpb24ICAICAAAABgMAAAAkU3lzdGVtLlRleHQuSnNvbi5Kc29uV3JpdGVyRXhjZXB0aW9uBgQAAAAHbWVzc2FnZQkFAAAACgYGAAAAGWh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20GBwAAABRTdGFja1RyYWNlIHN0cmluZy4uLgYIAAAAG1JlbW90ZSBTdGFja1RyYWNlIHN0cmluZy4uLgAAAAAK6AMAAAYJAAAAF0V4Y2VwdGlvbl9DbGFzc19TYW1wbGVzCgQFAAAAKVN5c3RlbS5Db2xsZWN0aW9ucy5MaXN0RGljdGlvbmFyeUludGVybmFsAwAAAARoZWFkB3ZlcnNpb24FY291bnQDAAA4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUICAkKAAAAAgAAAAIAAAAECgAAADhTeXN0ZW0uQ29sbGVjdGlvbnMuTGlzdERpY3Rpb25hcnlJbnRlcm5hbCtEaWN0aW9uYXJ5Tm9kZQMAAAADa2V5BXZhbHVlBG5leHQCAgM4U3lzdGVtLkNvbGxlY3Rpb25zLkxpc3REaWN0aW9uYXJ5SW50ZXJuYWwrRGljdGlvbmFyeU5vZGUGCwAAAAZzZWNyZXQIAQEJDAAAAAEMAAAACgAAAAgIAQAAAAYNAAAAA29uZQoL", TargetFrameworkMoniker.netcoreapp30) } }; #endif var keyNotFoundException = new KeyNotFoundException("message", exception); diff --git a/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs b/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs index a3b2ddbc9b35..9b5386156c19 100644 --- a/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs +++ b/src/System.Runtime.Serialization.Formatters/tests/EqualityExtensions.cs @@ -1213,16 +1213,6 @@ public static void IsEqual(this JsonReaderException @this, JsonReaderException o Assert.Equal(@this.LineNumber, other.LineNumber); Assert.Equal(@this.BytePositionInLine, other.BytePositionInLine); } - - public static void IsEqual(this JsonWriterException @this, JsonWriterException other, bool isSamePlatform) - { - if (@this == null && other == null) - return; - - Assert.NotNull(@this); - Assert.NotNull(other); - IsEqual(@this as Exception, other as Exception, isSamePlatform); - } #endif public static void IsEqual(this EventArgs @this, EventArgs other, bool isSamePlatform) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index d93eaac458e2..e93157824111 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -49,10 +49,6 @@ public enum JsonTokenType : byte String = (byte)6, True = (byte)8, } - public sealed partial class JsonWriterException : System.Exception - { - public JsonWriterException(string message) { } - } public partial struct JsonWriterOptions { private object _dummy; diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index c699fab93551..67b20808c250 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -25,7 +25,6 @@ - diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index 04707e411f8f..e0078fad4c41 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -110,29 +110,12 @@ public static void ThrowArgumentException(ReadOnlySpan propertyName, ReadO } } - public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) - { - GetJsonWriterOrArgumentException(propertyName, currentDepth); - } - - public static void ThrowJsonWriterException(string message) - { - throw GetJsonWriterException(message); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static JsonWriterException GetJsonWriterException(string message) - { - return new JsonWriterException(message); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) + public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { currentDepth &= JsonConstants.RemoveFlagsBitMask; if (currentDepth >= JsonConstants.MaxWriterDepth) { - ThrowJsonWriterException(SR.Format(SR.DepthTooLarge, currentDepth)); + ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth)); } else { @@ -141,37 +124,42 @@ private static void GetJsonWriterOrArgumentException(ReadOnlySpan property } } - public static void ThrowJsonWriterException_DepthNonZeroOrEmptyJson(int currentDepth) + public static void ThrowInvalidOperationException(string message) { - throw GetJsonWriterException(currentDepth); + throw GetInvalidOperationException(message); } [MethodImpl(MethodImplOptions.NoInlining)] - private static JsonWriterException GetJsonWriterException(int currentDepth) + private static InvalidOperationException GetInvalidOperationException(string message) + { + return new InvalidOperationException(message); + } + + public static void ThrowInvalidOperationException_DepthNonZeroOrEmptyJson(int currentDepth) + { + throw GetInvalidOperationException(currentDepth); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static InvalidOperationException GetInvalidOperationException(int currentDepth) { currentDepth &= JsonConstants.RemoveFlagsBitMask; if (currentDepth != 0) { - return new JsonWriterException(SR.Format(SR.ZeroDepthAtEnd, currentDepth)); + return new InvalidOperationException(SR.Format(SR.ZeroDepthAtEnd, currentDepth)); } else { - return new JsonWriterException(SR.Format(SR.EmptyJsonIsInvalid)); + return new InvalidOperationException(SR.Format(SR.EmptyJsonIsInvalid)); } } - public static void ThrowJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) - { - GetJsonWriterOrArgumentException(propertyName, currentDepth); - } - - [MethodImpl(MethodImplOptions.NoInlining)] - private static void GetJsonWriterOrArgumentException(ReadOnlySpan propertyName, int currentDepth) + public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan propertyName, int currentDepth) { currentDepth &= JsonConstants.RemoveFlagsBitMask; if (currentDepth >= JsonConstants.MaxWriterDepth) { - ThrowJsonWriterException(SR.Format(SR.DepthTooLarge, currentDepth)); + ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth)); } else { @@ -312,12 +300,12 @@ private static string GetResourceString(ref Utf8JsonReader json, ExceptionResour return message; } - public static void ThrowJsonWriterException(ExceptionResource resource, int currentDepth = default, byte token = default, JsonTokenType tokenType = default) + public static void ThrowInvalidOperationException(ExceptionResource resource, int currentDepth = default, byte token = default, JsonTokenType tokenType = default) { - throw GetJsonReaderException(resource, currentDepth, token, tokenType); + throw GetInvalidOperationException(resource, currentDepth, token, tokenType); } - public static void ThrowJsonWriterException_InvalidUTF8(ReadOnlySpan value) + public static void ThrowArgumentException_InvalidUTF8(ReadOnlySpan value) { var builder = new StringBuilder(); @@ -336,19 +324,19 @@ public static void ThrowJsonWriterException_InvalidUTF8(ReadOnlySpan value } } - throw new JsonWriterException(SR.Format(SR.CannotWriteInvalidUTF8, builder.ToString())); + throw new ArgumentException(SR.Format(SR.CannotWriteInvalidUTF8, builder.ToString())); } - public static void ThrowJsonWriterException_InvalidUTF16(int charAsInt) + public static void ThrowArgumentException_InvalidUTF16(int charAsInt) { - throw new JsonWriterException(SR.Format(SR.CannotWriteInvalidUTF16, $"0x{charAsInt:X2}")); + throw new ArgumentException(SR.Format(SR.CannotWriteInvalidUTF16, $"0x{charAsInt:X2}")); } [MethodImpl(MethodImplOptions.NoInlining)] - public static JsonWriterException GetJsonReaderException(ExceptionResource resource, int currentDepth, byte token, JsonTokenType tokenType) + public static InvalidOperationException GetInvalidOperationException(ExceptionResource resource, int currentDepth, byte token, JsonTokenType tokenType) { string message = GetResourceString(resource, currentDepth, token, tokenType); - return new JsonWriterException(message); + return new InvalidOperationException(message); } // This function will convert an ExceptionResource enum value to the resource string. diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs deleted file mode 100644 index b0a5c6320186..000000000000 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterException.cs +++ /dev/null @@ -1,29 +0,0 @@ -// 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. - -using System.Runtime.Serialization; - -namespace System.Text.Json -{ - /// - /// Defines a custom exception object that is thrown by the whenever it - /// tries to write invalid JSON text. This exception is also thrown whenever - /// you write past the pre-set maximum depth or if the you try to write invalid UTF-8 text. - /// - [Serializable] - public sealed class JsonWriterException : Exception - { - /// - /// Creates a new exception object to relay error information to the user. - /// - /// The context specific error message. - public JsonWriterException(string message) : base(message) - { - } - - private JsonWriterException(SerializationInfo info, StreamingContext context) : base(info, context) - { - } - } -} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 4d9438b66ac9..bbca1eb443a6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -104,7 +104,7 @@ private static int EscapeNextBytes(ReadOnlySpan value, ref Span dest { SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out UnicodeScalar unicodeScalar); if (status != SequenceValidity.WellFormed) - ThrowHelper.ThrowJsonWriterException_InvalidUTF8(value); + ThrowHelper.ThrowArgumentException_InvalidUTF8(value); destination[written++] = (byte)'\\'; int scalar = unicodeScalar.Value; @@ -406,13 +406,13 @@ private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, consumed++; if (value.Length <= consumed || firstChar >= JsonConstants.LowSurrogateStartValue) { - ThrowHelper.ThrowJsonWriterException_InvalidUTF16(firstChar); + ThrowHelper.ThrowArgumentException_InvalidUTF16(firstChar); } nextChar = value[consumed]; if (!InRange(nextChar, JsonConstants.LowSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) { - ThrowHelper.ThrowJsonWriterException_InvalidUTF16(nextChar); + ThrowHelper.ThrowArgumentException_InvalidUTF16(nextChar); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 40ee2a27f786..629999236ad6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -37,7 +37,7 @@ public bool Indented /// /// Defines whether the should skip structural validation and allow /// the user to write invalid JSON, when set to true. If set to false, any attempts to write invalid JSON will result in - /// a to be thrown (for example, writing a value within an object + /// a to be thrown (for example, writing a value within an object /// without a property name). If the JSON being written is known to be correct /// then skipping validation (by setting it to true) could improve performance. /// diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 84b1262ab9f5..18f21147dabd 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -19,7 +19,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) @@ -34,7 +34,7 @@ public void WriteString(string propertyName, DateTime value, bool suppressEscapi /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) @@ -63,7 +63,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index fcc1d1995223..f5e720adac86 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -19,7 +19,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) @@ -34,7 +34,7 @@ public void WriteString(string propertyName, DateTimeOffset value, bool suppress /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) @@ -63,7 +63,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index c9096d6a7eaa..1ef150afa82b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -19,7 +19,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) @@ -34,7 +34,7 @@ public void WriteNumber(string propertyName, decimal value, bool suppressEscapin /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) @@ -63,7 +63,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index b0a08a8d18ce..ef85208e0941 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -19,7 +19,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) @@ -34,7 +34,7 @@ public void WriteNumber(string propertyName, double value, bool suppressEscaping /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) @@ -64,7 +64,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 62da700c2b06..e76c7ae18202 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -19,7 +19,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) @@ -34,7 +34,7 @@ public void WriteNumber(string propertyName, float value, bool suppressEscaping /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) @@ -64,7 +64,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 808e980ac8be..508d61367cc8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -19,7 +19,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) @@ -34,7 +34,7 @@ public void WriteString(string propertyName, Guid value, bool suppressEscaping = /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) @@ -63,7 +63,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index 4c5429badcd0..9fcc26f92718 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -15,14 +15,14 @@ public ref partial struct Utf8JsonWriter private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) - ThrowHelper.ThrowJsonWriterOrArgumentException(propertyName, _currentDepth); + ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) - ThrowHelper.ThrowJsonWriterOrArgumentException(propertyName, _currentDepth); + ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); } private void ValidateWritingProperty() @@ -30,7 +30,7 @@ private void ValidateWritingProperty() if (!_inObject) { Debug.Assert(_tokenType != JsonTokenType.StartObject); - ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotWritePropertyWithinArray, tokenType: _tokenType); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWritePropertyWithinArray, tokenType: _tokenType); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 31eb87e3081a..bdcefbba3cea 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -17,7 +17,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNull(string propertyName, bool suppressEscaping = false) @@ -31,7 +31,7 @@ public void WriteNull(string propertyName, bool suppressEscaping = false) /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) @@ -61,7 +61,7 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) @@ -92,7 +92,7 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) @@ -107,7 +107,7 @@ public void WriteBoolean(string propertyName, bool value, bool suppressEscaping /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) @@ -138,7 +138,7 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 6d3954e73cae..d9144a74fd32 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -18,7 +18,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) @@ -33,7 +33,7 @@ public void WriteNumber(string propertyName, long value, bool suppressEscaping = /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) @@ -62,7 +62,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) @@ -91,7 +91,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) @@ -106,7 +106,7 @@ public void WriteNumber(string propertyName, int value, bool suppressEscaping = /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) @@ -121,7 +121,7 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppres /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 73367abc08ee..27223552fb68 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -21,7 +21,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(string propertyName, string value, bool suppressEscaping = false) @@ -37,7 +37,7 @@ public void WriteString(string propertyName, string value, bool suppressEscaping /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) @@ -67,7 +67,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) @@ -97,7 +97,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) @@ -113,7 +113,7 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool supp /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) @@ -143,7 +143,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) @@ -159,7 +159,7 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool supp /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) @@ -189,7 +189,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) @@ -205,7 +205,7 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool supp /// /// Thrown when the specified property name or value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index afdf5680ea34..f8ab93d28251 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -18,7 +18,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] @@ -34,7 +34,7 @@ public void WriteNumber(string propertyName, ulong value, bool suppressEscaping /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] @@ -64,7 +64,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] @@ -94,7 +94,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] @@ -110,7 +110,7 @@ public void WriteNumber(string propertyName, uint value, bool suppressEscaping = /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] @@ -126,7 +126,7 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppre /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index 2d14641b4a7a..f05132886a2e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -12,7 +12,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON string) as an element of a JSON array. /// /// The value to be written as a JSON string as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteStringValue(DateTime value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 23a5ceb883af..c7fb5a1dae78 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -12,7 +12,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON string) as an element of a JSON array. /// /// The value to be written as a JSON string as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteStringValue(DateTimeOffset value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index d509aaba9f23..b7bff49c996d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -10,7 +10,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumberValue(decimal value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 98dfb149aa27..4e467ffbb08b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -10,7 +10,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumberValue(double value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index dd4286a7ba67..2b93919080c4 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -10,7 +10,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumberValue(float value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index 051ab349d507..ea738383a3f2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -12,7 +12,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON string) as an element of a JSON array. /// /// The value to be written as a JSON string as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteStringValue(Guid value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs index 7ca5f91abcdb..afcac558eebb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -13,13 +13,13 @@ private void ValidateWritingValue() if (_inObject) { Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); - ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotWriteValueWithinObject, tokenType: _tokenType); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWriteValueWithinObject, tokenType: _tokenType); } else { if (!_isNotPrimitive && _tokenType != JsonTokenType.None) { - ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotWriteValueAfterPrimitive, tokenType: _tokenType); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWriteValueAfterPrimitive, tokenType: _tokenType); } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 5bc8def95a72..4bc1cb3ab6f3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -9,7 +9,7 @@ public ref partial struct Utf8JsonWriter /// /// Writes the JSON literal "null" as an element of a JSON array. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNullValue() @@ -24,7 +24,7 @@ public void WriteNullValue() /// Writes the value (as a JSON literal "true" or "false") as an element of a JSON array. /// /// The value to be written as a JSON literal "true" or "false" as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteBooleanValue(bool value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 8592c8403768..c6d3710d6c2c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -10,7 +10,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumberValue(int value) @@ -20,7 +20,7 @@ public void WriteNumberValue(int value) /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteNumberValue(long value) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 2636bd9f268e..af37f642bd80 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -17,7 +17,7 @@ public ref partial struct Utf8JsonWriter /// /// Thrown when the specified value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteStringValue(string value, bool suppressEscaping = false) @@ -31,7 +31,7 @@ public void WriteStringValue(string value, bool suppressEscaping = false) /// /// Thrown when the specified value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) @@ -183,7 +183,7 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap /// /// Thrown when the specified value is too large. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 7b94ceac18f7..58dfac63e326 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -10,7 +10,7 @@ public ref partial struct Utf8JsonWriter /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] @@ -21,7 +21,7 @@ public void WriteNumberValue(uint value) /// Writes the value (as a JSON number) as an element of a JSON array. /// /// The value to be written as a JSON number as an element of a JSON array. - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// [CLSCompliant(false)] diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index c3093ded14b5..46400cee1fd5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -13,7 +13,7 @@ namespace System.Text.Json /// It writes the text sequentially with no caching and adheres to the JSON RFC /// by default (https://tools.ietf.org/html/rfc8259), with the exception of writing comments. /// When the user attempts to write invalid JSON and validation is enabled, it throws - /// a JsonWriterException with a context specific error message. + /// a with a context specific error message. /// Since this type is a ref struct, it does not directly support async. However, it does provide /// support for reentrancy to write partial data, and continue writing in chunks. /// To be able to format the output with indentation and whitespace OR to skip validation, create an instance of @@ -144,14 +144,14 @@ private void Advance(int count) /// /// Let's the writer know whether more data will be written. This is used to validate /// that the JSON written sor far is structurally valid if no more data is to follow. - /// + /// /// Thrown when incomplete JSON has been written and is true. /// (for example when an open object or array needs to be closed). /// public void Flush(bool isFinalBlock = true) { if (isFinalBlock && !_writerOptions.SkipValidation && (CurrentDepth != 0 || _tokenType == JsonTokenType.None)) - ThrowHelper.ThrowJsonWriterException_DepthNonZeroOrEmptyJson(_currentDepth); + ThrowHelper.ThrowInvalidOperationException_DepthNonZeroOrEmptyJson(_currentDepth); Flush(); } @@ -167,7 +167,7 @@ private void Flush() /// /// Writes the beginning of a JSON array. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -180,7 +180,7 @@ public void WriteStartArray() /// /// Writes the beginning of a JSON object. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -193,7 +193,7 @@ public void WriteStartObject() private void WriteStart(byte token) { if (CurrentDepth >= JsonConstants.MaxWriterDepth) - ThrowHelper.ThrowJsonWriterException(ExceptionResource.DepthTooLarge, _currentDepth); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.DepthTooLarge, _currentDepth); if (_writerOptions.SlowPath) { @@ -258,14 +258,14 @@ private void ValidateStart() if (_inObject) { Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); - ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotStartObjectArrayWithoutProperty, tokenType: _tokenType); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotStartObjectArrayWithoutProperty, tokenType: _tokenType); } else { Debug.Assert(_tokenType != JsonTokenType.StartObject); if (_tokenType != JsonTokenType.None && (!_isNotPrimitive || CurrentDepth == 0)) { - ThrowHelper.ThrowJsonWriterException(ExceptionResource.CannotStartObjectArrayAfterPrimitiveOrClose, tokenType: _tokenType); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotStartObjectArrayAfterPrimitiveOrClose, tokenType: _tokenType); } } } @@ -317,7 +317,7 @@ private void WriteStartIndented(byte token) /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -348,7 +348,7 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -461,7 +461,7 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -476,7 +476,7 @@ public void WriteStartArray(string propertyName, bool suppressEscaping = false) /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -491,7 +491,7 @@ public void WriteStartObject(string propertyName, bool suppressEscaping = false) /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -522,7 +522,7 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// /// Thrown when the specified property name is too large. /// - /// + /// /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// @@ -630,7 +630,7 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte /// /// Writes the end of a JSON array. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteEndArray() @@ -642,7 +642,7 @@ public void WriteEndArray() /// /// Writes the end of a JSON object. /// - /// + /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// public void WriteEndObject() @@ -707,14 +707,14 @@ private void WriteEndSlow(byte token) private void ValidateEnd(byte token) { if (_bitStack.CurrentDepth <= 0) - ThrowHelper.ThrowJsonWriterException(ExceptionResource.MismatchedObjectArray, token); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.MismatchedObjectArray, token); if (token == JsonConstants.CloseBracket) { if (_inObject) { Debug.Assert(_tokenType != JsonTokenType.None); - ThrowHelper.ThrowJsonWriterException(ExceptionResource.MismatchedObjectArray, token); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.MismatchedObjectArray, token); } } else @@ -723,7 +723,7 @@ private void ValidateEnd(byte token) if (!_inObject) { - ThrowHelper.ThrowJsonWriterException(ExceptionResource.MismatchedObjectArray, token); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.MismatchedObjectArray, token); } } diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 8ca23b924a52..e9370bc2e0ab 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -48,9 +48,9 @@ public void FlushEmpty(bool formatted, bool skipValidation) { var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.Flush(); - WriterDidNotThrow(skipValidation, "Expected JsonWriterException to be thrown when calling Flush on an empty JSON payload."); + WriterDidNotThrow(skipValidation, "Expected InvalidOperationException to be thrown when calling Flush on an empty JSON payload."); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output = new FixedSizedBufferWriter(10); try @@ -58,9 +58,9 @@ public void FlushEmpty(bool formatted, bool skipValidation) var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteCommentValue("hi"); jsonUtf8.Flush(); - WriterDidNotThrow(skipValidation, "Expected JsonWriterException to be thrown when calling Flush on an empty JSON payload."); + WriterDidNotThrow(skipValidation, "Expected InvalidOperationException to be thrown when calling Flush on an empty JSON payload."); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } } [Theory] @@ -216,7 +216,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -224,7 +224,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -232,7 +232,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartArray("property at start", suppressEscaping: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -240,7 +240,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject("property at start", suppressEscaping: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -249,7 +249,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartArray("property inside array", suppressEscaping: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -258,7 +258,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -267,7 +267,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -276,7 +276,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStringValue("key"); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -285,7 +285,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteString("key", "value"); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -294,7 +294,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -305,7 +305,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -316,7 +316,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -327,7 +327,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -338,7 +338,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -348,7 +348,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -358,7 +358,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -368,7 +368,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -378,7 +378,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -401,7 +401,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -410,7 +410,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -421,7 +421,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -431,7 +431,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -442,7 +442,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -453,7 +453,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -476,7 +476,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteNumberValue(12345); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -485,7 +485,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteStartArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -494,7 +494,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -503,7 +503,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteStartArray("property name", suppressEscaping: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -512,7 +512,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject("property name", suppressEscaping: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -521,7 +521,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteString("property name", "value", suppressEscaping: true); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -530,7 +530,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -539,7 +539,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -714,9 +714,9 @@ public void WritingTooDeep(bool formatted, bool skipValidation) { jsonUtf8.WriteStartArray(); } - Assert.True(false, "Expected JsonWriterException to be thrown for depth >= 1000."); + Assert.True(false, "Expected InvalidOperationException to be thrown for depth >= 1000."); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -741,9 +741,9 @@ public void WritingTooDeepProperty(bool formatted, bool skipValidation) { jsonUtf8.WriteStartArray("name"); } - Assert.True(false, "Expected JsonWriterException to be thrown for depth >= 1000."); + Assert.True(false, "Expected InvalidOperationException to be thrown for depth >= 1000."); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } jsonUtf8 = new Utf8JsonWriter(output, state); @@ -754,9 +754,9 @@ public void WritingTooDeepProperty(bool formatted, bool skipValidation) { jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("name")); } - Assert.True(false, "Expected JsonWriterException to be thrown for depth >= 1000."); + Assert.True(false, "Expected InvalidOperationException to be thrown for depth >= 1000."); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -1045,13 +1045,13 @@ public void WriteInvalidPartialJson(bool formatted, bool skipValidation) jsonUtf8.WriteStringValue("Hello, World!"); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } try { jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -1133,7 +1133,7 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -1158,7 +1158,7 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject("name"); WriterDidNotThrow(skipValidation); } - catch (JsonWriterException) { } + catch (InvalidOperationException) { } output.Dispose(); } @@ -1633,7 +1633,7 @@ public void InvalidUTF8(bool formatted, bool skipValidation) break; } } - catch (JsonWriterException) { } + catch (ArgumentException) { } } jsonUtf8.WriteEndObject(); jsonUtf8.Flush(); @@ -2851,9 +2851,9 @@ private static void WriteTooLargeHelper(JsonWriterState state, ReadOnlySpan Date: Wed, 9 Jan 2019 21:10:35 -0800 Subject: [PATCH 16/33] Use Rune and Utf8Formatter/TryFormat in more places and remove UnicodeScalar. --- .../src/System.Text.Json.csproj | 1 - .../src/System/Text/Json/JsonConstants.cs | 1 + .../Json/Writer/JsonWriterHelper.Escaping.cs | 96 +++++------ .../Text/Json/Writer/JsonWriterHelper.cs | 161 +----------------- .../System/Text/Json/Writer/UnicodeScalar.cs | 70 -------- ...JsonWriter.WriteProperties.SignedNumber.cs | 6 +- ...onWriter.WriteProperties.UnsignedNumber.cs | 6 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 4 +- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 4 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 2 +- 10 files changed, 58 insertions(+), 293 deletions(-) delete mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index 67b20808c250..9ea6b4a2c875 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -30,7 +30,6 @@ - diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 6c47c84f2114..18bd6a0fa731 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -58,5 +58,6 @@ internal static class JsonConstants public const int HighSurrogateEndValue = 0xDBFF; public const int LowSurrogateStartValue = 0xDC00; public const int LowSurrogateEndValue = 0xDFFF; + public const int ShiftRightBy10 = 0x400; } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index bbca1eb443a6..3ac533295d46 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Buffers; using System.Buffers.Text; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -34,6 +35,9 @@ internal static partial class JsonWriterHelper 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; + private static char[] s_hexFormat = { 'x', '4' }; + private static StandardFormat s_hexStandardFormat = new StandardFormat('x', 4); + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedsEscaping(byte value) => AllowList[value] == 0; @@ -102,12 +106,12 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des private static int EscapeNextBytes(ReadOnlySpan value, ref Span destination, ref int written) { - SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out UnicodeScalar unicodeScalar); + SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out Rune rune); if (status != SequenceValidity.WellFormed) ThrowHelper.ThrowArgumentException_InvalidUTF8(value); destination[written++] = (byte)'\\'; - int scalar = unicodeScalar.Value; + int scalar = rune.Value; switch (scalar) { case JsonConstants.LineFeed: @@ -135,17 +139,26 @@ private static int EscapeNextBytes(ReadOnlySpan value, ref Span dest destination[written++] = (byte)'u'; if (scalar < JsonConstants.UnicodePlane01StartValue) { - WriteHex(scalar, ref destination, ref written); + Utf8Formatter.TryFormat(scalar, destination.Slice(written), out int bytesWritten, format: s_hexStandardFormat); + Debug.Assert(bytesWritten == 4); + written += bytesWritten; } else { - int quotient = DivMod(scalar - JsonConstants.UnicodePlane01StartValue, 0x400, out int remainder); + // Divide by 0x400 to shift right by 10 in order to find the surrogate pairs from the scalar + // High surrogate = ((scalar - 0x10000) / 0x400) + D800 + // Low surrogate = ((scalar - 0x10000) % 0x400) + DC00 + int quotient = Math.DivRem(scalar - JsonConstants.UnicodePlane01StartValue, JsonConstants.ShiftRightBy10, out int remainder); int firstChar = quotient + JsonConstants.HighSurrogateStartValue; int nextChar = remainder + JsonConstants.LowSurrogateStartValue; - WriteHex(firstChar, ref destination, ref written); + Utf8Formatter.TryFormat(firstChar, destination.Slice(written), out int bytesWritten, format: s_hexStandardFormat); + Debug.Assert(bytesWritten == 4); + written += bytesWritten; destination[written++] = (byte)'\\'; destination[written++] = (byte)'u'; - WriteHex(nextChar, ref destination, ref written); + Utf8Formatter.TryFormat(nextChar, destination.Slice(written), out bytesWritten, format: s_hexStandardFormat); + Debug.Assert(bytesWritten == 4); + written += bytesWritten; } break; } @@ -183,7 +196,7 @@ private static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBo private static bool IsLowWordSurrogate(uint @char) => (@char & 0xF800U) == 0xD800U; - public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out int numBytesConsumed, out UnicodeScalar scalarValue) + public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out int numBytesConsumed, out Rune rune) { // This method is implemented to match the behavior of System.Text.Encoding.UTF8 in terms of // how many bytes it consumes when reporting invalid sequences. The behavior is as follows: @@ -198,7 +211,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in // - Multi-byte sequences which are improperly terminated (no continuation byte when one is // expected) are reported as invalid sequences up to and including the last seen continuation byte. - scalarValue = UnicodeScalar.s_replacementChar; + rune = Rune.ReplacementChar; if (data.IsEmpty) { @@ -212,7 +225,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in if (IsAsciiValue(firstByte)) { // ASCII byte = well-formed one-byte sequence. - scalarValue = UnicodeScalar.CreateWithoutValidation(firstByte); + rune = new Rune(firstByte); numBytesConsumed = 1; return SequenceValidity.WellFormed; } @@ -243,7 +256,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in if (firstByte < (byte)0xE0U) { // Well-formed two-byte sequence. - scalarValue = UnicodeScalar.CreateWithoutValidation((((uint)firstByte & 0x1FU) << 6) | ((uint)secondByte & 0x3FU)); + rune = new Rune((((uint)firstByte & 0x1FU) << 6) | ((uint)secondByte & 0x3FU)); numBytesConsumed = 2; return SequenceValidity.WellFormed; } @@ -255,7 +268,9 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in uint scalar = (((uint)firstByte & 0x0FU) << 12) | (((uint)secondByte & 0x3FU) << 6); if (scalar < 0x800U || IsLowWordSurrogate(scalar)) - { goto OverlongOutOfRangeOrSurrogateSequence; } + { + goto OverlongOutOfRangeOrSurrogateSequence; + } // At this point, we have a valid two-byte start of a three-byte sequence. @@ -271,7 +286,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in { // Well-formed three-byte sequence. scalar |= (uint)thirdByte & 0x3FU; - scalarValue = UnicodeScalar.CreateWithoutValidation(scalar); + rune = new Rune(scalar); numBytesConsumed = 3; return SequenceValidity.WellFormed; } @@ -289,7 +304,9 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in uint scalar = (((uint)firstByte & 0x07U) << 18) | (((uint)secondByte & 0x3FU) << 12); if (!IsInRangeInclusive(scalar, 0x10000U, 0x10FFFFU)) - { goto OverlongOutOfRangeOrSurrogateSequence; } + { + goto OverlongOutOfRangeOrSurrogateSequence; + } // At this point, we have a valid two-byte start of a four-byte sequence. @@ -317,7 +334,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in { // Well-formed four-byte sequence. scalar |= (((uint)thirdByte & 0x3FU) << 6) | ((uint)fourthByte & 0x3FU); - scalarValue = UnicodeScalar.CreateWithoutValidation(scalar); + rune = new Rune(scalar); numBytesConsumed = 4; return SequenceValidity.WellFormed; } @@ -364,17 +381,6 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in return SequenceValidity.Incomplete; } - /// - /// We don't have access to Math.DivRem, so this is a copy of the implementation. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int DivMod(int numerator, int denominator, out int modulo) - { - int div = numerator / denominator; - modulo = numerator - (div * denominator); - return div; - } - public static void EscapeString(ref ReadOnlySpan value, ref Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -401,7 +407,7 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, ref Span destination, ref int consumed, ref int written) { int nextChar = -1; - if (InRange(firstChar, JsonConstants.HighSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) + if (IsInRangeInclusive(firstChar, JsonConstants.HighSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) { consumed++; if (value.Length <= consumed || firstChar >= JsonConstants.LowSurrogateStartValue) @@ -410,7 +416,7 @@ private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, } nextChar = value[consumed]; - if (!InRange(nextChar, JsonConstants.LowSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) + if (!IsInRangeInclusive(nextChar, JsonConstants.LowSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) { ThrowHelper.ThrowArgumentException_InvalidUTF16(nextChar); } @@ -442,47 +448,25 @@ private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, break; default: destination[written++] = 'u'; - WriteHex(firstChar, ref destination, ref written); + firstChar.TryFormat(destination.Slice(written), out int charsWritten, s_hexFormat); + Debug.Assert(charsWritten == 4); + written += charsWritten; if (nextChar != -1) { destination[written++] = '\\'; destination[written++] = 'u'; - WriteHex(nextChar, ref destination, ref written); + nextChar.TryFormat(destination.Slice(written), out charsWritten, s_hexFormat); + Debug.Assert(charsWritten == 4); + written += charsWritten; } break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool InRange(int ch, int start, int end) + private static bool IsInRangeInclusive(int ch, int start, int end) { return (uint)(ch - start) <= (uint)(end - start); } - - private static void WriteHex(int value, ref Span destination, ref int written) - { - destination[written++] = Int32LsbToHexDigit(value >> 12); - destination[written++] = Int32LsbToHexDigit((int)((value >> 8) & 0xFU)); - destination[written++] = Int32LsbToHexDigit((int)((value >> 4) & 0xFU)); - destination[written++] = Int32LsbToHexDigit((int)(value & 0xFU)); - } - - private static void WriteHex(int value, ref Span destination, ref int written) - { - destination[written++] = (char)Int32LsbToHexDigit(value >> 12); - destination[written++] = (char)Int32LsbToHexDigit((int)((value >> 8) & 0xFU)); - destination[written++] = (char)Int32LsbToHexDigit((int)((value >> 4) & 0xFU)); - destination[written++] = (char)Int32LsbToHexDigit((int)(value & 0xFU)); - } - - /// - /// Converts a number 0 - 15 to its associated hex character '0' - 'f' as byte. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static byte Int32LsbToHexDigit(int value) - { - Debug.Assert(value < 16); - return (byte)((value < 10) ? ('0' + value) : ('a' + (value - 10))); - } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index df608126a2de..75fe5b526184 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -11,8 +11,6 @@ namespace System.Text.Json { internal static partial class JsonWriterHelper { - public static readonly byte[] s_newLineUtf8 = Encoding.UTF8.GetBytes(Environment.NewLine); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteIndentation(Span buffer, int indent, out int bytesWritten) { @@ -20,6 +18,8 @@ public static bool TryWriteIndentation(Span buffer, int indent, out int by if (buffer.Length >= indent) { + // Based on perf tests, the break-even point where vectorized Fill is faster + // than explicitly writing the space in a loop is 8. if (indent < 8) { int i = 0; @@ -119,64 +119,7 @@ public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ThrowHelper.ThrowArgumentException(propertyName, value); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int CountDigits(ulong value) - { - int digits = 1; - uint part; - if (value >= 10000000) - { - if (value >= 100000000000000) - { - part = (uint)(value / 100000000000000); - digits += 14; - } - else - { - part = (uint)(value / 10000000); - digits += 7; - } - } - else - { - part = (uint)value; - } - - if (part < 10) - { - // no-op - } - else if (part < 100) - { - digits += 1; - } - else if (part < 1000) - { - digits += 2; - } - else if (part < 10000) - { - digits += 3; - } - else if (part < 100000) - { - digits += 4; - } - else if (part < 1000000) - { - digits += 5; - } - else - { - Debug.Assert(part < 10000000); - digits += 6; - } - - return digits; - } - // TODO: Replace this with publicly shipping implementation: https://github.com/dotnet/corefx/issues/34094 - /// /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes. /// @@ -316,7 +259,7 @@ public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span else { // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) - if (!InRange(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) + if (!IsInRangeInclusive(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) { // 3 byte encoding chd = unchecked((sbyte)0xE0) | (ch >> 12); @@ -334,7 +277,7 @@ public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span chd = *pSrc; // if (!IsLowSurrogate(chd)) { - if (!InRange(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) + if (!IsInRangeInclusive(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) { // high not followed by low -> bad goto InvalidData; @@ -405,7 +348,7 @@ public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span else { // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) - if (!InRange(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) + if (!IsInRangeInclusive(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) { if (pAllocatedBufferEnd - pTarget <= 2) goto DestinationFull; @@ -432,7 +375,7 @@ public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span chd = *pSrc; // if (!IsLowSurrogate(chd)) { - if (!InRange(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) + if (!IsInRangeInclusive(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) { // high not followed by low -> bad goto InvalidData; @@ -483,98 +426,6 @@ public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span } } - // Borrowed from https://github.com/dotnet/corefx/blob/master/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Signed.Default.cs#L16 - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryFormatInt64Default(long value, Span destination, out int bytesWritten) - { - if ((ulong)value < 10) - { - return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); - } - - return TryFormatInt64MultipleDigits(value, destination, out bytesWritten); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool TryFormatUInt64Default(ulong value, Span destination, out int bytesWritten) - { - if (value < 10) - { - return TryFormatUInt32SingleDigit((uint)value, destination, out bytesWritten); - } - - return TryFormatUInt64MultipleDigits(value, destination, out bytesWritten); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryFormatUInt32SingleDigit(uint value, Span destination, out int bytesWritten) - { - if (destination.Length == 0) - { - bytesWritten = 0; - return false; - } - destination[0] = (byte)('0' + value); - bytesWritten = 1; - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryFormatInt64MultipleDigits(long value, Span destination, out int bytesWritten) - { - if (value < 0) - { - value = -value; - int digitCount = CountDigits((ulong)value); - // WriteDigits does not do bounds checks - if (digitCount >= destination.Length) - { - bytesWritten = 0; - return false; - } - destination[0] = (byte)'-'; - bytesWritten = digitCount + 1; - WriteDigits((ulong)value, destination.Slice(1, digitCount)); - return true; - } - else - { - return TryFormatUInt64MultipleDigits((ulong)value, destination, out bytesWritten); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryFormatUInt64MultipleDigits(ulong value, Span destination, out int bytesWritten) - { - int digitCount = CountDigits(value); - // WriteDigits does not do bounds checks - if (digitCount > destination.Length) - { - bytesWritten = 0; - return false; - } - bytesWritten = digitCount; - WriteDigits(value, destination.Slice(0, digitCount)); - return true; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteDigits(ulong value, Span buffer) - { - // We can mutate the 'value' parameter since it's a copy-by-value local. - // It'll be used to represent the value left over after each division by 10. - - for (int i = buffer.Length - 1; i >= 1; i--) - { - ulong temp = '0' + value; - value /= 10; - buffer[i] = (byte)(temp - (value * 10)); - } - - Debug.Assert(value < 10); - buffer[0] = (byte)('0' + value); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe static int PtrDiff(char* a, char* b) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs b/src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs deleted file mode 100644 index fc8ba9189d3d..000000000000 --- a/src/System.Text.Json/src/System/Text/Json/Writer/UnicodeScalar.cs +++ /dev/null @@ -1,70 +0,0 @@ -// 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. - -using System.Runtime.CompilerServices; - -namespace System.Buffers.Text -{ - /// - /// Represents a 24-bit Unicode scalar value. - /// A scalar value is any value in the range [U+0000..U+D7FF] or [U+E000..U+10FFFF]. - /// - internal struct UnicodeScalar : IComparable, IEquatable - { - /// - /// The Unicode Replacement Character U+FFFD. - /// - public static readonly UnicodeScalar s_replacementChar = new UnicodeScalar(0xFFFD); - - /// - /// The integer value of this scalar. - /// - public readonly int Value; // = U+0000 if using default init - - /// - /// Constructs a Unicode scalar from the given value. - /// The value must represent a valid scalar. - /// - public UnicodeScalar(int value) - : this((uint)value) - { - // None of the APIs on this type are guaranteed to produce correct results - // if we don't validate the input during construction. - - if (!IsValidScalar((uint)Value)) - { - throw new ArgumentOutOfRangeException( - message: "Value must be between U+0000 and U+D7FF, inclusive; or value must be between U+E000 and U+10FFFF, inclusive.", - paramName: nameof(value)); - } - } - - // non-validating ctor for internal use - private UnicodeScalar(uint value) - { - Value = (int)value; - } - - internal static UnicodeScalar CreateWithoutValidation(uint value) => new UnicodeScalar(value); - - public int CompareTo(UnicodeScalar other) => Value.CompareTo(other.Value); - - public override bool Equals(object other) => (other is UnicodeScalar) && Equals((UnicodeScalar)other); - - public bool Equals(UnicodeScalar other) => Value == other.Value; - - public override int GetHashCode() => Value; - - private static bool IsValidScalar(uint value) - => (value < 0xD800U) || IsInRangeInclusive(value, 0xE000U, 0x10FFFFU); - - /// - /// Returns iff is between - /// and , inclusive. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsInRangeInclusive(uint value, uint lowerBound, uint upperBound) - => (value - lowerBound) <= (upperBound - lowerBound); - } -} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index d9144a74fd32..ec6e940b1612 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Buffers; +using System.Buffers.Text; using System.Diagnostics; namespace System.Text.Json @@ -304,10 +305,7 @@ private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, lon private void WriteNumberValueFormatLoop(long value, ref int idx) { int bytesWritten; - // Using Utf8Formatter with default StandardFormat is roughly 30% slower (17 ns versus 12 ns) - // See: https://github.com/dotnet/corefx/issues/25425 - // Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten); - while (!JsonWriterHelper.TryFormatInt64Default(value, _buffer.Slice(idx), out bytesWritten)) + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { AdvanceAndGrow(idx, JsonConstants.MaximumFormatInt64Length); idx = 0; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index f8ab93d28251..3f28a966a702 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Buffers; +using System.Buffers.Text; using System.Diagnostics; namespace System.Text.Json @@ -310,10 +311,7 @@ private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, ulo private void WriteNumberValueFormatLoop(ulong value, ref int idx) { int bytesWritten; - // Using Utf8Formatter with default StandardFormat is roughly 30% slower (17 ns versus 12 ns) - // See: https://github.com/dotnet/corefx/issues/25425 - // Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten); - while (!JsonWriterHelper.TryFormatUInt64Default(value, _buffer.Slice(idx), out bytesWritten)) + while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) { AdvanceAndGrow(idx, JsonConstants.MaximumFormatUInt64Length); idx = 0; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index c6d3710d6c2c..78134eef7ef0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.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.Buffers.Text; + namespace System.Text.Json { public ref partial struct Utf8JsonWriter @@ -61,7 +63,7 @@ private void WriteNumberValueMinimized(long value) _buffer[idx++] = JsonConstants.ListSeperator; } - JsonWriterHelper.TryFormatInt64Default(value, _buffer.Slice(idx), out int bytesWritten); + Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); Advance(idx + bytesWritten); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 58dfac63e326..c092b1b58331 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.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.Buffers.Text; + namespace System.Text.Json { public ref partial struct Utf8JsonWriter @@ -63,7 +65,7 @@ private void WriteNumberValueMinimized(ulong value) _buffer[idx++] = JsonConstants.ListSeperator; } - JsonWriterHelper.TryFormatUInt64Default(value, _buffer.Slice(idx), out int bytesWritten); + Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); Advance(idx + bytesWritten); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 46400cee1fd5..25780e71b6f0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -772,7 +772,7 @@ private void WriteEndIndented(byte token) private void WriteNewLine(ref int idx) { // Write '\r\n' OR '\n', depending on OS - if (JsonWriterHelper.s_newLineUtf8.Length == 2) + if (Environment.NewLine.Length == 2) { while (_buffer.Length <= idx) { From 424835a6cf1e9cb72b3d62b6efce73022ad66602 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Wed, 9 Jan 2019 22:03:14 -0800 Subject: [PATCH 17/33] Fix nits, typos, and reorder field assignment and method calls. --- .../src/Resources/Strings.resx | 2 +- .../src/System/Text/Json/JsonConstants.cs | 14 +- .../Reader/Utf8JsonReader.MultiSegment.cs | 6 +- .../System/Text/Json/Reader/Utf8JsonReader.cs | 6 +- .../src/System/Text/Json/ThrowHelper.cs | 11 +- .../Text/Json/Writer/JsonWriterHelper.cs | 2 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 8 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 8 +- ...JsonWriter.WriteProperties.SignedNumber.cs | 8 +- .../Utf8JsonWriter.WriteProperties.String.cs | 48 +++---- ...onWriter.WriteProperties.UnsignedNumber.cs | 8 +- .../Utf8JsonWriter.WriteValues.Comment.cs | 8 +- .../Utf8JsonWriter.WriteValues.DateTime.cs | 4 +- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 4 +- .../Utf8JsonWriter.WriteValues.Decimal.cs | 4 +- .../Utf8JsonWriter.WriteValues.Double.cs | 4 +- .../Utf8JsonWriter.WriteValues.Float.cs | 4 +- .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 4 +- .../Utf8JsonWriter.WriteValues.Literal.cs | 4 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteValues.String.cs | 16 +-- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 4 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 47 +++---- ...ArrayFormatter.cs => ArrayBufferWriter.cs} | 14 +- .../tests/System.Text.Json.Tests.csproj | 2 +- .../tests/Utf8JsonWriterTests.cs | 127 ++++++++++++------ 32 files changed, 244 insertions(+), 175 deletions(-) rename src/System.Text.Json/tests/{ArrayFormatter.cs => ArrayBufferWriter.cs} (91%) diff --git a/src/System.Text.Json/src/Resources/Strings.resx b/src/System.Text.Json/src/Resources/Strings.resx index 1332e9402cc1..33d1d0f6a578 100644 --- a/src/System.Text.Json/src/Resources/Strings.resx +++ b/src/System.Text.Json/src/Resources/Strings.resx @@ -145,7 +145,7 @@ Cannot write a JSON value within an object without a property name. Current token type is '{0}'. - CurrentDepth ({0}) is equal to or larger than the maximum allowed depth of 1000. Cannot write the next JSON object or array. + CurrentDepth ({0}) is equal to or larger than the maximum allowed depth of {1}. Cannot write the next JSON object or array. Writing an empty JSON payload (excluding comments) is invalid. diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 18bd6a0fa731..ffbfedb98bd3 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -14,7 +14,7 @@ internal static class JsonConstants public const byte CarriageReturn = (byte)'\r'; public const byte LineFeed = (byte)'\n'; public const byte Tab = (byte)'\t'; - public const byte ListSeperator = (byte)','; + public const byte ListSeparator = (byte)','; public const byte KeyValueSeperator = (byte)':'; public const byte Quote = (byte)'"'; public const byte BackSlash = (byte)'\\'; @@ -28,15 +28,21 @@ internal static class JsonConstants public static ReadOnlySpan NullValue => new byte[] { (byte)'n', (byte)'u', (byte)'l', (byte)'l' }; // Used to search for the end of a number - public static ReadOnlySpan Delimiters => new byte[] { ListSeperator, CloseBrace, CloseBracket, Space, LineFeed, CarriageReturn, Tab, Slash }; + public static ReadOnlySpan Delimiters => new byte[] { ListSeparator, CloseBrace, CloseBracket, Space, LineFeed, CarriageReturn, Tab, Slash }; // Explicitly skipping ReverseSolidus since that is handled separately public static ReadOnlySpan EscapableChars => new byte[] { Quote, (byte)'n', (byte)'r', (byte)'t', Slash, (byte)'u', (byte)'b', (byte)'f' }; + public const int SpacesPerIndent = 2; public const int RemoveFlagsBitMask = 0x7FFFFFFF; public const int MaxWriterDepth = 1_000; - public const int MaxTokenSize = 2_000_000_000 / 6; // 357_913_941 bytes - public const int MaxCharacterTokenSize = 2_000_000_000 / 6; // 357_913_941 characters + // In the worst case, an ASCII character represented as a single utf-8 byte could expand 6x when escaped. + // For example: '+' becomes '\u0043' + // Escaping surrogate pairs (represented by 3 or 4 utf-8 bytes) would expand to 12 bytes (which is still <= 6x). + // The same factor applies to utf-16 characters. + public const int MaxExpansionFactorWhileEscaping = 6; + public const int MaxTokenSize = 2_000_000_000 / MaxExpansionFactorWhileEscaping; // 357_913_941 bytes + public const int MaxCharacterTokenSize = 2_000_000_000 / MaxExpansionFactorWhileEscaping; // 357_913_941 characters public const int MaximumFormatInt64Length = 20; // 19 + sign (i.e. -9223372036854775808) public const int MaximumFormatUInt64Length = 20; // i.e. 18446744073709551615 diff --git a/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs index 4d35bc1b5a00..0fb3efa944da 100644 --- a/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.MultiSegment.cs @@ -1557,7 +1557,7 @@ private ConsumeTokenResult ConsumeNextTokenMultiSegment(byte marker) ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker); } - if (marker == JsonConstants.ListSeperator) + if (marker == JsonConstants.ListSeparator) { _consumed++; _bytePositionInLine++; @@ -1666,7 +1666,7 @@ private ConsumeTokenResult ConsumeNextTokenFromLastNonCommentTokenMultiSegment() Debug.Assert(first != JsonConstants.Slash); - if (first == JsonConstants.ListSeperator) + if (first == JsonConstants.ListSeparator) { _consumed++; _bytePositionInLine++; @@ -1951,7 +1951,7 @@ private ConsumeTokenResult ConsumeNextTokenUntilAfterAllCommentsAreSkippedMultiS { ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker); } - else if (marker == JsonConstants.ListSeperator) + else if (marker == JsonConstants.ListSeparator) { _consumed++; _bytePositionInLine++; diff --git a/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs index ae1791799de6..291b8e22f0e2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs +++ b/src/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.cs @@ -1216,7 +1216,7 @@ private ConsumeTokenResult ConsumeNextToken(byte marker) ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker); } - if (marker == JsonConstants.ListSeperator) + if (marker == JsonConstants.ListSeparator) { _consumed++; _bytePositionInLine++; @@ -1316,7 +1316,7 @@ private ConsumeTokenResult ConsumeNextTokenFromLastNonCommentToken() Debug.Assert(first != JsonConstants.Slash); - if (first == JsonConstants.ListSeperator) + if (first == JsonConstants.ListSeparator) { _consumed++; _bytePositionInLine++; @@ -1588,7 +1588,7 @@ private ConsumeTokenResult ConsumeNextTokenUntilAfterAllCommentsAreSkipped(byte { ThrowHelper.ThrowJsonReaderException(ref this, ExceptionResource.ExpectedEndAfterSingleJson, marker); } - else if (marker == JsonConstants.ListSeperator) + else if (marker == JsonConstants.ListSeparator) { _consumed++; _bytePositionInLine++; diff --git a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index e0078fad4c41..4831b531541e 100644 --- a/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -115,7 +115,7 @@ public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan p currentDepth &= JsonConstants.RemoveFlagsBitMask; if (currentDepth >= JsonConstants.MaxWriterDepth) { - ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth)); + ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth, JsonConstants.MaxWriterDepth)); } else { @@ -159,7 +159,7 @@ public static void ThrowInvalidOperationOrArgumentException(ReadOnlySpan p currentDepth &= JsonConstants.RemoveFlagsBitMask; if (currentDepth >= JsonConstants.MaxWriterDepth) { - ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth)); + ThrowInvalidOperationException(SR.Format(SR.DepthTooLarge, currentDepth, JsonConstants.MaxWriterDepth)); } else { @@ -324,6 +324,11 @@ public static void ThrowArgumentException_InvalidUTF8(ReadOnlySpan value) } } + if (printFirst10 < value.Length) + { + builder.Append("..."); + } + throw new ArgumentException(SR.Format(SR.CannotWriteInvalidUTF8, builder.ToString())); } @@ -350,7 +355,7 @@ private static string GetResourceString(ExceptionResource resource, int currentD message = SR.Format(SR.MismatchedObjectArray, token); break; case ExceptionResource.DepthTooLarge: - message = SR.Format(SR.DepthTooLarge, currentDepth & JsonConstants.RemoveFlagsBitMask); + message = SR.Format(SR.DepthTooLarge, currentDepth & JsonConstants.RemoveFlagsBitMask, JsonConstants.MaxWriterDepth); break; case ExceptionResource.CannotStartObjectArrayWithoutProperty: message = SR.Format(SR.CannotStartObjectArrayWithoutProperty, tokenType); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 75fe5b526184..5fa32ea4f76b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -14,7 +14,7 @@ internal static partial class JsonWriterHelper [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteIndentation(Span buffer, int indent, out int bytesWritten) { - Debug.Assert(indent % 2 == 0); + Debug.Assert(indent % JsonConstants.SpacesPerIndent == 0); if (buffer.Length >= indent) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 18f21147dabd..5cc54ff58fdf 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -117,11 +117,11 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -150,11 +150,11 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index f5e720adac86..f3ddeeb5f8e2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -117,11 +117,11 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -150,11 +150,11 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 1ef150afa82b..e3c90808b8af 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -117,11 +117,11 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decim private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -150,11 +150,11 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index ef85208e0941..eb0755d63332 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -119,11 +119,11 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, doubl private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -152,11 +152,11 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index e76c7ae18202..c7d94cf5aea5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -119,11 +119,11 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -152,11 +152,11 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 508d61367cc8..0bca2afa27a8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -117,11 +117,11 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -150,11 +150,11 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index 9fcc26f92718..f1d439b92b73 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -43,7 +43,7 @@ private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyNam { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } while (_buffer.Length <= idx) @@ -81,7 +81,7 @@ private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) @@ -143,7 +143,7 @@ private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyNam { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } while (_buffer.Length <= idx) @@ -194,7 +194,7 @@ private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index bdcefbba3cea..692b26f3c9d7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -194,11 +194,11 @@ private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -227,11 +227,11 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index ec6e940b1612..61066ec20477 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -162,11 +162,11 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -195,11 +195,11 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 27223552fb68..dcb675988c1e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -269,9 +269,9 @@ private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -283,9 +283,9 @@ private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyNa private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -297,9 +297,9 @@ private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyNa private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -311,9 +311,9 @@ private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyNa private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); value = span.Slice(0, written); @@ -401,15 +401,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref R private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] valueArray = null; char[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -432,7 +432,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -467,15 +467,15 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] valueArray = null; byte[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -498,7 +498,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -533,15 +533,15 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] valueArray = null; char[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -564,7 +564,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -599,15 +599,15 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] valueArray = null; byte[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -630,7 +630,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 3f28a966a702..12bc8a7fbb64 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -168,11 +168,11 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -201,11 +201,11 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 230002931f71..072ca0a92694 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -108,13 +108,13 @@ private void WriteCommentIndented(ref ReadOnlySpan escapedValue) private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); char[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -230,13 +230,13 @@ private void WriteCommentIndented(ref ReadOnlySpan escapedValue) private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); byte[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index f05132886a2e..eda3ec8ee04a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -50,7 +50,7 @@ private void WriteStringValueMinimized(DateTime value) int idx = 0; if (_currentDepth < 0) { - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } _buffer[idx++] = JsonConstants.Quote; @@ -72,7 +72,7 @@ private void WriteStringValueIndented(DateTime value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index c7fb5a1dae78..9cd206cdeb44 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -50,7 +50,7 @@ private void WriteStringValueMinimized(DateTimeOffset value) int idx = 0; if (_currentDepth < 0) { - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } _buffer[idx++] = JsonConstants.Quote; @@ -72,7 +72,7 @@ private void WriteStringValueIndented(DateTimeOffset value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index b7bff49c996d..d0e3e81e901c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -45,7 +45,7 @@ private void WriteNumberValueMinimized(decimal value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } WriteNumberValueFormatLoop(value, ref idx); @@ -62,7 +62,7 @@ private void WriteNumberValueIndented(decimal value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 4e467ffbb08b..267f0961b354 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -47,7 +47,7 @@ private void WriteNumberValueMinimized(double value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } WriteNumberValueFormatLoop(value, ref idx); @@ -64,7 +64,7 @@ private void WriteNumberValueIndented(double value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 2b93919080c4..0416eeeebc4e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -47,7 +47,7 @@ private void WriteNumberValueMinimized(float value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } WriteNumberValueFormatLoop(value, ref idx); @@ -64,7 +64,7 @@ private void WriteNumberValueIndented(float value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index ea738383a3f2..783c2616d4b8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -50,7 +50,7 @@ private void WriteStringValueMinimized(Guid value) int idx = 0; if (_currentDepth < 0) { - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } _buffer[idx++] = JsonConstants.Quote; @@ -72,7 +72,7 @@ private void WriteStringValueIndented(Guid value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 4bc1cb3ab6f3..e7337218a410 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -75,7 +75,7 @@ private void WriteLiteralMinimized(ref ReadOnlySpan value) int idx = 0; if (_currentDepth < 0) { - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } value.CopyTo(_buffer.Slice(idx)); @@ -92,7 +92,7 @@ private void WriteLiteralIndented(ref ReadOnlySpan value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 78134eef7ef0..dcaca4d292c9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -60,7 +60,7 @@ private void WriteNumberValueMinimized(long value) int idx = 0; if (_currentDepth < 0) { - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); @@ -77,7 +77,7 @@ private void WriteNumberValueIndented(long value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index af37f642bd80..57f6c2327f12 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -96,7 +96,7 @@ private void WriteStringMinimized(ref ReadOnlySpan escapedValue) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } WriteStringValue(ref escapedValue, ref idx); @@ -113,7 +113,7 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) @@ -140,13 +140,13 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); char[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -248,7 +248,7 @@ private void WriteStringMinimized(ref ReadOnlySpan escapedValue) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } WriteStringValue(ref escapedValue, ref idx); @@ -265,7 +265,7 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) @@ -292,13 +292,13 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); byte[] valueArray = null; if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); Span span; if (length > StackallocThreshold) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index c092b1b58331..72362e47b325 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -62,7 +62,7 @@ private void WriteNumberValueMinimized(ulong value) int idx = 0; if (_currentDepth < 0) { - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); @@ -79,7 +79,7 @@ private void WriteNumberValueIndented(ulong value) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 25780e71b6f0..c12059003e93 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -22,8 +22,6 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { private const int StackallocThreshold = 256; - private const int MaxExpansionFactorWhileEscaping = 6; - private const int SpacesPerIndent = 2; private const int DefaultGrowthSize = 4096; private readonly IBufferWriter _output; @@ -62,7 +60,7 @@ public long BytesWritten // else, no list separator is needed since we are writing the first item. private int _currentDepth; - private int Indentation => CurrentDepth * SpacesPerIndent; + private int Indentation => CurrentDepth * JsonConstants.SpacesPerIndent; /// /// Tracks the recursive depth of the nested objects / arrays within the JSON text @@ -143,7 +141,7 @@ private void Advance(int count) /// Advances the underlying based on what has been written so far. /// /// Let's the writer know whether more data will be written. This is used to validate - /// that the JSON written sor far is structurally valid if no more data is to follow. + /// that the JSON written so far is structurally valid if no more data is to follow. /// /// Thrown when incomplete JSON has been written and is true. /// (for example when an open object or array needs to be closed). @@ -159,8 +157,8 @@ public void Flush(bool isFinalBlock = true) [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Flush() { - BytesCommitted += _buffered; _output.Advance(_buffered); + BytesCommitted += _buffered; _buffered = 0; } @@ -220,7 +218,7 @@ private void WriteStartMinimized(byte token) if (_currentDepth < 0) { - _buffer[0] = JsonConstants.ListSeperator; + _buffer[0] = JsonConstants.ListSeparator; _buffer[1] = token; } else @@ -279,7 +277,7 @@ private void WriteStartIndented(byte token) { GrowAndEnsure(); } - _buffer[idx++] = JsonConstants.ListSeperator; + _buffer[idx++] = JsonConstants.ListSeparator; } if (_tokenType != JsonTokenType.None) @@ -422,11 +420,11 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -596,11 +594,11 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); char[] propertyArray = null; - int length = firstEscapeIndexProp + MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -653,16 +651,6 @@ public void WriteEndObject() private void WriteEnd(byte token) { - _currentDepth |= 1 << 31; - _currentDepth--; - - // Necessary if WriteEndX is called without a corresponding WriteStartX first. - // Checking for int.MaxValue because int.MinValue - 1 = int.MaxValue - if (_currentDepth == int.MaxValue) - { - _currentDepth = 0; - } - if (_writerOptions.SlowPath) { WriteEndSlow(token); @@ -671,6 +659,13 @@ private void WriteEnd(byte token) { WriteEndMinimized(token); } + + _currentDepth |= 1 << 31; + // Necessary if WriteEndX is called without a corresponding WriteStartX first. + if (CurrentDepth != 0) + { + _currentDepth--; + } } private void WriteEndMinimized(byte token) @@ -733,8 +728,7 @@ private void ValidateEnd(byte token) private void WriteEndIndented(byte token) { // Do not format/indent empty JSON object/array. - if ((_tokenType == JsonTokenType.StartObject && token == JsonConstants.CloseBrace) - || (_tokenType == JsonTokenType.StartArray && token == JsonConstants.CloseBracket)) + if (_tokenType == JsonTokenType.StartObject || _tokenType == JsonTokenType.StartArray) { WriteEndMinimized(token); } @@ -744,6 +738,13 @@ private void WriteEndIndented(byte token) WriteNewLine(ref idx); int indent = Indentation; + // Necessary if WriteEndX is called without a corresponding WriteStartX first. + if (indent != 0) + { + // The end token should be at an outer indent and since we haven't updated + // current depth yet, explicitly subtract here. + indent -= JsonConstants.SpacesPerIndent; + } while (true) { bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); diff --git a/src/System.Text.Json/tests/ArrayFormatter.cs b/src/System.Text.Json/tests/ArrayBufferWriter.cs similarity index 91% rename from src/System.Text.Json/tests/ArrayFormatter.cs rename to src/System.Text.Json/tests/ArrayBufferWriter.cs index d757dd4c9b97..13249f80d1c8 100644 --- a/src/System.Text.Json/tests/ArrayFormatter.cs +++ b/src/System.Text.Json/tests/ArrayBufferWriter.cs @@ -7,11 +7,11 @@ namespace System.Text.Json.Tests { - internal class ArrayFormatter : IBufferWriter, IDisposable + internal class ArrayBufferWriter : IBufferWriter, IDisposable { - ResizableArray _buffer; + private ResizableArray _buffer; - public ArrayFormatter(int capacity) + public ArrayBufferWriter(int capacity) { _buffer = new ResizableArray(ArrayPool.Shared.Rent(capacity)); } @@ -30,7 +30,10 @@ public void Clear() public Memory GetMemory(int minimumLength = 0) { if (minimumLength < 1) + { minimumLength = 1; + } + if (minimumLength > _buffer.FreeCount) { int doubleCount = _buffer.FreeCount * 2; @@ -39,6 +42,7 @@ public Memory GetMemory(int minimumLength = 0) byte[] oldArray = _buffer.Resize(newArray); ArrayPool.Shared.Return(oldArray); } + return _buffer.FreeMemory; } @@ -46,7 +50,10 @@ public Memory GetMemory(int minimumLength = 0) public Span GetSpan(int minimumLength = 0) { if (minimumLength < 1) + { minimumLength = 1; + } + if (minimumLength > _buffer.FreeCount) { int doubleCount = _buffer.FreeCount * 2; @@ -55,6 +62,7 @@ public Span GetSpan(int minimumLength = 0) byte[] oldArray = _buffer.Resize(newArray); ArrayPool.Shared.Return(oldArray); } + return _buffer.FreeSpan; } diff --git a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj index a8c9c4036196..7ca71749e3f6 100644 --- a/src/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -4,7 +4,7 @@ netcoreapp-Debug;netcoreapp-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release - + diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index e9370bc2e0ab..00dc34eb6620 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -208,7 +208,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -392,7 +392,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -467,7 +467,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -553,7 +553,7 @@ public void InvalidNumbersJson(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -667,7 +667,7 @@ public void InvalidJsonContinueShouldSucceed(bool formatted) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = true }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); @@ -687,6 +687,7 @@ public void InvalidJsonContinueShouldSucceed(bool formatted) sb.Append(Environment.NewLine); sb.Append("]"); } + sb.Append(","); if (formatted) sb.Append(Environment.NewLine); sb.Append("[]"); @@ -705,7 +706,7 @@ public void WritingTooDeep(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -730,7 +731,7 @@ public void WritingTooDeepProperty(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); @@ -771,7 +772,7 @@ public void WritingTooLargeProperty(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); @@ -815,7 +816,7 @@ public void WriteSingleValue(bool formatted, bool skipValidation) for (int i = 0; i < 3; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteNumberValue(123456789012345); @@ -844,7 +845,7 @@ public void WriteHelloWorld(bool formatted, bool skipValidation) for (int i = 0; i < 9; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -901,7 +902,7 @@ public void WritePartialHelloWorld(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -967,7 +968,7 @@ public void WritePartialHelloWorldSaveState(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); Assert.Equal(0, jsonUtf8.CurrentDepth); @@ -1023,7 +1024,7 @@ public void WriteInvalidPartialJson(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1065,7 +1066,7 @@ public void WritePartialJsonSkipFlush(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1115,7 +1116,7 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1141,7 +1142,7 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1185,7 +1186,7 @@ public void WriteComments(bool formatted, bool skipValidation, string comment) for (int i = 0; i < 3; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartArray(); @@ -1252,7 +1253,7 @@ public void WriteStrings(bool formatted, bool skipValidation) for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartArray(); @@ -1324,7 +1325,7 @@ public void WriteHelloWorldEscaped(bool formatted, bool skipValidation, string k for (int i = 0; i < 18; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1432,7 +1433,7 @@ public void EscapeAsciiCharacters(bool formatted, bool skipValidation) var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); for (int i = 0; i < 4; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1493,7 +1494,7 @@ public void EscapeCharacters(bool formatted, bool skipValidation) var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); for (int i = 0; i < 4; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1545,7 +1546,7 @@ public void EscapeSurrogatePairs(bool formatted, bool skipValidation) var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); for (int i = 0; i < 4; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1589,7 +1590,7 @@ public void InvalidUTF8(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1650,7 +1651,7 @@ public void WriteCustomStrings(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new ArrayFormatter(10); + var output = new ArrayBufferWriter(10); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1678,7 +1679,7 @@ public void WriteStartEnd(bool formatted, bool skipValidation) { string expectedStr = GetStartEndExpectedString(prettyPrint: formatted); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); @@ -1698,6 +1699,54 @@ public void WriteStartEnd(bool formatted, bool skipValidation) output.Dispose(); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void WriteStartEndInvalid(bool formatted) + { + { + string expectedStr = "[}"; + + var output = new ArrayBufferWriter(1024); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = true }); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartArray(); + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + + { + string expectedStr = "{]"; + + var output = new ArrayBufferWriter(1024); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = true }); + + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + jsonUtf8.WriteEndArray(); + jsonUtf8.Flush(); + + ArraySegment arraySegment = output.Formatted; + string actualStr = Encoding.UTF8.GetString(arraySegment.Array, arraySegment.Offset, arraySegment.Count); + + Assert.Equal(expectedStr, actualStr); + + output.Dispose(); + } + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] @@ -1711,7 +1760,7 @@ public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidati for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1776,7 +1825,7 @@ public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidati for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1832,7 +1881,7 @@ public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidat for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1897,7 +1946,7 @@ public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidat for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -1953,7 +2002,7 @@ public void WriteArrayWithProperty(bool formatted, bool skipValidation) for (int i = 0; i < 3; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2018,7 +2067,7 @@ public void WriteBooleanValue(bool formatted, bool skipValidation, bool value, s for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2089,7 +2138,7 @@ public void WriteNullValue(bool formatted, bool skipValidation, string keyString for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2169,7 +2218,7 @@ public void WriteIntegerValue(bool formatted, bool skipValidation, int value) for (int i = 0; i < 3; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2346,7 +2395,7 @@ public void WriteNumbers(bool formatted, bool skipValidation, string keyString) for (int j = 0; j < 6; j++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); ReadOnlySpan keyUtf16 = keyString; @@ -2516,7 +2565,7 @@ public void WriteGuidsValue(bool formatted, bool skipValidation, string keyStrin for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2609,7 +2658,7 @@ public void WriteDateTimesValue(bool formatted, bool skipValidation, string keyS for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2702,7 +2751,7 @@ public void WriteDateTimeOffsetsValue(bool formatted, bool skipValidation, strin for (int i = 0; i < 6; i++) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); @@ -2775,7 +2824,7 @@ public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) Span value = new byte[1_000_000_001]; value.Fill((byte)'b'); - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); try @@ -2820,7 +2869,7 @@ public void WriteLargeKeyValue(bool formatted, bool skipValidation) private static void WriteTooLargeHelper(JsonWriterState state, ReadOnlySpan key, ReadOnlySpan value, bool noThrow = false) { - var output = new ArrayFormatter(1024); + var output = new ArrayBufferWriter(1024); var jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStartObject(); From 1c09b09d2954d922d14afd1543c99f60abca9b13 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 17:42:49 -0800 Subject: [PATCH 18/33] Pass spans by in (or by value) instead of by ref. --- .../src/System.Text.Json.csproj | 4 - .../src/System/Text/Json/JsonConstants.cs | 4 +- .../Json/Writer/JsonWriterHelper.Escaping.cs | 16 +- .../Text/Json/Writer/JsonWriterHelper.cs | 16 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 66 +++--- ...onWriter.WriteProperties.DateTimeOffset.cs | 66 +++--- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 66 +++--- .../Utf8JsonWriter.WriteProperties.Double.cs | 66 +++--- .../Utf8JsonWriter.WriteProperties.Float.cs | 66 +++--- .../Utf8JsonWriter.WriteProperties.Guid.cs | 66 +++--- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 16 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 62 +++--- ...JsonWriter.WriteProperties.SignedNumber.cs | 66 +++--- .../Utf8JsonWriter.WriteProperties.String.cs | 210 +++++++++--------- ...onWriter.WriteProperties.UnsignedNumber.cs | 66 +++--- .../Utf8JsonWriter.WriteValues.Comment.cs | 70 +++--- .../Utf8JsonWriter.WriteValues.Literal.cs | 12 +- .../Utf8JsonWriter.WriteValues.String.cs | 64 +++--- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 79 +++---- .../tests/Utf8JsonWriterTests.cs | 54 +++++ 20 files changed, 579 insertions(+), 556 deletions(-) diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index 9ea6b4a2c875..f0d0617ce453 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -12,8 +12,6 @@ - - @@ -23,8 +21,6 @@ - - diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index ffbfedb98bd3..201172c67af1 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -34,13 +34,15 @@ internal static class JsonConstants public static ReadOnlySpan EscapableChars => new byte[] { Quote, (byte)'n', (byte)'r', (byte)'t', Slash, (byte)'u', (byte)'b', (byte)'f' }; public const int SpacesPerIndent = 2; - public const int RemoveFlagsBitMask = 0x7FFFFFFF; public const int MaxWriterDepth = 1_000; + public const int RemoveFlagsBitMask = 0x7FFFFFFF; + // In the worst case, an ASCII character represented as a single utf-8 byte could expand 6x when escaped. // For example: '+' becomes '\u0043' // Escaping surrogate pairs (represented by 3 or 4 utf-8 bytes) would expand to 12 bytes (which is still <= 6x). // The same factor applies to utf-16 characters. public const int MaxExpansionFactorWhileEscaping = 6; + public const int MaxTokenSize = 2_000_000_000 / MaxExpansionFactorWhileEscaping; // 357_913_941 bytes public const int MaxCharacterTokenSize = 2_000_000_000 / MaxExpansionFactorWhileEscaping; // 357_913_941 characters diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 3ac533295d46..40eb85143400 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -35,8 +35,8 @@ internal static partial class JsonWriterHelper 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; - private static char[] s_hexFormat = { 'x', '4' }; - private static StandardFormat s_hexStandardFormat = new StandardFormat('x', 4); + private static readonly char[] s_hexFormat = { 'x', '4' }; + private static readonly StandardFormat s_hexStandardFormat = new StandardFormat('x', 4); [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedsEscaping(byte value) => AllowList[value] == 0; @@ -80,7 +80,7 @@ public static int NeedsEscaping(ReadOnlySpan value) return idx; } - public static void EscapeString(ref ReadOnlySpan value, ref Span destination, int indexOfFirstByteToEscape, out int written) + public static void EscapeString(in ReadOnlySpan value, in Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -93,7 +93,7 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des byte val = value[consumed]; if (NeedsEscaping(val)) { - consumed += EscapeNextBytes(value.Slice(consumed), ref destination, ref written); + consumed += EscapeNextBytes(value.Slice(consumed), destination, ref written); } else { @@ -104,7 +104,7 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des } } - private static int EscapeNextBytes(ReadOnlySpan value, ref Span destination, ref int written) + private static int EscapeNextBytes(ReadOnlySpan value, in Span destination, ref int written) { SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out Rune rune); if (status != SequenceValidity.WellFormed) @@ -381,7 +381,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in return SequenceValidity.Incomplete; } - public static void EscapeString(ref ReadOnlySpan value, ref Span destination, int indexOfFirstByteToEscape, out int written) + public static void EscapeString(in ReadOnlySpan value, in Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -394,7 +394,7 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des char val = value[consumed]; if (NeedsEscaping(val)) { - EscapeNextChars(ref value, val, ref destination, ref consumed, ref written); + EscapeNextChars(value, val, destination, ref consumed, ref written); } else { @@ -404,7 +404,7 @@ public static void EscapeString(ref ReadOnlySpan value, ref Span des } } - private static void EscapeNextChars(ref ReadOnlySpan value, int firstChar, ref Span destination, ref int consumed, ref int written) + private static void EscapeNextChars(in ReadOnlySpan value, int firstChar, in Span destination, ref int consumed, ref int written) { int nextChar = -1; if (IsInRangeInclusive(firstChar, JsonConstants.HighSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 5fa32ea4f76b..26556e5ff99f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -50,14 +50,14 @@ public static bool TryWriteIndentation(Span buffer, int indent, out int by } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateProperty(ref ReadOnlySpan propertyName) + public static void ValidateProperty(in ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateValue(ref ReadOnlySpan value) + public static void ValidateValue(in ReadOnlySpan value) { if (value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); @@ -78,42 +78,42 @@ public static void ValidateSingle(float value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateProperty(ref ReadOnlySpan propertyName) + public static void ValidateProperty(in ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateValue(ref ReadOnlySpan value) + public static void ValidateValue(in ReadOnlySpan value) { if (value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 5cc54ff58fdf..272dc8ee6353 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -39,15 +39,15 @@ public void WriteString(string propertyName, DateTime value, bool suppressEscapi /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -68,22 +68,22 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTime value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTime value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -91,15 +91,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT if (propertyIdx != -1) { - WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + WriteStringEscapeProperty(propertyName, value, propertyIdx); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTime value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTime value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -107,15 +107,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT if (propertyIdx != -1) { - WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + WriteStringEscapeProperty(propertyName, value, propertyIdx); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -137,10 +137,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -148,7 +147,7 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date } } - private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -170,10 +169,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -181,7 +179,7 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTime value) { if (_writerOptions.Indented) { @@ -189,7 +187,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, value); + WriteStringIndented(propertyName, value); } else { @@ -197,11 +195,11 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTime value) { if (_writerOptions.Indented) { @@ -209,7 +207,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, value); + WriteStringIndented(propertyName, value); } else { @@ -217,40 +215,40 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTime { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTime value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTime value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTime value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTime value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index f3ddeeb5f8e2..228eae03b57a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -39,15 +39,15 @@ public void WriteString(string propertyName, DateTimeOffset value, bool suppress /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -68,22 +68,22 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTimeOffset value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -91,15 +91,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT if (propertyIdx != -1) { - WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + WriteStringEscapeProperty(propertyName, value, propertyIdx); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTimeOffset value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -107,15 +107,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, DateT if (propertyIdx != -1) { - WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + WriteStringEscapeProperty(propertyName, value, propertyIdx); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -137,10 +137,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -148,7 +147,7 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date } } - private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -170,10 +169,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -181,7 +179,7 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Date } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTimeOffset value) { if (_writerOptions.Indented) { @@ -189,7 +187,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeO { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, value); + WriteStringIndented(propertyName, value); } else { @@ -197,11 +195,11 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeO { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTimeOffset value) { if (_writerOptions.Indented) { @@ -209,7 +207,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeO { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, value); + WriteStringIndented(propertyName, value); } else { @@ -217,40 +215,40 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, DateTimeO { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index e3c90808b8af..82ab5c89d92c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -39,15 +39,15 @@ public void WriteNumber(string propertyName, decimal value, bool suppressEscapin /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -68,22 +68,22 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decimal value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, decimal value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -91,15 +91,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decim if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decimal value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, decimal value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -107,15 +107,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, decim if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -137,10 +137,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -148,7 +147,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -170,10 +169,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -181,7 +179,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, deci } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, decimal value) { if (_writerOptions.Indented) { @@ -189,7 +187,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal v { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -197,11 +195,11 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal v { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, decimal value) { if (_writerOptions.Indented) { @@ -209,7 +207,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal v { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -217,40 +215,40 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, decimal v { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, decimal value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, decimal value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, decimal value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, decimal value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index eb0755d63332..b62921ef1703 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -39,16 +39,16 @@ public void WriteNumber(string propertyName, double value, bool suppressEscaping /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateDouble(value); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -69,23 +69,23 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateDouble(value); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, double value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, double value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -93,15 +93,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, doubl if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, double value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, double value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -109,15 +109,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, doubl if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -139,10 +139,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -150,7 +149,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -172,10 +171,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -183,7 +181,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, doub } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, double value) { if (_writerOptions.Indented) { @@ -191,7 +189,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double va { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -199,11 +197,11 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double va { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, double value) { if (_writerOptions.Indented) { @@ -211,7 +209,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double va { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -219,40 +217,40 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, double va { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, double value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, double value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, double value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, double value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index c7d94cf5aea5..3faa54f4eecb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -39,16 +39,16 @@ public void WriteNumber(string propertyName, float value, bool suppressEscaping /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateSingle(value); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -69,23 +69,23 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateSingle(value); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, float value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -93,15 +93,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, float value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -109,15 +109,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, float if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -139,10 +139,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -150,7 +149,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -172,10 +171,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -183,7 +181,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, floa } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, float value) { if (_writerOptions.Indented) { @@ -191,7 +189,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float val { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -199,11 +197,11 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float val { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, float value) { if (_writerOptions.Indented) { @@ -211,7 +209,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float val { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -219,40 +217,40 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, float val { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, float value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, float value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, float value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, float value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 0bca2afa27a8..c7f47226843e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -39,15 +39,15 @@ public void WriteString(string propertyName, Guid value, bool suppressEscaping = /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -68,22 +68,22 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -91,15 +91,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid if (propertyIdx != -1) { - WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + WriteStringEscapeProperty(propertyName, value, propertyIdx); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -107,15 +107,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, Guid if (propertyIdx != -1) { - WriteStringEscapeProperty(ref propertyName, value, propertyIdx); + WriteStringEscapeProperty(propertyName, value, propertyIdx); } else { - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -137,10 +137,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -148,7 +147,7 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid } } - private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -170,10 +169,9 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStringByOptions(ref propertyName, value); + WriteStringByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -181,7 +179,7 @@ private void WriteStringEscapeProperty(ref ReadOnlySpan propertyName, Guid } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, Guid value) { if (_writerOptions.Indented) { @@ -189,7 +187,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid valu { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, value); + WriteStringIndented(propertyName, value); } else { @@ -197,11 +195,11 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid valu { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, Guid value) { if (_writerOptions.Indented) { @@ -209,7 +207,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid valu { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, value); + WriteStringIndented(propertyName, value); } else { @@ -217,40 +215,40 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, Guid valu { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Guid value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Guid value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Guid value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteStringValue(value, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Guid value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index f1d439b92b73..ddbcd82ab9a6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -12,14 +12,14 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) + private void ValidatePropertyNameAndDepth(in ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ValidatePropertyNameAndDepth(ref ReadOnlySpan propertyName) + private void ValidatePropertyNameAndDepth(in ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); @@ -34,7 +34,7 @@ private void ValidateWritingProperty() } } - private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyName) + private int WritePropertyNameMinimized(in ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) @@ -53,7 +53,7 @@ private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyNam } _buffer[idx++] = JsonConstants.Quote; - CopyLoop(ref escapedPropertyName, ref idx); + CopyLoop(escapedPropertyName, ref idx); while (_buffer.Length <= idx) { @@ -72,7 +72,7 @@ private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyNam return idx; } - private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName) + private int WritePropertyNameIndented(in ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) @@ -108,7 +108,7 @@ private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName } _buffer[idx++] = JsonConstants.Quote; - CopyLoop(ref escapedPropertyName, ref idx); + CopyLoop(escapedPropertyName, ref idx); while (_buffer.Length <= idx) { @@ -134,7 +134,7 @@ private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName return idx; } - private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyName) + private int WritePropertyNameMinimized(in ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) @@ -185,7 +185,7 @@ private int WritePropertyNameMinimized(ref ReadOnlySpan escapedPropertyNam return idx; } - private int WritePropertyNameIndented(ref ReadOnlySpan escapedPropertyName) + private int WritePropertyNameIndented(in ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 692b26f3c9d7..ff90d286fca9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -36,17 +36,17 @@ public void WriteNull(string propertyName, bool suppressEscaping = false) /// public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = JsonConstants.NullValue; if (!suppressEscaping) { - WriteLiteralSuppressFalse(ref propertyName, ref span); + WriteLiteralSuppressFalse(propertyName, span); } else { - WriteLiteralByOptions(ref propertyName, ref span); + WriteLiteralByOptions(propertyName, span); } _currentDepth |= 1 << 31; @@ -66,17 +66,17 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f /// public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = JsonConstants.NullValue; if (!suppressEscaping) { - WriteLiteralSuppressFalse(ref propertyName, ref span); + WriteLiteralSuppressFalse(propertyName, span); } else { - WriteLiteralByOptions(ref propertyName, ref span); + WriteLiteralByOptions(propertyName, span); } _currentDepth |= 1 << 31; @@ -112,17 +112,17 @@ public void WriteBoolean(string propertyName, bool value, bool suppressEscaping /// public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; if (!suppressEscaping) { - WriteLiteralSuppressFalse(ref propertyName, ref span); + WriteLiteralSuppressFalse(propertyName, span); } else { - WriteLiteralByOptions(ref propertyName, ref span); + WriteLiteralByOptions(propertyName, span); } _currentDepth |= 1 << 31; @@ -143,24 +143,24 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr /// public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; if (!suppressEscaping) { - WriteLiteralSuppressFalse(ref propertyName, ref span); + WriteLiteralSuppressFalse(propertyName, span); } else { - WriteLiteralByOptions(ref propertyName, ref span); + WriteLiteralByOptions(propertyName, span); } _currentDepth |= 1 << 31; _tokenType = value ? JsonTokenType.True : JsonTokenType.False; } - private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteLiteralSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -168,15 +168,15 @@ private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref if (propertyIdx != -1) { - WriteLiteralEscapeProperty(ref propertyName, ref value, propertyIdx); + WriteLiteralEscapeProperty(propertyName, value, propertyIdx); } else { - WriteLiteralByOptions(ref propertyName, ref value); + WriteLiteralByOptions(propertyName, value); } } - private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteLiteralSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -184,15 +184,15 @@ private void WriteLiteralSuppressFalse(ref ReadOnlySpan propertyName, ref if (propertyIdx != -1) { - WriteLiteralEscapeProperty(ref propertyName, ref value, propertyIdx); + WriteLiteralEscapeProperty(propertyName, value, propertyIdx); } else { - WriteLiteralByOptions(ref propertyName, ref value); + WriteLiteralByOptions(propertyName, value); } } - private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) + private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in ReadOnlySpan value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -214,10 +214,9 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteLiteralByOptions(ref propertyName, ref value); + WriteLiteralByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -225,7 +224,7 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref } } - private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp) + private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in ReadOnlySpan value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -247,10 +246,9 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteLiteralByOptions(ref propertyName, ref value); + WriteLiteralByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -258,7 +256,7 @@ private void WriteLiteralEscapeProperty(ref ReadOnlySpan propertyName, ref } } - private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteLiteralByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int idx; if (_writerOptions.Indented) @@ -267,7 +265,7 @@ private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref Read { ValidateWritingProperty(); } - idx = WritePropertyNameIndented(ref propertyName); + idx = WritePropertyNameIndented(propertyName); } else { @@ -275,7 +273,7 @@ private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref Read { ValidateWritingProperty(); } - idx = WritePropertyNameMinimized(ref propertyName); + idx = WritePropertyNameMinimized(propertyName); } if (value.Length > _buffer.Length - idx) @@ -290,7 +288,7 @@ private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref Read Advance(idx); } - private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteLiteralByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int idx; if (_writerOptions.Indented) @@ -299,7 +297,7 @@ private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref Read { ValidateWritingProperty(); } - idx = WritePropertyNameIndented(ref propertyName); + idx = WritePropertyNameIndented(propertyName); } else { @@ -307,7 +305,7 @@ private void WriteLiteralByOptions(ref ReadOnlySpan propertyName, ref Read { ValidateWritingProperty(); } - idx = WritePropertyNameMinimized(ref propertyName); + idx = WritePropertyNameMinimized(propertyName); } if (value.Length > _buffer.Length - idx) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 61066ec20477..d77f0b7ad4b2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -39,15 +39,15 @@ public void WriteNumber(string propertyName, long value, bool suppressEscaping = /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -68,15 +68,15 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -128,7 +128,7 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppres public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName, (long)value, suppressEscaping); - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, long value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -136,15 +136,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, long value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -152,15 +152,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, long if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -182,10 +182,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -193,7 +192,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -215,10 +214,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -226,7 +224,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, long } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, long value) { if (_writerOptions.Indented) { @@ -234,7 +232,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long valu { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -242,11 +240,11 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long valu { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, long value) { if (_writerOptions.Indented) { @@ -254,7 +252,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long valu { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -262,40 +260,40 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, long valu { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, long value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, long value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, long value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, long value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index dcb675988c1e..e603fcb257d0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -42,15 +42,15 @@ public void WriteString(string propertyName, string value, bool suppressEscaping /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, ref value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringSuppressTrue(ref propertyName, ref value); + WriteStringSuppressTrue(propertyName, value); } _currentDepth |= 1 << 31; @@ -72,15 +72,15 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, ref value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringSuppressTrue(ref propertyName, ref value); + WriteStringSuppressTrue(propertyName, value); } _currentDepth |= 1 << 31; @@ -118,15 +118,15 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool supp /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, ref value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringSuppressTrue(ref propertyName, ref value); + WriteStringSuppressTrue(propertyName, value); } _currentDepth |= 1 << 31; @@ -164,15 +164,15 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool supp /// public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidatePropertyAndValue(ref propertyName, ref value); + JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref propertyName, ref value); + WriteStringSuppressFalse(propertyName, value); } else { - WriteStringSuppressTrue(ref propertyName, ref value); + WriteStringSuppressTrue(propertyName, value); } _currentDepth |= 1 << 31; @@ -212,118 +212,114 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool supp => WriteString(propertyName, value.AsSpan(), suppressEscaping); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) { - WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + WriteStringEscapeValueOnly(escapedPropertyName, value, valueIdx); } else { - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) { - WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + WriteStringEscapeValueOnly(escapedPropertyName, value, valueIdx); } else { - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) { - WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + WriteStringEscapeValueOnly(escapedPropertyName, value, valueIdx); } else { - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value) + private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) { - WriteStringEscapeValueOnly(ref escapedPropertyName, ref value, valueIdx); + WriteStringEscapeValueOnly(escapedPropertyName, value, valueIdx); } else { - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, value); } } - private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); Span span = valueArray; - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndex, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); - WriteStringByOptions(ref escapedPropertyName, ref value); + WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -334,15 +330,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref R // Equivalent to: valueIdx != -1 || propertyIdx != -1 if (valueIdx + propertyIdx != -2) { - WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + WriteStringEscapePropertyOrValue(propertyName, value, propertyIdx, valueIdx); } else { - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -353,15 +349,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref R // Equivalent to: valueIdx != -1 || propertyIdx != -1 if (valueIdx + propertyIdx != -2) { - WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + WriteStringEscapePropertyOrValue(propertyName, value, propertyIdx, valueIdx); } else { - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -372,15 +368,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref R // Equivalent to: valueIdx != -1 || propertyIdx != -1 if (valueIdx + propertyIdx != -2) { - WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + WriteStringEscapePropertyOrValue(propertyName, value, propertyIdx, valueIdx); } else { - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -391,15 +387,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan propertyName, ref R // Equivalent to: valueIdx != -1 || propertyIdx != -1 if (valueIdx + propertyIdx != -2) { - WriteStringEscapePropertyOrValue(ref propertyName, ref value, propertyIdx, valueIdx); + WriteStringEscapePropertyOrValue(propertyName, value, propertyIdx, valueIdx); } else { - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); } } - private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -426,7 +422,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } @@ -448,11 +444,11 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); propertyName = span.Slice(0, written); } - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); if (valueArray != null) { @@ -465,7 +461,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam } } - private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -492,7 +488,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } @@ -514,11 +510,11 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); propertyName = span.Slice(0, written); } - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); if (valueArray != null) { @@ -531,7 +527,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam } } - private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -558,7 +554,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } @@ -580,11 +576,11 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); propertyName = span.Slice(0, written); } - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); if (valueArray != null) { @@ -597,7 +593,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam } } - private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyName, ref ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -624,7 +620,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } @@ -646,11 +642,11 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); propertyName = span.Slice(0, written); } - WriteStringByOptions(ref propertyName, ref value); + WriteStringByOptions(propertyName, value); if (valueArray != null) { @@ -663,7 +659,7 @@ private void WriteStringEscapePropertyOrValue(ref ReadOnlySpan propertyNam } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -671,7 +667,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, ref value); + WriteStringIndented(propertyName, value); } else { @@ -679,11 +675,11 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, ref value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -691,7 +687,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, ref value); + WriteStringIndented(propertyName, value); } else { @@ -699,11 +695,11 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, ref value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -711,7 +707,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, ref value); + WriteStringIndented(propertyName, value); } else { @@ -719,11 +715,11 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, ref value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadOnlySpan value) + private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -731,7 +727,7 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringIndented(ref propertyName, ref value); + WriteStringIndented(propertyName, value); } else { @@ -739,83 +735,83 @@ private void WriteStringByOptions(ref ReadOnlySpan propertyName, ref ReadO { ValidateWritingProperty(); } - WriteStringMinimized(ref propertyName, ref value); + WriteStringMinimized(propertyName, value); } } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringMinimized(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedPropertyName, ref ReadOnlySpan escapedValue) + private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringValue(ref ReadOnlySpan escapedValue, ref int idx) + private void WriteStringValue(in ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { @@ -847,7 +843,7 @@ private void WriteStringValue(ref ReadOnlySpan escapedValue, ref int idx) _buffer[idx++] = JsonConstants.Quote; } - private void WriteStringValue(ref ReadOnlySpan escapedValue, ref int idx) + private void WriteStringValue(in ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { @@ -856,7 +852,7 @@ private void WriteStringValue(ref ReadOnlySpan escapedValue, ref int idx) } _buffer[idx++] = JsonConstants.Quote; - CopyLoop(ref escapedValue, ref idx); + CopyLoop(escapedValue, ref idx); while (_buffer.Length <= idx) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 12bc8a7fbb64..7ad1a3bb3da2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -41,15 +41,15 @@ public void WriteNumber(string propertyName, ulong value, bool suppressEscaping [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -71,15 +71,15 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateProperty(ref propertyName); + JsonWriterHelper.ValidateProperty(propertyName); if (!suppressEscaping) { - WriteNumberSuppressFalse(ref propertyName, value); + WriteNumberSuppressFalse(propertyName, value); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } _currentDepth |= 1 << 31; @@ -134,7 +134,7 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppre public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName, (ulong)value, suppressEscaping); - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, ulong value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -142,15 +142,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong value) + private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, ulong value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -158,15 +158,15 @@ private void WriteNumberSuppressFalse(ref ReadOnlySpan propertyName, ulong if (propertyIdx != -1) { - WriteNumberEscapeProperty(ref propertyName, value, propertyIdx); + WriteNumberEscapeProperty(propertyName, value, propertyIdx); } else { - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(propertyName, value); } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -188,10 +188,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -199,7 +198,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon } } - private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -221,10 +220,9 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteNumberByOptions(ref propertyName, value); + WriteNumberByOptions(span.Slice(0, written), value); if (propertyArray != null) { @@ -232,7 +230,7 @@ private void WriteNumberEscapeProperty(ref ReadOnlySpan propertyName, ulon } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, ulong value) { if (_writerOptions.Indented) { @@ -240,7 +238,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong val { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -248,11 +246,11 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong val { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong value) + private void WriteNumberByOptions(in ReadOnlySpan propertyName, ulong value) { if (_writerOptions.Indented) { @@ -260,7 +258,7 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong val { ValidateWritingProperty(); } - WriteNumberIndented(ref propertyName, value); + WriteNumberIndented(propertyName, value); } else { @@ -268,40 +266,40 @@ private void WriteNumberByOptions(ref ReadOnlySpan propertyName, ulong val { ValidateWritingProperty(); } - WriteNumberMinimized(ref propertyName, value); + WriteNumberMinimized(propertyName, value); } } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, ulong value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberMinimized(ref ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, ulong value) { - int idx = WritePropertyNameMinimized(ref escapedPropertyName); + int idx = WritePropertyNameMinimized(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, ulong value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); Advance(idx); } - private void WriteNumberIndented(ref ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, ulong value) { - int idx = WritePropertyNameIndented(ref escapedPropertyName); + int idx = WritePropertyNameIndented(escapedPropertyName); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 072ca0a92694..0110343ca1ae 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -31,19 +31,19 @@ public void WriteCommentValue(string value, bool suppressEscaping = false) /// public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref value); + JsonWriterHelper.ValidateValue(value); if (!suppressEscaping) { - WriteCommentSuppressFalse(ref value); + WriteCommentSuppressFalse(value); } else { - WriteCommentByOptions(ref value); + WriteCommentByOptions(value); } } - private void WriteCommentSuppressFalse(ref ReadOnlySpan value) + private void WriteCommentSuppressFalse(in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -51,36 +51,36 @@ private void WriteCommentSuppressFalse(ref ReadOnlySpan value) if (valueIdx != -1) { - WriteCommentEscapeValue(ref value, valueIdx); + WriteCommentEscapeValue(value, valueIdx); } else { - WriteCommentByOptions(ref value); + WriteCommentByOptions(value); } } - private void WriteCommentByOptions(ref ReadOnlySpan value) + private void WriteCommentByOptions(in ReadOnlySpan value) { if (_writerOptions.Indented) { - WriteCommentIndented(ref value); + WriteCommentIndented(value); } else { - WriteCommentMinimized(ref value); + WriteCommentMinimized(value); } } - private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) + private void WriteCommentMinimized(in ReadOnlySpan escapedValue) { int idx = 0; - WriteCommentValue(ref escapedValue, ref idx); + WriteCommentValue(escapedValue, ref idx); Advance(idx); } - private void WriteCommentIndented(ref ReadOnlySpan escapedValue) + private void WriteCommentIndented(in ReadOnlySpan escapedValue) { int idx = 0; @@ -101,12 +101,12 @@ private void WriteCommentIndented(ref ReadOnlySpan escapedValue) idx = 0; } - WriteCommentValue(ref escapedValue, ref idx); + WriteCommentValue(escapedValue, ref idx); Advance(idx); } - private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -131,11 +131,11 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } - WriteCommentByOptions(ref value); + WriteCommentByOptions(value); if (valueArray != null) { @@ -153,19 +153,19 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca /// public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref value); + JsonWriterHelper.ValidateValue(value); if (!suppressEscaping) { - WriteCommentSuppressFalse(ref value); + WriteCommentSuppressFalse(value); } else { - WriteCommentByOptions(ref value); + WriteCommentByOptions(value); } } - private void WriteCommentSuppressFalse(ref ReadOnlySpan value) + private void WriteCommentSuppressFalse(in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -173,36 +173,36 @@ private void WriteCommentSuppressFalse(ref ReadOnlySpan value) if (valueIdx != -1) { - WriteCommentEscapeValue(ref value, valueIdx); + WriteCommentEscapeValue(value, valueIdx); } else { - WriteCommentByOptions(ref value); + WriteCommentByOptions(value); } } - private void WriteCommentByOptions(ref ReadOnlySpan value) + private void WriteCommentByOptions(in ReadOnlySpan value) { if (_writerOptions.Indented) { - WriteCommentIndented(ref value); + WriteCommentIndented(value); } else { - WriteCommentMinimized(ref value); + WriteCommentMinimized(value); } } - private void WriteCommentMinimized(ref ReadOnlySpan escapedValue) + private void WriteCommentMinimized(in ReadOnlySpan escapedValue) { int idx = 0; - WriteCommentValue(ref escapedValue, ref idx); + WriteCommentValue(escapedValue, ref idx); Advance(idx); } - private void WriteCommentIndented(ref ReadOnlySpan escapedValue) + private void WriteCommentIndented(in ReadOnlySpan escapedValue) { int idx = 0; @@ -223,12 +223,12 @@ private void WriteCommentIndented(ref ReadOnlySpan escapedValue) idx = 0; } - WriteCommentValue(ref escapedValue, ref idx); + WriteCommentValue(escapedValue, ref idx); Advance(idx); } - private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -253,11 +253,11 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } - WriteCommentByOptions(ref value); + WriteCommentByOptions(value); if (valueArray != null) { @@ -265,7 +265,7 @@ private void WriteCommentEscapeValue(ref ReadOnlySpan value, int firstEsca } } - private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) + private void WriteCommentValue(in ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { @@ -311,7 +311,7 @@ private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) _buffer[idx++] = JsonConstants.Slash; } - private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) + private void WriteCommentValue(in ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { @@ -327,7 +327,7 @@ private void WriteCommentValue(ref ReadOnlySpan escapedValue, ref int idx) } _buffer[idx++] = JsonConstants.Asterisk; - CopyLoop(ref escapedValue, ref idx); + CopyLoop(escapedValue, ref idx); while (_buffer.Length <= idx) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index e7337218a410..ea0c71abdd3f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -43,7 +43,7 @@ public void WriteBooleanValue(bool value) _currentDepth |= 1 << 31; } - private void WriteLiteralByOptions(ReadOnlySpan value) + private void WriteLiteralByOptions(in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -51,7 +51,7 @@ private void WriteLiteralByOptions(ReadOnlySpan value) { ValidateWritingValue(); } - WriteLiteralIndented(ref value); + WriteLiteralIndented(value); } else { @@ -59,11 +59,11 @@ private void WriteLiteralByOptions(ReadOnlySpan value) { ValidateWritingValue(); } - WriteLiteralMinimized(ref value); + WriteLiteralMinimized(value); } } - private void WriteLiteralMinimized(ref ReadOnlySpan value) + private void WriteLiteralMinimized(in ReadOnlySpan value) { // Calculated based on the following: ',null' OR ',true' OR ',false' int bytesNeeded = value.Length + 1; @@ -83,7 +83,7 @@ private void WriteLiteralMinimized(ref ReadOnlySpan value) Advance(idx + value.Length); } - private void WriteLiteralIndented(ref ReadOnlySpan value) + private void WriteLiteralIndented(in ReadOnlySpan value) { int idx = 0; if (_currentDepth < 0) @@ -112,7 +112,7 @@ private void WriteLiteralIndented(ref ReadOnlySpan value) idx = 0; } - CopyLoop(ref value, ref idx); + CopyLoop(value, ref idx); Advance(idx); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 57f6c2327f12..c73f866f1007 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -36,22 +36,22 @@ public void WriteStringValue(string value, bool suppressEscaping = false) /// public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref value); + JsonWriterHelper.ValidateValue(value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref value); + WriteStringSuppressFalse(value); } else { - WriteStringByOptions(ref value); + WriteStringByOptions(value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ref ReadOnlySpan value) + private void WriteStringSuppressFalse(in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -59,15 +59,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan value) if (valueIdx != -1) { - WriteStringEscapeValue(ref value, valueIdx); + WriteStringEscapeValue(value, valueIdx); } else { - WriteStringByOptions(ref value); + WriteStringByOptions(value); } } - private void WriteStringByOptions(ref ReadOnlySpan value) + private void WriteStringByOptions(in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -75,7 +75,7 @@ private void WriteStringByOptions(ref ReadOnlySpan value) { ValidateWritingValue(); } - WriteStringIndented(ref value); + WriteStringIndented(value); } else { @@ -83,11 +83,11 @@ private void WriteStringByOptions(ref ReadOnlySpan value) { ValidateWritingValue(); } - WriteStringMinimized(ref value); + WriteStringMinimized(value); } } - private void WriteStringMinimized(ref ReadOnlySpan escapedValue) + private void WriteStringMinimized(in ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -99,12 +99,12 @@ private void WriteStringMinimized(ref ReadOnlySpan escapedValue) _buffer[idx++] = JsonConstants.ListSeparator; } - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedValue) + private void WriteStringIndented(in ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -133,12 +133,12 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) idx = 0; } - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -163,11 +163,11 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } - WriteStringByOptions(ref value); + WriteStringByOptions(value); if (valueArray != null) { @@ -188,22 +188,22 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap /// public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) { - JsonWriterHelper.ValidateValue(ref value); + JsonWriterHelper.ValidateValue(value); if (!suppressEscaping) { - WriteStringSuppressFalse(ref value); + WriteStringSuppressFalse(value); } else { - WriteStringByOptions(ref value); + WriteStringByOptions(value); } _currentDepth |= 1 << 31; _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ref ReadOnlySpan value) + private void WriteStringSuppressFalse(in ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -211,15 +211,15 @@ private void WriteStringSuppressFalse(ref ReadOnlySpan value) if (valueIdx != -1) { - WriteStringEscapeValue(ref value, valueIdx); + WriteStringEscapeValue(value, valueIdx); } else { - WriteStringByOptions(ref value); + WriteStringByOptions(value); } } - private void WriteStringByOptions(ref ReadOnlySpan value) + private void WriteStringByOptions(in ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -227,7 +227,7 @@ private void WriteStringByOptions(ref ReadOnlySpan value) { ValidateWritingValue(); } - WriteStringIndented(ref value); + WriteStringIndented(value); } else { @@ -235,11 +235,11 @@ private void WriteStringByOptions(ref ReadOnlySpan value) { ValidateWritingValue(); } - WriteStringMinimized(ref value); + WriteStringMinimized(value); } } - private void WriteStringMinimized(ref ReadOnlySpan escapedValue) + private void WriteStringMinimized(in ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -251,12 +251,12 @@ private void WriteStringMinimized(ref ReadOnlySpan escapedValue) _buffer[idx++] = JsonConstants.ListSeparator; } - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringIndented(ref ReadOnlySpan escapedValue) + private void WriteStringIndented(in ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -285,12 +285,12 @@ private void WriteStringIndented(ref ReadOnlySpan escapedValue) idx = 0; } - WriteStringValue(ref escapedValue, ref idx); + WriteStringValue(escapedValue, ref idx); Advance(idx); } - private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscapeIndexVal) + private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -315,11 +315,11 @@ private void WriteStringEscapeValue(ref ReadOnlySpan value, int firstEscap span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref value, ref span, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); value = span.Slice(0, written); } - WriteStringByOptions(ref value); + WriteStringByOptions(value); if (valueArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index c12059003e93..d4295b24ff76 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -321,15 +321,15 @@ private void WriteStartIndented(byte token) /// public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { - ValidatePropertyNameAndDepth(ref propertyName); + ValidatePropertyNameAndDepth(propertyName); if (!suppressEscaping) { - WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBracket); + WriteStartSuppressFalse(propertyName, JsonConstants.OpenBracket); } else { - WriteStartByOptions(ref propertyName, JsonConstants.OpenBracket); + WriteStartByOptions(propertyName, JsonConstants.OpenBracket); } _currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -352,15 +352,15 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { - ValidatePropertyNameAndDepth(ref propertyName); + ValidatePropertyNameAndDepth(propertyName); if (!suppressEscaping) { - WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBrace); + WriteStartSuppressFalse(propertyName, JsonConstants.OpenBrace); } else { - WriteStartByOptions(ref propertyName, JsonConstants.OpenBrace); + WriteStartByOptions(propertyName, JsonConstants.OpenBrace); } _currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -369,7 +369,7 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap _tokenType = JsonTokenType.StartObject; } - private void WriteStartSuppressFalse(ref ReadOnlySpan propertyName, byte token) + private void WriteStartSuppressFalse(in ReadOnlySpan propertyName, byte token) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -377,15 +377,15 @@ private void WriteStartSuppressFalse(ref ReadOnlySpan propertyName, byte t if (propertyIdx != -1) { - WriteStartEscapeProperty(ref propertyName, token, propertyIdx); + WriteStartEscapeProperty(propertyName, token, propertyIdx); } else { - WriteStartByOptions(ref propertyName, token); + WriteStartByOptions(propertyName, token); } } - private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token) + private void WriteStartByOptions(in ReadOnlySpan propertyName, byte token) { int idx; if (_writerOptions.Indented) @@ -395,7 +395,7 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token ValidateWritingProperty(); UpdateBitStackOnStart(token); } - idx = WritePropertyNameIndented(ref propertyName); + idx = WritePropertyNameIndented(propertyName); } else { @@ -404,7 +404,7 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token ValidateWritingProperty(); UpdateBitStackOnStart(token); } - idx = WritePropertyNameMinimized(ref propertyName); + idx = WritePropertyNameMinimized(propertyName); } if (1 > _buffer.Length - idx) @@ -418,7 +418,7 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token Advance(idx); } - private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + private void WriteStartEscapeProperty(in ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -440,10 +440,10 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); - WriteStartByOptions(ref propertyName, token); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + + WriteStartByOptions(span.Slice(0, written), token); if (propertyArray != null) { @@ -495,15 +495,15 @@ public void WriteStartObject(string propertyName, bool suppressEscaping = false) /// public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) { - ValidatePropertyNameAndDepth(ref propertyName); + ValidatePropertyNameAndDepth(propertyName); if (!suppressEscaping) { - WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBracket); + WriteStartSuppressFalse(propertyName, JsonConstants.OpenBracket); } else { - WriteStartByOptions(ref propertyName, JsonConstants.OpenBracket); + WriteStartByOptions(propertyName, JsonConstants.OpenBracket); } _currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -526,15 +526,15 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) { - ValidatePropertyNameAndDepth(ref propertyName); + ValidatePropertyNameAndDepth(propertyName); if (!suppressEscaping) { - WriteStartSuppressFalse(ref propertyName, JsonConstants.OpenBrace); + WriteStartSuppressFalse(propertyName, JsonConstants.OpenBrace); } else { - WriteStartByOptions(ref propertyName, JsonConstants.OpenBrace); + WriteStartByOptions(propertyName, JsonConstants.OpenBrace); } _currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -543,7 +543,7 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap _tokenType = JsonTokenType.StartObject; } - private void WriteStartSuppressFalse(ref ReadOnlySpan propertyName, byte token) + private void WriteStartSuppressFalse(in ReadOnlySpan propertyName, byte token) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -551,15 +551,15 @@ private void WriteStartSuppressFalse(ref ReadOnlySpan propertyName, byte t if (propertyIdx != -1) { - WriteStartEscapeProperty(ref propertyName, token, propertyIdx); + WriteStartEscapeProperty(propertyName, token, propertyIdx); } else { - WriteStartByOptions(ref propertyName, token); + WriteStartByOptions(propertyName, token); } } - private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token) + private void WriteStartByOptions(in ReadOnlySpan propertyName, byte token) { int idx; if (_writerOptions.Indented) @@ -569,7 +569,7 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token ValidateWritingProperty(); UpdateBitStackOnStart(token); } - idx = WritePropertyNameIndented(ref propertyName); + idx = WritePropertyNameIndented(propertyName); } else { @@ -578,7 +578,7 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token ValidateWritingProperty(); UpdateBitStackOnStart(token); } - idx = WritePropertyNameMinimized(ref propertyName); + idx = WritePropertyNameMinimized(propertyName); } if (1 > _buffer.Length - idx) @@ -592,7 +592,7 @@ private void WriteStartByOptions(ref ReadOnlySpan propertyName, byte token Advance(idx); } - private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + private void WriteStartEscapeProperty(in ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -614,10 +614,9 @@ private void WriteStartEscapeProperty(ref ReadOnlySpan propertyName, byte span = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(ref propertyName, ref span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - WriteStartByOptions(ref propertyName, token); + WriteStartByOptions(span.Slice(0, written), token); if (propertyArray != null) { @@ -811,28 +810,22 @@ private void GrowAndEnsure() { Flush(); int previousSpanLength = _buffer.Length; + Debug.Assert(previousSpanLength < DefaultGrowthSize); _buffer = _output.GetSpan(DefaultGrowthSize); if (_buffer.Length <= previousSpanLength) { - _buffer = _output.GetSpan(DefaultGrowthSize); - if (_buffer.Length <= previousSpanLength) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.FailedToGetLargerSpan); - } + ThrowHelper.ThrowArgumentException(ExceptionResource.FailedToGetLargerSpan); } } private void GrowAndEnsure(int minimumSize) { Flush(); + Debug.Assert(minimumSize < DefaultGrowthSize); _buffer = _output.GetSpan(DefaultGrowthSize); if (_buffer.Length < minimumSize) { - _buffer = _output.GetSpan(DefaultGrowthSize); - if (_buffer.Length < minimumSize) - { - ThrowHelper.ThrowArgumentException(ExceptionResource.FailedToGetMinimumSizeSpan, minimumSize); - } + ThrowHelper.ThrowArgumentException(ExceptionResource.FailedToGetMinimumSizeSpan, minimumSize); } } @@ -850,7 +843,7 @@ private void AdvanceAndGrow(int alreadyWritten, int minimumSize) GrowAndEnsure(minimumSize); } - private void CopyLoop(ref ReadOnlySpan span, ref int idx) + private void CopyLoop(ReadOnlySpan span, ref int idx) { while (true) { diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 00dc34eb6620..706d2667921e 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -1403,6 +1403,60 @@ public void WriteHelloWorldEscaped(bool formatted, bool skipValidation, string k } } + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void EscapingLeavesInputUnchanged(bool formatted, bool skipValidation) + { + string keyStr = "mess\nage"; + string valueStr = "Hello, \nWorld!"; + + ReadOnlySpan keyUtf16 = keyStr; + ReadOnlySpan valueUtf16 = valueStr; + + byte[] keyUtf8 = Encoding.UTF8.GetBytes(keyStr); + byte[] valueUtf8 = Encoding.UTF8.GetBytes(valueStr); + + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + + for (int i = 0; i < 5; i++) + { + var output = new ArrayBufferWriter(1024); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + jsonUtf8.WriteStartObject(); + + switch (i) + { + case 0: + jsonUtf8.WriteString(keyUtf8, valueStr, suppressEscaping: false); + break; + case 1: + jsonUtf8.WriteString(keyUtf8, valueUtf16, suppressEscaping: false); + break; + case 2: + jsonUtf8.WriteString(keyUtf8, valueUtf8, suppressEscaping: false); + break; + case 3: + jsonUtf8.WriteString(keyStr, valueUtf8, suppressEscaping: false); + break; + case 4: + jsonUtf8.WriteString(keyUtf16, valueUtf8, suppressEscaping: false); + break; + } + + jsonUtf8.WriteEndObject(); + jsonUtf8.Flush(); + + output.Dispose(); + + Assert.True(keyUtf8.AsSpan().SequenceEqual(Encoding.UTF8.GetBytes(keyStr))); + Assert.True(valueUtf8.AsSpan().SequenceEqual(Encoding.UTF8.GetBytes(valueStr))); + } + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] From a91c70229ff562d6e5739c371cfaf6d6b46f60d7 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 18:39:34 -0800 Subject: [PATCH 19/33] Update comments and remove unnecessary test. --- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 4 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 4 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 4 +- ...JsonWriter.WriteProperties.SignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteProperties.String.cs | 16 +++--- ...onWriter.WriteProperties.UnsignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteValues.Comment.cs | 4 +- .../Utf8JsonWriter.WriteValues.String.cs | 4 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 4 +- .../tests/Utf8JsonWriterTests.cs | 54 ------------------- 14 files changed, 32 insertions(+), 86 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 272dc8ee6353..8214909cd474 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -130,7 +130,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -162,7 +162,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 228eae03b57a..35de9f7a563b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -130,7 +130,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -162,7 +162,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 82ab5c89d92c..532583ce11cb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -130,7 +130,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decim } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -162,7 +162,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decim } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index b62921ef1703..2b92aa61117c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -132,7 +132,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, doubl } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -164,7 +164,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, doubl } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 3faa54f4eecb..38a89e0c01db 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -132,7 +132,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -164,7 +164,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index c7f47226843e..e3fc03b2280b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -130,7 +130,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -162,7 +162,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index ff90d286fca9..6264765260f7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -207,7 +207,7 @@ private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -239,7 +239,7 @@ private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index d77f0b7ad4b2..229c931a06ef 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -175,7 +175,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -207,7 +207,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index e603fcb257d0..729b711dc3f8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -415,7 +415,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -437,7 +437,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -481,7 +481,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; @@ -503,7 +503,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; @@ -547,7 +547,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; @@ -569,7 +569,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -613,7 +613,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -635,7 +635,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 7ad1a3bb3da2..d265e4c8d3bb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -181,7 +181,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -213,7 +213,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 0110343ca1ae..fda3465d2771 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -124,7 +124,7 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -246,7 +246,7 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index c73f866f1007..e518259186de 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -156,7 +156,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; @@ -308,7 +308,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index d4295b24ff76..84c8c33429d0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -433,7 +433,7 @@ private void WriteStartEscapeProperty(in ReadOnlySpan propertyName, byte t } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { byte* ptr = stackalloc byte[length]; @@ -607,7 +607,7 @@ private void WriteStartEscapeProperty(in ReadOnlySpan propertyName, byte t } else { - // Cannot create a span directly since the span gets exposed outside this method. + // Cannot create a span directly since it gets passed to instance methods on a ref struct. unsafe { char* ptr = stackalloc char[length]; diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 706d2667921e..00dc34eb6620 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -1403,60 +1403,6 @@ public void WriteHelloWorldEscaped(bool formatted, bool skipValidation, string k } } - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void EscapingLeavesInputUnchanged(bool formatted, bool skipValidation) - { - string keyStr = "mess\nage"; - string valueStr = "Hello, \nWorld!"; - - ReadOnlySpan keyUtf16 = keyStr; - ReadOnlySpan valueUtf16 = valueStr; - - byte[] keyUtf8 = Encoding.UTF8.GetBytes(keyStr); - byte[] valueUtf8 = Encoding.UTF8.GetBytes(valueStr); - - var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - - for (int i = 0; i < 5; i++) - { - var output = new ArrayBufferWriter(1024); - var jsonUtf8 = new Utf8JsonWriter(output, state); - - jsonUtf8.WriteStartObject(); - - switch (i) - { - case 0: - jsonUtf8.WriteString(keyUtf8, valueStr, suppressEscaping: false); - break; - case 1: - jsonUtf8.WriteString(keyUtf8, valueUtf16, suppressEscaping: false); - break; - case 2: - jsonUtf8.WriteString(keyUtf8, valueUtf8, suppressEscaping: false); - break; - case 3: - jsonUtf8.WriteString(keyStr, valueUtf8, suppressEscaping: false); - break; - case 4: - jsonUtf8.WriteString(keyUtf16, valueUtf8, suppressEscaping: false); - break; - } - - jsonUtf8.WriteEndObject(); - jsonUtf8.Flush(); - - output.Dispose(); - - Assert.True(keyUtf8.AsSpan().SequenceEqual(Encoding.UTF8.GetBytes(keyStr))); - Assert.True(valueUtf8.AsSpan().SequenceEqual(Encoding.UTF8.GetBytes(valueStr))); - } - } - [Theory] [InlineData(true, true)] [InlineData(true, false)] From f1cdc28129f62f838719831d0357971e21528ebe Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 19:07:36 -0800 Subject: [PATCH 20/33] Remove some aggressive inlining and pass spans by value rather than in --- .../Json/Writer/JsonWriterHelper.Escaping.cs | 10 ++-- .../Text/Json/Writer/JsonWriterHelper.cs | 17 +++--- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 20 +++---- ...onWriter.WriteProperties.DateTimeOffset.cs | 20 +++---- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 20 +++---- .../Utf8JsonWriter.WriteProperties.Double.cs | 20 +++---- .../Utf8JsonWriter.WriteProperties.Float.cs | 20 +++---- .../Utf8JsonWriter.WriteProperties.Guid.cs | 20 +++---- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 12 ++--- .../Utf8JsonWriter.WriteProperties.Literal.cs | 12 ++--- ...JsonWriter.WriteProperties.SignedNumber.cs | 20 +++---- .../Utf8JsonWriter.WriteProperties.String.cs | 52 +++++++++---------- ...onWriter.WriteProperties.UnsignedNumber.cs | 20 +++---- .../Utf8JsonWriter.WriteValues.Comment.cs | 20 +++---- .../Utf8JsonWriter.WriteValues.Literal.cs | 6 +-- .../Utf8JsonWriter.WriteValues.String.cs | 16 +++--- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 12 ++--- 17 files changed, 157 insertions(+), 160 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 40eb85143400..2cd357a53c18 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -44,7 +44,6 @@ internal static partial class JsonWriterHelper [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool NeedsEscaping(char value) => value > byte.MaxValue || AllowList[value] == 0; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int NeedsEscaping(ReadOnlySpan value) { int idx; @@ -62,7 +61,6 @@ public static int NeedsEscaping(ReadOnlySpan value) return idx; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int NeedsEscaping(ReadOnlySpan value) { int idx; @@ -80,7 +78,7 @@ public static int NeedsEscaping(ReadOnlySpan value) return idx; } - public static void EscapeString(in ReadOnlySpan value, in Span destination, int indexOfFirstByteToEscape, out int written) + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -104,7 +102,7 @@ public static void EscapeString(in ReadOnlySpan value, in Span desti } } - private static int EscapeNextBytes(ReadOnlySpan value, in Span destination, ref int written) + private static int EscapeNextBytes(ReadOnlySpan value, Span destination, ref int written) { SequenceValidity status = PeekFirstSequence(value, out int numBytesConsumed, out Rune rune); if (status != SequenceValidity.WellFormed) @@ -381,7 +379,7 @@ public static SequenceValidity PeekFirstSequence(ReadOnlySpan data, out in return SequenceValidity.Incomplete; } - public static void EscapeString(in ReadOnlySpan value, in Span destination, int indexOfFirstByteToEscape, out int written) + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); @@ -404,7 +402,7 @@ public static void EscapeString(in ReadOnlySpan value, in Span desti } } - private static void EscapeNextChars(in ReadOnlySpan value, int firstChar, in Span destination, ref int consumed, ref int written) + private static void EscapeNextChars(ReadOnlySpan value, int firstChar, Span destination, ref int consumed, ref int written) { int nextChar = -1; if (IsInRangeInclusive(firstChar, JsonConstants.HighSurrogateStartValue, JsonConstants.LowSurrogateEndValue)) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 26556e5ff99f..01fdea2e6dcc 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -11,7 +11,6 @@ namespace System.Text.Json { internal static partial class JsonWriterHelper { - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryWriteIndentation(Span buffer, int indent, out int bytesWritten) { Debug.Assert(indent % JsonConstants.SpacesPerIndent == 0); @@ -50,14 +49,14 @@ public static bool TryWriteIndentation(Span buffer, int indent, out int by } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateProperty(in ReadOnlySpan propertyName) + public static void ValidateProperty(ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateValue(in ReadOnlySpan value) + public static void ValidateValue(ReadOnlySpan value) { if (value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); @@ -78,42 +77,42 @@ public static void ValidateSingle(float value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateProperty(in ReadOnlySpan propertyName) + public static void ValidateProperty(ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException_PropertyNameTooLarge(propertyName.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidateValue(in ReadOnlySpan value) + public static void ValidateValue(ReadOnlySpan value) { if (value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException_ValueTooLarge(value.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) + public static void ValidatePropertyAndValue(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) + public static void ValidatePropertyAndValue(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) + public static void ValidatePropertyAndValue(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxTokenSize || value.Length > JsonConstants.MaxTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void ValidatePropertyAndValue(in ReadOnlySpan propertyName, in ReadOnlySpan value) + public static void ValidatePropertyAndValue(ReadOnlySpan propertyName, ReadOnlySpan value) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 8214909cd474..d64433fd58f6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -83,7 +83,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTime value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTime value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -99,7 +99,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTi } } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTime value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTime value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -115,7 +115,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTi } } - private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -147,7 +147,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } } - private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -179,7 +179,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTime value) + private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime value) { if (_writerOptions.Indented) { @@ -199,7 +199,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTime v } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTime value) + private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime value) { if (_writerOptions.Indented) { @@ -219,7 +219,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTime v } } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, DateTime value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -228,7 +228,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Dat Advance(idx); } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, DateTime value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -237,7 +237,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Dat Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTime value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -246,7 +246,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Date Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTime value) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTime value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 35de9f7a563b..9df6a064d49b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -83,7 +83,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTimeOffset value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -99,7 +99,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTi } } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTimeOffset value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -115,7 +115,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, DateTi } } - private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -147,7 +147,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } } - private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -179,7 +179,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, DateT } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffset value) { if (_writerOptions.Indented) { @@ -199,7 +199,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTimeOf } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffset value) { if (_writerOptions.Indented) { @@ -219,7 +219,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, DateTimeOf } } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, DateTimeOffset value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -228,7 +228,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Dat Advance(idx); } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, DateTimeOffset value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -237,7 +237,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Dat Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTimeOffset value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -246,7 +246,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Date Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, DateTimeOffset value) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTimeOffset value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 532583ce11cb..57f5bad911b8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -83,7 +83,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, decimal value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, decimal value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -99,7 +99,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, decima } } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, decimal value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, decimal value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -115,7 +115,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, decima } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -147,7 +147,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decim } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -179,7 +179,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, decim } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, decimal value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value) { if (_writerOptions.Indented) { @@ -199,7 +199,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, decimal va } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, decimal value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value) { if (_writerOptions.Indented) { @@ -219,7 +219,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, decimal va } } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, decimal value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -228,7 +228,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, dec Advance(idx); } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, decimal value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -237,7 +237,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, dec Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -246,7 +246,7 @@ private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, deci Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, decimal value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 2b92aa61117c..fdeaf295589f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -85,7 +85,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, double value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, double value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -101,7 +101,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, double } } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, double value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, double value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -117,7 +117,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, double } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -149,7 +149,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, doubl } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -181,7 +181,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, doubl } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, double value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { if (_writerOptions.Indented) { @@ -201,7 +201,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, double val } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, double value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { if (_writerOptions.Indented) { @@ -221,7 +221,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, double val } } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, double value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -230,7 +230,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, dou Advance(idx); } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, double value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -239,7 +239,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, dou Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -248,7 +248,7 @@ private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, doub Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, double value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 38a89e0c01db..f15de8457f1e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -85,7 +85,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, float value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, float value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -101,7 +101,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, float } } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, float value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, float value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -117,7 +117,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, float } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -149,7 +149,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -181,7 +181,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, float } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, float value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { if (_writerOptions.Indented) { @@ -201,7 +201,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, float valu } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, float value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { if (_writerOptions.Indented) { @@ -221,7 +221,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, float valu } } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, float value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -230,7 +230,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, flo Advance(idx); } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, float value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -239,7 +239,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, flo Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -248,7 +248,7 @@ private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, floa Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, float value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index e3fc03b2280b..fb02d442fcfe 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -83,7 +83,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, Guid value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -99,7 +99,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, Guid v } } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, Guid value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -115,7 +115,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, Guid v } } - private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -147,7 +147,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid } } - private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -179,7 +179,7 @@ private void WriteStringEscapeProperty(in ReadOnlySpan propertyName, Guid } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, Guid value) + private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { if (_writerOptions.Indented) { @@ -199,7 +199,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, Guid value } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, Guid value) + private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { if (_writerOptions.Indented) { @@ -219,7 +219,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, Guid value } } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, Guid value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -228,7 +228,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Gui Advance(idx); } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, Guid value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -237,7 +237,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, Gui Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -246,7 +246,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Guid Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, Guid value) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index ddbcd82ab9a6..934e0f4e6093 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -12,14 +12,14 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ValidatePropertyNameAndDepth(in ReadOnlySpan propertyName) + private void ValidatePropertyNameAndDepth(ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ValidatePropertyNameAndDepth(in ReadOnlySpan propertyName) + private void ValidatePropertyNameAndDepth(ReadOnlySpan propertyName) { if (propertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); @@ -34,7 +34,7 @@ private void ValidateWritingProperty() } } - private int WritePropertyNameMinimized(in ReadOnlySpan escapedPropertyName) + private int WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) @@ -72,7 +72,7 @@ private int WritePropertyNameMinimized(in ReadOnlySpan escapedPropertyName return idx; } - private int WritePropertyNameIndented(in ReadOnlySpan escapedPropertyName) + private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) @@ -134,7 +134,7 @@ private int WritePropertyNameIndented(in ReadOnlySpan escapedPropertyName) return idx; } - private int WritePropertyNameMinimized(in ReadOnlySpan escapedPropertyName) + private int WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) @@ -185,7 +185,7 @@ private int WritePropertyNameMinimized(in ReadOnlySpan escapedPropertyName return idx; } - private int WritePropertyNameIndented(in ReadOnlySpan escapedPropertyName) + private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) { int idx = 0; if (_currentDepth < 0) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 6264765260f7..9e3fccc1d7b6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -160,7 +160,7 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr _tokenType = value ? JsonTokenType.True : JsonTokenType.False; } - private void WriteLiteralSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteLiteralSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -176,7 +176,7 @@ private void WriteLiteralSuppressFalse(in ReadOnlySpan propertyName, in Re } } - private void WriteLiteralSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteLiteralSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -192,7 +192,7 @@ private void WriteLiteralSuppressFalse(in ReadOnlySpan propertyName, in Re } } - private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in ReadOnlySpan value, int firstEscapeIndexProp) + private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -224,7 +224,7 @@ private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in R } } - private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in ReadOnlySpan value, int firstEscapeIndexProp) + private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -256,7 +256,7 @@ private void WriteLiteralEscapeProperty(in ReadOnlySpan propertyName, in R } } - private void WriteLiteralByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { int idx; if (_writerOptions.Indented) @@ -288,7 +288,7 @@ private void WriteLiteralByOptions(in ReadOnlySpan propertyName, in ReadOn Advance(idx); } - private void WriteLiteralByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { int idx; if (_writerOptions.Indented) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 229c931a06ef..a23c11f7bab4 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -128,7 +128,7 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppres public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName, (long)value, suppressEscaping); - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, long value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, long value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -144,7 +144,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, long v } } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, long value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, long value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -160,7 +160,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, long v } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -192,7 +192,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -224,7 +224,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, long } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, long value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { if (_writerOptions.Indented) { @@ -244,7 +244,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, long value } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, long value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { if (_writerOptions.Indented) { @@ -264,7 +264,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, long value } } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, long value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -273,7 +273,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, lon Advance(idx); } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, long value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -282,7 +282,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, lon Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -291,7 +291,7 @@ private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, long Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, long value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 729b711dc3f8..ea34f4aee28f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -212,7 +212,7 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool supp => WriteString(propertyName, value.AsSpan(), suppressEscaping); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) + private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -226,7 +226,7 @@ private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) + private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -240,7 +240,7 @@ private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) + private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -254,7 +254,7 @@ private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value) + private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -267,7 +267,7 @@ private void WriteStringSuppressTrue(in ReadOnlySpan escapedPropertyName, } } - private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -280,7 +280,7 @@ private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyNam ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -293,7 +293,7 @@ private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyNam ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -306,7 +306,7 @@ private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyNam ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); @@ -319,7 +319,7 @@ private void WriteStringEscapeValueOnly(in ReadOnlySpan escapedPropertyNam ArrayPool.Shared.Return(valueArray); } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -338,7 +338,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in Rea } } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -357,7 +357,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in Rea } } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -376,7 +376,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in Rea } } - private void WriteStringSuppressFalse(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -659,7 +659,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -679,7 +679,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnl } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -699,7 +699,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnl } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -719,7 +719,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnl } } - private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -739,7 +739,7 @@ private void WriteStringByOptions(in ReadOnlySpan propertyName, in ReadOnl } } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -748,7 +748,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in Advance(idx); } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -757,7 +757,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in Advance(idx); } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -766,7 +766,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in Advance(idx); } - private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -775,7 +775,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedPropertyName, in Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -784,7 +784,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in R Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -793,7 +793,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in R Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -802,7 +802,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in R Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in ReadOnlySpan escapedValue) + private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -811,7 +811,7 @@ private void WriteStringIndented(in ReadOnlySpan escapedPropertyName, in R Advance(idx); } - private void WriteStringValue(in ReadOnlySpan escapedValue, ref int idx) + private void WriteStringValue(ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { @@ -843,7 +843,7 @@ private void WriteStringValue(in ReadOnlySpan escapedValue, ref int idx) _buffer[idx++] = JsonConstants.Quote; } - private void WriteStringValue(in ReadOnlySpan escapedValue, ref int idx) + private void WriteStringValue(ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index d265e4c8d3bb..d892e636a160 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -134,7 +134,7 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppre public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName, (ulong)value, suppressEscaping); - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, ulong value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, ulong value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -150,7 +150,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, ulong } } - private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, ulong value) + private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, ulong value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -166,7 +166,7 @@ private void WriteNumberSuppressFalse(in ReadOnlySpan propertyName, ulong } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -198,7 +198,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong } } - private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -230,7 +230,7 @@ private void WriteNumberEscapeProperty(in ReadOnlySpan propertyName, ulong } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, ulong value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { if (_writerOptions.Indented) { @@ -250,7 +250,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, ulong valu } } - private void WriteNumberByOptions(in ReadOnlySpan propertyName, ulong value) + private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { if (_writerOptions.Indented) { @@ -270,7 +270,7 @@ private void WriteNumberByOptions(in ReadOnlySpan propertyName, ulong valu } } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, ulong value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -279,7 +279,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, ulo Advance(idx); } - private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, ulong value) { int idx = WritePropertyNameMinimized(escapedPropertyName); @@ -288,7 +288,7 @@ private void WriteNumberMinimized(in ReadOnlySpan escapedPropertyName, ulo Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong value) { int idx = WritePropertyNameIndented(escapedPropertyName); @@ -297,7 +297,7 @@ private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, ulon Advance(idx); } - private void WriteNumberIndented(in ReadOnlySpan escapedPropertyName, ulong value) + private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong value) { int idx = WritePropertyNameIndented(escapedPropertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index fda3465d2771..73bbcc949dc3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -43,7 +43,7 @@ public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = } } - private void WriteCommentSuppressFalse(in ReadOnlySpan value) + private void WriteCommentSuppressFalse(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -59,7 +59,7 @@ private void WriteCommentSuppressFalse(in ReadOnlySpan value) } } - private void WriteCommentByOptions(in ReadOnlySpan value) + private void WriteCommentByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -71,7 +71,7 @@ private void WriteCommentByOptions(in ReadOnlySpan value) } } - private void WriteCommentMinimized(in ReadOnlySpan escapedValue) + private void WriteCommentMinimized(ReadOnlySpan escapedValue) { int idx = 0; @@ -80,7 +80,7 @@ private void WriteCommentMinimized(in ReadOnlySpan escapedValue) Advance(idx); } - private void WriteCommentIndented(in ReadOnlySpan escapedValue) + private void WriteCommentIndented(ReadOnlySpan escapedValue) { int idx = 0; @@ -165,7 +165,7 @@ public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = } } - private void WriteCommentSuppressFalse(in ReadOnlySpan value) + private void WriteCommentSuppressFalse(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -181,7 +181,7 @@ private void WriteCommentSuppressFalse(in ReadOnlySpan value) } } - private void WriteCommentByOptions(in ReadOnlySpan value) + private void WriteCommentByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -193,7 +193,7 @@ private void WriteCommentByOptions(in ReadOnlySpan value) } } - private void WriteCommentMinimized(in ReadOnlySpan escapedValue) + private void WriteCommentMinimized(ReadOnlySpan escapedValue) { int idx = 0; @@ -202,7 +202,7 @@ private void WriteCommentMinimized(in ReadOnlySpan escapedValue) Advance(idx); } - private void WriteCommentIndented(in ReadOnlySpan escapedValue) + private void WriteCommentIndented(ReadOnlySpan escapedValue) { int idx = 0; @@ -265,7 +265,7 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn } } - private void WriteCommentValue(in ReadOnlySpan escapedValue, ref int idx) + private void WriteCommentValue(ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { @@ -311,7 +311,7 @@ private void WriteCommentValue(in ReadOnlySpan escapedValue, ref int idx) _buffer[idx++] = JsonConstants.Slash; } - private void WriteCommentValue(in ReadOnlySpan escapedValue, ref int idx) + private void WriteCommentValue(ReadOnlySpan escapedValue, ref int idx) { while (_buffer.Length <= idx) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index ea0c71abdd3f..7b619e904937 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -43,7 +43,7 @@ public void WriteBooleanValue(bool value) _currentDepth |= 1 << 31; } - private void WriteLiteralByOptions(in ReadOnlySpan value) + private void WriteLiteralByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -63,7 +63,7 @@ private void WriteLiteralByOptions(in ReadOnlySpan value) } } - private void WriteLiteralMinimized(in ReadOnlySpan value) + private void WriteLiteralMinimized(ReadOnlySpan value) { // Calculated based on the following: ',null' OR ',true' OR ',false' int bytesNeeded = value.Length + 1; @@ -83,7 +83,7 @@ private void WriteLiteralMinimized(in ReadOnlySpan value) Advance(idx + value.Length); } - private void WriteLiteralIndented(in ReadOnlySpan value) + private void WriteLiteralIndented(ReadOnlySpan value) { int idx = 0; if (_currentDepth < 0) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index e518259186de..0480084cd2ab 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -51,7 +51,7 @@ public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = f _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(in ReadOnlySpan value) + private void WriteStringSuppressFalse(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -67,7 +67,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan value) } } - private void WriteStringByOptions(in ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -87,7 +87,7 @@ private void WriteStringByOptions(in ReadOnlySpan value) } } - private void WriteStringMinimized(in ReadOnlySpan escapedValue) + private void WriteStringMinimized(ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -104,7 +104,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedValue) Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedValue) + private void WriteStringIndented(ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -203,7 +203,7 @@ public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = f _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(in ReadOnlySpan value) + private void WriteStringSuppressFalse(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -219,7 +219,7 @@ private void WriteStringSuppressFalse(in ReadOnlySpan value) } } - private void WriteStringByOptions(in ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { @@ -239,7 +239,7 @@ private void WriteStringByOptions(in ReadOnlySpan value) } } - private void WriteStringMinimized(in ReadOnlySpan escapedValue) + private void WriteStringMinimized(ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) @@ -256,7 +256,7 @@ private void WriteStringMinimized(in ReadOnlySpan escapedValue) Advance(idx); } - private void WriteStringIndented(in ReadOnlySpan escapedValue) + private void WriteStringIndented(ReadOnlySpan escapedValue) { int idx = 0; if (_currentDepth < 0) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 84c8c33429d0..a3d7ead7f869 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -369,7 +369,7 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap _tokenType = JsonTokenType.StartObject; } - private void WriteStartSuppressFalse(in ReadOnlySpan propertyName, byte token) + private void WriteStartSuppressFalse(ReadOnlySpan propertyName, byte token) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -385,7 +385,7 @@ private void WriteStartSuppressFalse(in ReadOnlySpan propertyName, byte to } } - private void WriteStartByOptions(in ReadOnlySpan propertyName, byte token) + private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) { int idx; if (_writerOptions.Indented) @@ -418,7 +418,7 @@ private void WriteStartByOptions(in ReadOnlySpan propertyName, byte token) Advance(idx); } - private void WriteStartEscapeProperty(in ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); @@ -543,7 +543,7 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap _tokenType = JsonTokenType.StartObject; } - private void WriteStartSuppressFalse(in ReadOnlySpan propertyName, byte token) + private void WriteStartSuppressFalse(ReadOnlySpan propertyName, byte token) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -559,7 +559,7 @@ private void WriteStartSuppressFalse(in ReadOnlySpan propertyName, byte to } } - private void WriteStartByOptions(in ReadOnlySpan propertyName, byte token) + private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) { int idx; if (_writerOptions.Indented) @@ -592,7 +592,7 @@ private void WriteStartByOptions(in ReadOnlySpan propertyName, byte token) Advance(idx); } - private void WriteStartEscapeProperty(in ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); From baa5ac294a71a2d0f56c6ad50095b8396b56ac50 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 21:33:51 -0800 Subject: [PATCH 21/33] Update comments, dont compute bytes needed, and use if instead of loop before advancing. --- .../Text/Json/Writer/JsonWriterOptions.cs | 28 +++-- .../Text/Json/Writer/JsonWriterState.cs | 4 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 41 ++---- ...onWriter.WriteProperties.DateTimeOffset.cs | 41 ++---- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 31 ++--- .../Utf8JsonWriter.WriteProperties.Double.cs | 31 ++--- .../Utf8JsonWriter.WriteProperties.Float.cs | 31 ++--- .../Utf8JsonWriter.WriteProperties.Guid.cs | 39 ++---- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 114 ++++++++--------- .../Utf8JsonWriter.WriteProperties.Literal.cs | 34 ++--- ...JsonWriter.WriteProperties.SignedNumber.cs | 31 ++--- .../Utf8JsonWriter.WriteProperties.String.cs | 81 ++++-------- ...onWriter.WriteProperties.UnsignedNumber.cs | 31 ++--- .../Utf8JsonWriter.WriteValues.Comment.cs | 51 +++----- .../Utf8JsonWriter.WriteValues.DateTime.cs | 35 ++---- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 35 ++---- .../Utf8JsonWriter.WriteValues.Decimal.cs | 19 +-- .../Utf8JsonWriter.WriteValues.Double.cs | 19 +-- .../Utf8JsonWriter.WriteValues.Float.cs | 19 +-- .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 35 ++---- .../Utf8JsonWriter.WriteValues.Helpers.cs | 19 +-- .../Utf8JsonWriter.WriteValues.Literal.cs | 34 ++--- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 32 ++--- .../Utf8JsonWriter.WriteValues.String.cs | 40 ++---- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 32 ++--- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 118 ++++++++---------- 26 files changed, 376 insertions(+), 649 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 629999236ad6..26428994f854 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -23,39 +23,47 @@ public bool Indented { get { - return (_optionsMask & 1) != 0; + return (_optionsMask & IndentBit) != 0; } set { if (value) - _optionsMask |= 1; + _optionsMask |= IndentBit; else - _optionsMask &= ~1; + _optionsMask &= ~IndentBit; } } /// /// Defines whether the should skip structural validation and allow /// the user to write invalid JSON, when set to true. If set to false, any attempts to write invalid JSON will result in - /// a to be thrown (for example, writing a value within an object - /// without a property name). If the JSON being written is known to be correct - /// then skipping validation (by setting it to true) could improve performance. + /// a to be thrown. /// + /// + /// If the JSON being written is known to be correct, + /// then skipping validation (by setting it to true) could improve performance. + /// An example of invalid JSON where the writer will throw (when SkipValidation + /// is set to false) is when you write a value within a JSON object + /// without a property name. + /// public bool SkipValidation { get { - return (_optionsMask & 2) != 0; + return (_optionsMask & SkipValidationBit) != 0; } set { if (value) - _optionsMask |= 2; + _optionsMask |= SkipValidationBit; else - _optionsMask &= ~2; + _optionsMask &= ~SkipValidationBit; } } - internal bool SlowPath => _optionsMask != 2; // Equivalent to: Indented || !SkipValidation; + internal bool IndentedOrNotSkipValidation => _optionsMask != SkipValidationBit; // Equivalent to: Indented || !SkipValidation; + + private const int IndentBit = 1; + private const int SkipValidationBit = 2; } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs index c9420aaf143d..52e98d4a3f7d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterState.cs @@ -7,11 +7,13 @@ namespace System.Text.Json /// /// Defines an opaque type that holds and saves all the relevant state information which must be provided /// to the to continue writing after completing a partial write. + /// + /// /// This type is required to support reentrancy when writing incomplete data, and to continue /// writing in chunks. Unlike the , which is a ref struct, /// this type can survive across async/await boundaries and hence this type is required to provide /// support for writing more JSON text asynchronously before continuing with a new instance of the . - /// + /// public struct JsonWriterState { internal long _bytesWritten; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index d64433fd58f6..46fcb60f1cdd 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -50,7 +50,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su WriteStringByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -79,7 +79,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su WriteStringByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -183,18 +183,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime valu { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -203,18 +197,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime valu { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -257,30 +245,27 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim private void WriteStringValue(DateTime value, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; FormatLoop(value, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; } private void FormatLoop(DateTime value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatDateTimeLength); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDateTimeLength); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 9df6a064d49b..3692b2916408 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -50,7 +50,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b WriteStringByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -79,7 +79,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b WriteStringByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -183,18 +183,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffse { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -203,18 +197,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffse { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -257,30 +245,27 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim private void WriteStringValue(DateTimeOffset value, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; FormatLoop(value, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; } private void FormatLoop(DateTimeOffset value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatDateTimeOffsetLength); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDateTimeOffsetLength); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 57f5bad911b8..49b732edc7b2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -50,7 +50,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -79,7 +79,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -183,18 +183,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -203,18 +197,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -257,11 +245,10 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal private void WriteNumberValueFormatLoop(decimal value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatDecimalLength); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDecimalLength); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index fdeaf295589f..5015982d3f72 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -51,7 +51,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -81,7 +81,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -185,18 +185,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -205,18 +199,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -259,11 +247,10 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double private void WriteNumberValueFormatLoop(double value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatDoubleLength); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDoubleLength); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index f15de8457f1e..839a760ba4eb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -51,7 +51,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -81,7 +81,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -185,18 +185,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -205,18 +199,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -259,11 +247,10 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float v private void WriteNumberValueFormatLoop(float value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatSingleLength); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatSingleLength); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index fb02d442fcfe..9104805ab373 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -50,7 +50,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre WriteStringByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -79,7 +79,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre WriteStringByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -183,18 +183,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -203,18 +197,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -257,18 +245,18 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid va private void WriteStringValue(Guid value, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); + AdvanceAndGrow(ref idx); idx = 0; } _buffer[idx++] = JsonConstants.Quote; FormatLoop(value, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); + AdvanceAndGrow(ref idx); idx = 0; } _buffer[idx++] = JsonConstants.Quote; @@ -276,11 +264,10 @@ private void WriteStringValue(Guid value, ref int idx) private void FormatLoop(Guid value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatGuidLength); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatGuidLength); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index 934e0f4e6093..122d269c8abd 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -25,12 +25,30 @@ private void ValidatePropertyNameAndDepth(ReadOnlySpan propertyName) ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void ValidateWritingProperty() { - if (!_inObject) + if (!_writerOptions.SkipValidation) { - Debug.Assert(_tokenType != JsonTokenType.StartObject); - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWritePropertyWithinArray, tokenType: _tokenType); + if (!_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.StartObject); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWritePropertyWithinArray, tokenType: _tokenType); + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ValidateWritingProperty(byte token) + { + if (!_writerOptions.SkipValidation) + { + if (!_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.StartObject); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWritePropertyWithinArray, tokenType: _tokenType); + } + UpdateBitStackOnStart(token); } } @@ -39,33 +57,30 @@ private int WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } _buffer[idx++] = JsonConstants.ListSeparator; } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; CopyLoop(escapedPropertyName, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.KeyValueSeperator; @@ -77,7 +92,7 @@ private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -97,37 +112,32 @@ private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; CopyLoop(escapedPropertyName, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.KeyValueSeperator; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Space; @@ -139,17 +149,16 @@ private int WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } _buffer[idx++] = JsonConstants.ListSeparator; } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; @@ -164,21 +173,18 @@ private int WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName) break; } partialConsumed += consumed; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.KeyValueSeperator; @@ -190,7 +196,7 @@ private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -210,14 +216,12 @@ private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; @@ -232,28 +236,24 @@ private int WritePropertyNameIndented(ReadOnlySpan escapedPropertyName) break; } partialConsumed += consumed; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.KeyValueSeperator; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Space; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 9e3fccc1d7b6..73317fc44078 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -49,7 +49,7 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f WriteLiteralByOptions(propertyName, span); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Null; } @@ -79,7 +79,7 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f WriteLiteralByOptions(propertyName, span); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Null; } @@ -125,7 +125,7 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr WriteLiteralByOptions(propertyName, span); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = value ? JsonTokenType.True : JsonTokenType.False; } @@ -156,7 +156,7 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr WriteLiteralByOptions(propertyName, span); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = value ? JsonTokenType.True : JsonTokenType.False; } @@ -261,25 +261,18 @@ private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan int idx; if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); idx = WritePropertyNameIndented(propertyName); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); idx = WritePropertyNameMinimized(propertyName); } if (value.Length > _buffer.Length - idx) { - AdvanceAndGrow(idx, value.Length); - idx = 0; + AdvanceAndGrow(ref idx, value.Length); } value.CopyTo(_buffer.Slice(idx)); @@ -293,25 +286,18 @@ private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan int idx; if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); idx = WritePropertyNameIndented(propertyName); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); idx = WritePropertyNameMinimized(propertyName); } if (value.Length > _buffer.Length - idx) { - AdvanceAndGrow(idx, value.Length); - idx = 0; + AdvanceAndGrow(ref idx, value.Length); } value.CopyTo(_buffer.Slice(idx)); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index a23c11f7bab4..6f208a80abee 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -50,7 +50,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -79,7 +79,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -228,18 +228,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -248,18 +242,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -302,11 +290,10 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long va private void WriteNumberValueFormatLoop(long value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatInt64Length); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatInt64Length); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index ea34f4aee28f..73823313461a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -12,7 +12,7 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { /// - /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// Writes the property name and string text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. @@ -53,7 +53,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu WriteStringSuppressTrue(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -83,12 +83,12 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu WriteStringSuppressTrue(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } /// - /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// Writes the property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. @@ -129,12 +129,12 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu WriteStringSuppressTrue(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } /// - /// Writes the UTF-16 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// Writes the property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. @@ -175,12 +175,12 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu WriteStringSuppressTrue(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } /// - /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// Writes the UTF-16 property name and string text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. @@ -196,7 +196,7 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool supp => WriteString(propertyName, value.AsSpan(), suppressEscaping); /// - /// Writes the UTF-8 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. + /// Writes the UTF-8 property name and string text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-8 encoded property name of the JSON object to be written. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. @@ -663,18 +663,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan< { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -683,18 +677,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan< { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -703,18 +691,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan< { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -723,18 +705,12 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan< { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } @@ -813,10 +789,9 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl private void WriteStringValue(ReadOnlySpan escapedValue, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; @@ -831,33 +806,29 @@ private void WriteStringValue(ReadOnlySpan escapedValue, ref int idx) break; } partialConsumed += consumed; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; } private void WriteStringValue(ReadOnlySpan escapedValue, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; CopyLoop(escapedValue, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Quote; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index d892e636a160..752aa7bf53e5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -52,7 +52,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -82,7 +82,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr WriteNumberByOptions(propertyName, value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -234,18 +234,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -254,18 +248,12 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - } + ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } @@ -308,11 +296,10 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong v private void WriteNumberValueFormatLoop(ulong value, ref int idx) { - int bytesWritten; - while (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { - AdvanceAndGrow(idx, JsonConstants.MaximumFormatUInt64Length); - idx = 0; + AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatUInt64Length); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 73bbcc949dc3..ca3952ea141a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -11,7 +11,7 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { /// - /// Writes the UTF-16 text value (as a JSON comment). + /// Writes the string text value (as a JSON comment). /// /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. @@ -97,8 +97,7 @@ private void WriteCommentIndented(ReadOnlySpan escapedValue) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteCommentValue(escapedValue, ref idx); @@ -219,8 +218,7 @@ private void WriteCommentIndented(ReadOnlySpan escapedValue) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteCommentValue(escapedValue, ref idx); @@ -267,17 +265,15 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn private void WriteCommentValue(ReadOnlySpan escapedValue, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Slash; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Asterisk; @@ -292,54 +288,47 @@ private void WriteCommentValue(ReadOnlySpan escapedValue, ref int idx) break; } partialConsumed += consumed; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Asterisk; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Slash; } private void WriteCommentValue(ReadOnlySpan escapedValue, ref int idx) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Slash; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Asterisk; CopyLoop(escapedValue, ref idx); - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Asterisk; - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.Slash; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index eda3ec8ee04a..a742d6a065fc 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -19,46 +19,32 @@ public void WriteStringValue(DateTime value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } private void WriteStringValueMinimized(DateTime value) { - // Calculated based on the following: ',"DateTime value"' - int bytesNeeded = JsonConstants.MaximumFormatDateTimeLength + 3; - if (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(bytesNeeded); - } - int idx = 0; if (_currentDepth < 0) { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } _buffer[idx++] = JsonConstants.ListSeparator; } - _buffer[idx++] = JsonConstants.Quote; - - Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); - idx += bytesWritten; - - _buffer[idx++] = JsonConstants.Quote; + WriteStringValue(value, ref idx); Advance(idx); } @@ -68,7 +54,7 @@ private void WriteStringValueIndented(DateTime value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -88,8 +74,7 @@ private void WriteStringValueIndented(DateTime value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 9cd206cdeb44..3ef4f2580794 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -19,46 +19,32 @@ public void WriteStringValue(DateTimeOffset value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } private void WriteStringValueMinimized(DateTimeOffset value) { - // Calculated based on the following: ',"DateTimeOffset value"' - int bytesNeeded = JsonConstants.MaximumFormatDateTimeOffsetLength + 3; - if (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(bytesNeeded); - } - int idx = 0; if (_currentDepth < 0) { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } _buffer[idx++] = JsonConstants.ListSeparator; } - _buffer[idx++] = JsonConstants.Quote; - - Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); - idx += bytesWritten; - - _buffer[idx++] = JsonConstants.Quote; + WriteStringValue(value, ref idx); Advance(idx); } @@ -68,7 +54,7 @@ private void WriteStringValueIndented(DateTimeOffset value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -88,8 +74,7 @@ private void WriteStringValueIndented(DateTimeOffset value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index d0e3e81e901c..e3bf333e4de2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -17,22 +17,16 @@ public void WriteNumberValue(decimal value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -41,7 +35,7 @@ private void WriteNumberValueMinimized(decimal value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -58,7 +52,7 @@ private void WriteNumberValueIndented(decimal value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -78,8 +72,7 @@ private void WriteNumberValueIndented(decimal value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 267f0961b354..47465ea9f336 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -19,22 +19,16 @@ public void WriteNumberValue(double value) if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -43,7 +37,7 @@ private void WriteNumberValueMinimized(double value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -60,7 +54,7 @@ private void WriteNumberValueIndented(double value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -80,8 +74,7 @@ private void WriteNumberValueIndented(double value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 0416eeeebc4e..667b3219df46 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -19,22 +19,16 @@ public void WriteNumberValue(float value) if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } @@ -43,7 +37,7 @@ private void WriteNumberValueMinimized(float value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -60,7 +54,7 @@ private void WriteNumberValueIndented(float value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -80,8 +74,7 @@ private void WriteNumberValueIndented(float value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index 783c2616d4b8..f64b5b25e5e2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -19,46 +19,32 @@ public void WriteStringValue(Guid value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } private void WriteStringValueMinimized(Guid value) { - // Calculated based on the following: ',"Guid value"' - int bytesNeeded = JsonConstants.MaximumFormatGuidLength + 3; - if (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(bytesNeeded); - } - int idx = 0; if (_currentDepth < 0) { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } _buffer[idx++] = JsonConstants.ListSeparator; } - _buffer[idx++] = JsonConstants.Quote; - - Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); - idx += bytesWritten; - - _buffer[idx++] = JsonConstants.Quote; + WriteStringValue(value, ref idx); Advance(idx); } @@ -68,7 +54,7 @@ private void WriteStringValueIndented(Guid value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -88,8 +74,7 @@ private void WriteStringValueIndented(Guid value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs index afcac558eebb..1e7ee95d6a4d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -10,16 +10,19 @@ public ref partial struct Utf8JsonWriter { private void ValidateWritingValue() { - if (_inObject) + if (!_writerOptions.SkipValidation) { - Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWriteValueWithinObject, tokenType: _tokenType); - } - else - { - if (!_isNotPrimitive && _tokenType != JsonTokenType.None) + if (_inObject) + { + Debug.Assert(_tokenType != JsonTokenType.None && _tokenType != JsonTokenType.StartArray); + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWriteValueWithinObject, tokenType: _tokenType); + } + else { - ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWriteValueAfterPrimitive, tokenType: _tokenType); + if (!_isNotPrimitive && _tokenType != JsonTokenType.None) + { + ThrowHelper.ThrowInvalidOperationException(ExceptionResource.CannotWriteValueAfterPrimitive, tokenType: _tokenType); + } } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 7b619e904937..3e084500e6b8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -16,7 +16,7 @@ public void WriteNullValue() { WriteLiteralByOptions(JsonConstants.NullValue); - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Null; } @@ -40,47 +40,38 @@ public void WriteBooleanValue(bool value) _tokenType = JsonTokenType.False; } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); } private void WriteLiteralByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteLiteralIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteLiteralMinimized(value); } } private void WriteLiteralMinimized(ReadOnlySpan value) { - // Calculated based on the following: ',null' OR ',true' OR ',false' - int bytesNeeded = value.Length + 1; - if (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(bytesNeeded); - } - int idx = 0; if (_currentDepth < 0) { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } _buffer[idx++] = JsonConstants.ListSeparator; } - value.CopyTo(_buffer.Slice(idx)); + CopyLoop(value, ref idx); - Advance(idx + value.Length); + Advance(idx); } private void WriteLiteralIndented(ReadOnlySpan value) @@ -88,7 +79,7 @@ private void WriteLiteralIndented(ReadOnlySpan value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -108,8 +99,7 @@ private void WriteLiteralIndented(ReadOnlySpan value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } CopyLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index dcaca4d292c9..daabbd59b17e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -29,43 +29,34 @@ public void WriteNumberValue(long value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } private void WriteNumberValueMinimized(long value) { - // Calculated based on the following: ',long.MaxValue' - int bytesNeeded = JsonConstants.MaximumFormatInt64Length + 1; - if (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(bytesNeeded); - } - int idx = 0; if (_currentDepth < 0) { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } _buffer[idx++] = JsonConstants.ListSeparator; } - Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); + WriteNumberValueFormatLoop(value, ref idx); - Advance(idx + bytesWritten); + Advance(idx); } private void WriteNumberValueIndented(long value) @@ -73,7 +64,7 @@ private void WriteNumberValueIndented(long value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -93,8 +84,7 @@ private void WriteNumberValueIndented(long value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 0480084cd2ab..536f795e84aa 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -10,7 +10,7 @@ namespace System.Text.Json public ref partial struct Utf8JsonWriter { /// - /// Writes the UTF-16 text value (as a JSON string) as an element of a JSON array. + /// Writes the string text value (as a JSON string) as an element of a JSON array. /// /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. @@ -47,7 +47,7 @@ public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = f WriteStringByOptions(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -71,18 +71,12 @@ private void WriteStringByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringMinimized(value); } } @@ -92,7 +86,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedValue) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -109,7 +103,7 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -129,8 +123,7 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteStringValue(escapedValue, ref idx); @@ -199,7 +192,7 @@ public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = f WriteStringByOptions(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } @@ -223,18 +216,12 @@ private void WriteStringByOptions(ReadOnlySpan value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteStringMinimized(value); } } @@ -244,7 +231,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedValue) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -261,7 +248,7 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -281,8 +268,7 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteStringValue(escapedValue, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 72362e47b325..8246a482f489 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -31,43 +31,34 @@ public void WriteNumberValue(ulong value) { if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueIndented(value); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingValue(); - } + ValidateWritingValue(); WriteNumberValueMinimized(value); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.Number; } private void WriteNumberValueMinimized(ulong value) { - // Calculated based on the following: ',ulong.MaxValue' - int bytesNeeded = JsonConstants.MaximumFormatUInt64Length + 1; - if (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(bytesNeeded); - } - int idx = 0; if (_currentDepth < 0) { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } _buffer[idx++] = JsonConstants.ListSeparator; } - Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten); + WriteNumberValueFormatLoop(value, ref idx); - Advance(idx + bytesWritten); + Advance(idx); } private void WriteNumberValueIndented(ulong value) @@ -75,7 +66,7 @@ private void WriteNumberValueIndented(ulong value) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -95,8 +86,7 @@ private void WriteNumberValueIndented(ulong value) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index a3d7ead7f869..1743ef62fd01 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -12,13 +12,15 @@ namespace System.Text.Json /// Provides a high-performance API for forward-only, non-cached writing of UTF-8 encoded JSON text. /// It writes the text sequentially with no caching and adheres to the JSON RFC /// by default (https://tools.ietf.org/html/rfc8259), with the exception of writing comments. + /// + /// /// When the user attempts to write invalid JSON and validation is enabled, it throws /// a with a context specific error message. /// Since this type is a ref struct, it does not directly support async. However, it does provide /// support for reentrancy to write partial data, and continue writing in chunks. /// To be able to format the output with indentation and whitespace OR to skip validation, create an instance of /// and pass that in to the writer. - /// + /// public ref partial struct Utf8JsonWriter { private const int StackallocThreshold = 256; @@ -71,15 +73,17 @@ public long BytesWritten /// /// Returns the current snapshot of the state which must /// be captured by the caller and passed back in to the ctor with more data. - /// Unlike the , which is a ref struct, the state can survive - /// across async/await boundaries and hence this type is required to provide support for reading - /// in more data asynchronously before continuing with a new instance of the . /// /// /// Thrown when there is JSON data that has been written and buffered but not yet flushed to the . /// Getting the state for creating a new without first committing the data that has been written /// would result in an inconsistent state. Call Flush before getting the current state. /// + /// + /// Unlike the , which is a ref struct, the state can survive + /// across async/await boundaries and hence this type is required to provide support for reading + /// in more data asynchronously before continuing with a new instance of the . + /// public JsonWriterState GetCurrentState() { if (_buffered != 0) @@ -193,7 +197,7 @@ private void WriteStart(byte token) if (CurrentDepth >= JsonConstants.MaxWriterDepth) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.DepthTooLarge, _currentDepth); - if (_writerOptions.SlowPath) + if (_writerOptions.IndentedOrNotSkipValidation) { WriteStartSlow(token); } @@ -209,24 +213,23 @@ private void WriteStart(byte token) private void WriteStartMinimized(byte token) { - // Calculated based on the following: ',[' OR ',{' - int bytesNeeded = 2; - while (_buffer.Length < bytesNeeded) - { - GrowAndEnsure(); - } - + int idx = 0; if (_currentDepth < 0) { - _buffer[0] = JsonConstants.ListSeparator; - _buffer[1] = token; + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeparator; } - else + + if (_buffer.Length <= idx) { - bytesNeeded--; - _buffer[0] = token; + AdvanceAndGrow(ref idx); } - Advance(bytesNeeded); + _buffer[idx++] = token; + + Advance(idx); } private void WriteStartSlow(byte token) @@ -273,7 +276,7 @@ private void WriteStartIndented(byte token) int idx = 0; if (_currentDepth < 0) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { GrowAndEnsure(); } @@ -293,14 +296,12 @@ private void WriteStartIndented(byte token) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = token; @@ -390,27 +391,18 @@ private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) int idx; if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - UpdateBitStackOnStart(token); - } + ValidateWritingProperty(token); idx = WritePropertyNameIndented(propertyName); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - UpdateBitStackOnStart(token); - } + ValidateWritingProperty(token); idx = WritePropertyNameMinimized(propertyName); } if (1 > _buffer.Length - idx) { - AdvanceAndGrow(idx, 1); - idx = 0; + AdvanceAndGrow(ref idx, 1); } _buffer[idx++] = token; @@ -564,27 +556,18 @@ private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) int idx; if (_writerOptions.Indented) { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - UpdateBitStackOnStart(token); - } + ValidateWritingProperty(token); idx = WritePropertyNameIndented(propertyName); } else { - if (!_writerOptions.SkipValidation) - { - ValidateWritingProperty(); - UpdateBitStackOnStart(token); - } + ValidateWritingProperty(token); idx = WritePropertyNameMinimized(propertyName); } if (1 > _buffer.Length - idx) { - AdvanceAndGrow(idx, 1); - idx = 0; + AdvanceAndGrow(ref idx, 1); } _buffer[idx++] = token; @@ -650,7 +633,7 @@ public void WriteEndObject() private void WriteEnd(byte token) { - if (_writerOptions.SlowPath) + if (_writerOptions.IndentedOrNotSkipValidation) { WriteEndSlow(token); } @@ -659,7 +642,7 @@ private void WriteEnd(byte token) WriteEndMinimized(token); } - _currentDepth |= 1 << 31; + SetFlagToAddListSeparatorBeforeNextItem(); // Necessary if WriteEndX is called without a corresponding WriteStartX first. if (CurrentDepth != 0) { @@ -669,7 +652,7 @@ private void WriteEnd(byte token) private void WriteEndMinimized(byte token) { - while (_buffer.Length < 1) + if (_buffer.Length < 1) { GrowAndEnsure(); } @@ -753,14 +736,12 @@ private void WriteEndIndented(byte token) break; } indent -= bytesWritten; - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = token; @@ -774,18 +755,16 @@ private void WriteNewLine(ref int idx) // Write '\r\n' OR '\n', depending on OS if (Environment.NewLine.Length == 2) { - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.CarriageReturn; } - while (_buffer.Length <= idx) + if (_buffer.Length <= idx) { - AdvanceAndGrow(idx); - idx = 0; + AdvanceAndGrow(ref idx); } _buffer[idx++] = JsonConstants.LineFeed; } @@ -829,18 +808,20 @@ private void GrowAndEnsure(int minimumSize) } } - private void AdvanceAndGrow(int alreadyWritten) + private void AdvanceAndGrow(ref int alreadyWritten) { Debug.Assert(alreadyWritten >= 0); Advance(alreadyWritten); GrowAndEnsure(); + alreadyWritten = 0; } - private void AdvanceAndGrow(int alreadyWritten, int minimumSize) + private void AdvanceAndGrow(ref int alreadyWritten, int minimumSize) { Debug.Assert(minimumSize >= 1 && minimumSize <= 128); Advance(alreadyWritten); GrowAndEnsure(minimumSize); + alreadyWritten = 0; } private void CopyLoop(ReadOnlySpan span, ref int idx) @@ -856,9 +837,14 @@ private void CopyLoop(ReadOnlySpan span, ref int idx) span.Slice(0, _buffer.Length - idx).CopyTo(_buffer.Slice(idx)); span = span.Slice(_buffer.Length - idx); - AdvanceAndGrow(_buffer.Length); - idx = 0; + idx = _buffer.Length; + AdvanceAndGrow(ref idx); } } + + private void SetFlagToAddListSeparatorBeforeNextItem() + { + _currentDepth |= 1 << 31; + } } } From 644118ce2cf412bc43a3f743b8adfc4386c9b035 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 22:12:00 -0800 Subject: [PATCH 22/33] Reduce code bloat by removing duplciate calls to ValidateX. --- .../Utf8JsonWriter.WriteProperties.DateTime.cs | 6 ++---- .../Utf8JsonWriter.WriteProperties.DateTimeOffset.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteProperties.Decimal.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteProperties.Double.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteProperties.Float.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteProperties.Guid.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteProperties.Literal.cs | 6 ++---- .../Utf8JsonWriter.WriteProperties.SignedNumber.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteProperties.String.cs | 12 ++++-------- .../Utf8JsonWriter.WriteProperties.UnsignedNumber.cs | 6 ++---- .../Writer/Utf8JsonWriter.WriteValues.DateTime.cs | 3 +-- .../Utf8JsonWriter.WriteValues.DateTimeOffset.cs | 3 +-- .../Writer/Utf8JsonWriter.WriteValues.Decimal.cs | 3 +-- .../Json/Writer/Utf8JsonWriter.WriteValues.Double.cs | 3 +-- .../Json/Writer/Utf8JsonWriter.WriteValues.Float.cs | 3 +-- .../Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs | 3 +-- .../Writer/Utf8JsonWriter.WriteValues.Literal.cs | 3 +-- .../Utf8JsonWriter.WriteValues.SignedNumber.cs | 3 +-- .../Json/Writer/Utf8JsonWriter.WriteValues.String.cs | 6 ++---- .../Utf8JsonWriter.WriteValues.UnsignedNumber.cs | 3 +-- .../src/System/Text/Json/Writer/Utf8JsonWriter.cs | 6 ++---- 21 files changed, 35 insertions(+), 70 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 46fcb60f1cdd..21c5d9df90f1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -181,28 +181,26 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 3692b2916408..110806d18ea6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -181,28 +181,26 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffset value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffset value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 49b732edc7b2..54f16a0a15ae 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -181,28 +181,26 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 5015982d3f72..3d2024cb438b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -183,28 +183,26 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 839a760ba4eb..2c98f0b1e94d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -183,28 +183,26 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } private void WriteNumberByOptions(ReadOnlySpan propertyName, float value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 9104805ab373..754e43bdbd5e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -181,28 +181,26 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 73317fc44078..d255c1fddcc5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -258,15 +258,14 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { + ValidateWritingProperty(); int idx; if (_writerOptions.Indented) { - ValidateWritingProperty(); idx = WritePropertyNameIndented(propertyName); } else { - ValidateWritingProperty(); idx = WritePropertyNameMinimized(propertyName); } @@ -283,15 +282,14 @@ private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { + ValidateWritingProperty(); int idx; if (_writerOptions.Indented) { - ValidateWritingProperty(); idx = WritePropertyNameIndented(propertyName); } else { - ValidateWritingProperty(); idx = WritePropertyNameMinimized(propertyName); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 6f208a80abee..993d720156ca 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -226,28 +226,26 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 73823313461a..77aa1322e3a6 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -661,56 +661,52 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteStringIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteStringMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 752aa7bf53e5..fb66c944c51f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -232,28 +232,26 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) { + ValidateWritingProperty(); if (_writerOptions.Indented) { - ValidateWritingProperty(); WriteNumberIndented(propertyName, value); } else { - ValidateWritingProperty(); WriteNumberMinimized(propertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index a742d6a065fc..b34b7306b26e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -17,14 +17,13 @@ public ref partial struct Utf8JsonWriter /// public void WriteStringValue(DateTime value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteStringValueIndented(value); } else { - ValidateWritingValue(); WriteStringValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 3ef4f2580794..5a699af0d6c5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -17,14 +17,13 @@ public ref partial struct Utf8JsonWriter /// public void WriteStringValue(DateTimeOffset value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteStringValueIndented(value); } else { - ValidateWritingValue(); WriteStringValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index e3bf333e4de2..bb20bbce05c1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -15,14 +15,13 @@ public ref partial struct Utf8JsonWriter /// public void WriteNumberValue(decimal value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteNumberValueIndented(value); } else { - ValidateWritingValue(); WriteNumberValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 47465ea9f336..7a7da6b35592 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -17,14 +17,13 @@ public void WriteNumberValue(double value) { JsonWriterHelper.ValidateDouble(value); + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteNumberValueIndented(value); } else { - ValidateWritingValue(); WriteNumberValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 667b3219df46..3d137eadabb2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -17,14 +17,13 @@ public void WriteNumberValue(float value) { JsonWriterHelper.ValidateSingle(value); + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteNumberValueIndented(value); } else { - ValidateWritingValue(); WriteNumberValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index f64b5b25e5e2..c7e82cd48e67 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -17,14 +17,13 @@ public ref partial struct Utf8JsonWriter /// public void WriteStringValue(Guid value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteStringValueIndented(value); } else { - ValidateWritingValue(); WriteStringValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 3e084500e6b8..5cf5d6623b55 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -45,14 +45,13 @@ public void WriteBooleanValue(bool value) private void WriteLiteralByOptions(ReadOnlySpan value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteLiteralIndented(value); } else { - ValidateWritingValue(); WriteLiteralMinimized(value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index daabbd59b17e..527e1cc5f9fa 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -27,14 +27,13 @@ public void WriteNumberValue(int value) /// public void WriteNumberValue(long value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteNumberValueIndented(value); } else { - ValidateWritingValue(); WriteNumberValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 536f795e84aa..fd785bd13aee 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -69,14 +69,13 @@ private void WriteStringSuppressFalse(ReadOnlySpan value) private void WriteStringByOptions(ReadOnlySpan value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteStringIndented(value); } else { - ValidateWritingValue(); WriteStringMinimized(value); } } @@ -214,14 +213,13 @@ private void WriteStringSuppressFalse(ReadOnlySpan value) private void WriteStringByOptions(ReadOnlySpan value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteStringIndented(value); } else { - ValidateWritingValue(); WriteStringMinimized(value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 8246a482f489..89173bf44cc0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -29,14 +29,13 @@ public void WriteNumberValue(uint value) [CLSCompliant(false)] public void WriteNumberValue(ulong value) { + ValidateWritingValue(); if (_writerOptions.Indented) { - ValidateWritingValue(); WriteNumberValueIndented(value); } else { - ValidateWritingValue(); WriteNumberValueMinimized(value); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 1743ef62fd01..b640d03dd77d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -388,15 +388,14 @@ private void WriteStartSuppressFalse(ReadOnlySpan propertyName, byte token private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) { + ValidateWritingProperty(token); int idx; if (_writerOptions.Indented) { - ValidateWritingProperty(token); idx = WritePropertyNameIndented(propertyName); } else { - ValidateWritingProperty(token); idx = WritePropertyNameMinimized(propertyName); } @@ -553,15 +552,14 @@ private void WriteStartSuppressFalse(ReadOnlySpan propertyName, byte token private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) { + ValidateWritingProperty(token); int idx; if (_writerOptions.Indented) { - ValidateWritingProperty(token); idx = WritePropertyNameIndented(propertyName); } else { - ValidateWritingProperty(token); idx = WritePropertyNameMinimized(propertyName); } From baa4931a5abf0b4544395e2d97c393b5be06a37c Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 22:32:52 -0800 Subject: [PATCH 23/33] Add details on how .NET types are formatted to comments. --- .../Utf8JsonWriter.WriteProperties.DateTime.cs | 9 +++++++++ ...sonWriter.WriteProperties.DateTimeOffset.cs | 9 +++++++++ .../Utf8JsonWriter.WriteProperties.Decimal.cs | 9 +++++++++ .../Utf8JsonWriter.WriteProperties.Double.cs | 9 +++++++++ .../Utf8JsonWriter.WriteProperties.Float.cs | 9 +++++++++ .../Utf8JsonWriter.WriteProperties.Guid.cs | 9 +++++++++ ...8JsonWriter.WriteProperties.SignedNumber.cs | 18 ++++++++++++++++++ ...sonWriter.WriteProperties.UnsignedNumber.cs | 18 ++++++++++++++++++ .../Utf8JsonWriter.WriteValues.DateTime.cs | 5 ++++- ...tf8JsonWriter.WriteValues.DateTimeOffset.cs | 5 ++++- .../Utf8JsonWriter.WriteValues.Decimal.cs | 5 +++++ .../Utf8JsonWriter.WriteValues.Double.cs | 5 +++++ .../Writer/Utf8JsonWriter.WriteValues.Float.cs | 5 +++++ .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 5 ++++- .../Utf8JsonWriter.WriteValues.SignedNumber.cs | 8 +++++++- ...tf8JsonWriter.WriteValues.UnsignedNumber.cs | 8 +++++++- 16 files changed, 131 insertions(+), 5 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 21c5d9df90f1..ffed84cc5a7a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteString(string propertyName, DateTime value, bool suppressEscapi /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -66,6 +72,9 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 110806d18ea6..bfcece86cffd 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteString(string propertyName, DateTimeOffset value, bool suppress /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -66,6 +72,9 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 54f16a0a15ae..3c9955b0a588 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteNumber(string propertyName, decimal value, bool suppressEscapin /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -66,6 +72,9 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 3d2024cb438b..04290fa96b08 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteNumber(string propertyName, double value, bool suppressEscaping /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -67,6 +73,9 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 2c98f0b1e94d..7991de2a1d3d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteNumber(string propertyName, float value, bool suppressEscaping /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -67,6 +73,9 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 754e43bdbd5e..e5f54894ac3e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. + /// public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteString(string propertyName, Guid value, bool suppressEscaping = /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. + /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -66,6 +72,9 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. + /// public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 993d720156ca..9a6ee12074f7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); @@ -37,6 +40,9 @@ public void WriteNumber(string propertyName, long value, bool suppressEscaping = /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -66,6 +72,9 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { JsonWriterHelper.ValidateProperty(propertyName); @@ -95,6 +104,9 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), (long)value, suppressEscaping); @@ -110,6 +122,9 @@ public void WriteNumber(string propertyName, int value, bool suppressEscaping = /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName, (long)value, suppressEscaping); @@ -125,6 +140,9 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppres /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) => WriteNumber(propertyName, (long)value, suppressEscaping); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index fb66c944c51f..d54260a978d8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -22,6 +22,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); @@ -38,6 +41,9 @@ public void WriteNumber(string propertyName, ulong value, bool suppressEscaping /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { @@ -68,6 +74,9 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { @@ -98,6 +107,9 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName.AsSpan(), (ulong)value, suppressEscaping); @@ -114,6 +126,9 @@ public void WriteNumber(string propertyName, uint value, bool suppressEscaping = /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName, (ulong)value, suppressEscaping); @@ -130,6 +145,9 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppre /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) => WriteNumber(propertyName, (ulong)value, suppressEscaping); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index b34b7306b26e..8e85e4a7e343 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Buffers.Text; +using System.Buffers; namespace System.Text.Json { @@ -15,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// public void WriteStringValue(DateTime value) { ValidateWritingValue(); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 5a699af0d6c5..b4f441e6fc47 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Buffers.Text; +using System.Buffers; namespace System.Text.Json { @@ -15,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// public void WriteStringValue(DateTimeOffset value) { ValidateWritingValue(); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index bb20bbce05c1..5890ec1c9f7a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.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.Buffers; + namespace System.Text.Json { public ref partial struct Utf8JsonWriter @@ -13,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumberValue(decimal value) { ValidateWritingValue(); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 7a7da6b35592..d6439b137a63 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.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.Buffers; + namespace System.Text.Json { public ref partial struct Utf8JsonWriter @@ -13,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumberValue(double value) { JsonWriterHelper.ValidateDouble(value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 3d137eadabb2..5bc66ba5eb41 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.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.Buffers; + namespace System.Text.Json { public ref partial struct Utf8JsonWriter @@ -13,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G') + /// public void WriteNumberValue(float value) { JsonWriterHelper.ValidateSingle(value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index c7e82cd48e67..dadf88204f50 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Buffers.Text; +using System.Buffers; namespace System.Text.Json { @@ -15,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. + /// public void WriteStringValue(Guid value) { ValidateWritingValue(); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 527e1cc5f9fa..8800223cadd8 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Buffers.Text; +using System.Buffers; namespace System.Text.Json { @@ -15,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumberValue(int value) => WriteNumberValue((long)value); @@ -25,6 +28,9 @@ public void WriteNumberValue(int value) /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// public void WriteNumberValue(long value) { ValidateWritingValue(); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 89173bf44cc0..e340cfd6f8e0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Buffers.Text; +using System.Buffers; namespace System.Text.Json { @@ -15,6 +15,9 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumberValue(uint value) => WriteNumberValue((ulong)value); @@ -26,6 +29,9 @@ public void WriteNumberValue(uint value) /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// + /// + /// Writes the using the default (i.e. 'G'), for example: 32767 + /// [CLSCompliant(false)] public void WriteNumberValue(ulong value) { From 2b91e6cd72ddb4b80a5b98fe499f5f18d8b0a102 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 11 Jan 2019 22:50:46 -0800 Subject: [PATCH 24/33] Reduce code duplication when writing values. --- .../Utf8JsonWriter.WriteValues.Comment.cs | 17 +---- .../Utf8JsonWriter.WriteValues.DateTime.cs | 35 +--------- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 35 +--------- .../Utf8JsonWriter.WriteValues.Decimal.cs | 35 +--------- .../Utf8JsonWriter.WriteValues.Double.cs | 35 +--------- .../Utf8JsonWriter.WriteValues.Float.cs | 35 +--------- .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 35 +--------- .../Utf8JsonWriter.WriteValues.Helpers.cs | 39 +++++++++++ .../Utf8JsonWriter.WriteValues.Literal.cs | 35 +--------- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 35 +--------- .../Utf8JsonWriter.WriteValues.String.cs | 70 ++----------------- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 35 +--------- 12 files changed, 62 insertions(+), 379 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index ca3952ea141a..0af2e965bfc0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -204,22 +204,7 @@ private void WriteCommentMinimized(ReadOnlySpan escapedValue) private void WriteCommentIndented(ReadOnlySpan escapedValue) { int idx = 0; - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + WriteFormattingPreamble(ref idx); WriteCommentValue(escapedValue, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index 8e85e4a7e343..e85cb1c6bf1d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -37,14 +37,7 @@ public void WriteStringValue(DateTime value) private void WriteStringValueMinimized(DateTime value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteStringValue(value, ref idx); @@ -53,31 +46,7 @@ private void WriteStringValueMinimized(DateTime value) private void WriteStringValueIndented(DateTime value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index b4f441e6fc47..55e2df916b24 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -37,14 +37,7 @@ public void WriteStringValue(DateTimeOffset value) private void WriteStringValueMinimized(DateTimeOffset value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteStringValue(value, ref idx); @@ -53,31 +46,7 @@ private void WriteStringValueMinimized(DateTimeOffset value) private void WriteStringValueIndented(DateTimeOffset value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index 5890ec1c9f7a..382e5be504b7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -37,14 +37,7 @@ public void WriteNumberValue(decimal value) private void WriteNumberValueMinimized(decimal value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteNumberValueFormatLoop(value, ref idx); @@ -53,31 +46,7 @@ private void WriteNumberValueMinimized(decimal value) private void WriteNumberValueIndented(decimal value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index d6439b137a63..8c19b067dda1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -39,14 +39,7 @@ public void WriteNumberValue(double value) private void WriteNumberValueMinimized(double value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteNumberValueFormatLoop(value, ref idx); @@ -55,31 +48,7 @@ private void WriteNumberValueMinimized(double value) private void WriteNumberValueIndented(double value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 5bc66ba5eb41..e2dea1d2384d 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -39,14 +39,7 @@ public void WriteNumberValue(float value) private void WriteNumberValueMinimized(float value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteNumberValueFormatLoop(value, ref idx); @@ -55,31 +48,7 @@ private void WriteNumberValueMinimized(float value) private void WriteNumberValueIndented(float value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index dadf88204f50..a6d17ce081fa 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -37,14 +37,7 @@ public void WriteStringValue(Guid value) private void WriteStringValueMinimized(Guid value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteStringValue(value, ref idx); @@ -53,31 +46,7 @@ private void WriteStringValueMinimized(Guid value) private void WriteStringValueIndented(Guid value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteStringValue(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs index 1e7ee95d6a4d..e59d0a0d1289 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Helpers.cs @@ -26,5 +26,44 @@ private void ValidateWritingValue() } } } + + private int WriteCommaAndFormattingPreamble() + { + int idx = 0; + WriteListSeparator(ref idx); + WriteFormattingPreamble(ref idx); + return idx; + } + + private void WriteFormattingPreamble(ref int idx) + { + if (_tokenType != JsonTokenType.None) + WriteNewLine(ref idx); + + int indent = Indentation; + while (true) + { + bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); + idx += bytesWritten; + if (result) + { + break; + } + indent -= bytesWritten; + AdvanceAndGrow(ref idx); + } + } + + private void WriteListSeparator(ref int idx) + { + if (_currentDepth < 0) + { + if (_buffer.Length <= idx) + { + GrowAndEnsure(); + } + _buffer[idx++] = JsonConstants.ListSeparator; + } + } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 5cf5d6623b55..303ca4940e31 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -59,14 +59,7 @@ private void WriteLiteralByOptions(ReadOnlySpan value) private void WriteLiteralMinimized(ReadOnlySpan value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); CopyLoop(value, ref idx); @@ -75,31 +68,7 @@ private void WriteLiteralMinimized(ReadOnlySpan value) private void WriteLiteralIndented(ReadOnlySpan value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); CopyLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 8800223cadd8..7b0694c5da0e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -50,14 +50,7 @@ public void WriteNumberValue(long value) private void WriteNumberValueMinimized(long value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteNumberValueFormatLoop(value, ref idx); @@ -66,31 +59,7 @@ private void WriteNumberValueMinimized(long value) private void WriteNumberValueIndented(long value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteNumberValueFormatLoop(value, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index fd785bd13aee..51c33fde0d94 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -83,14 +83,7 @@ private void WriteStringByOptions(ReadOnlySpan value) private void WriteStringMinimized(ReadOnlySpan escapedValue) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteStringValue(escapedValue, ref idx); @@ -99,31 +92,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedValue) private void WriteStringIndented(ReadOnlySpan escapedValue) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteStringValue(escapedValue, ref idx); @@ -227,14 +196,7 @@ private void WriteStringByOptions(ReadOnlySpan value) private void WriteStringMinimized(ReadOnlySpan escapedValue) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteStringValue(escapedValue, ref idx); @@ -243,31 +205,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedValue) private void WriteStringIndented(ReadOnlySpan escapedValue) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteStringValue(escapedValue, ref idx); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index e340cfd6f8e0..335245bbde4f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -52,14 +52,7 @@ public void WriteNumberValue(ulong value) private void WriteNumberValueMinimized(ulong value) { int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } + WriteListSeparator(ref idx); WriteNumberValueFormatLoop(value, ref idx); @@ -68,31 +61,7 @@ private void WriteNumberValueMinimized(ulong value) private void WriteNumberValueIndented(ulong value) { - int idx = 0; - if (_currentDepth < 0) - { - if (_buffer.Length <= idx) - { - GrowAndEnsure(); - } - _buffer[idx++] = JsonConstants.ListSeparator; - } - - if (_tokenType != JsonTokenType.None) - WriteNewLine(ref idx); - - int indent = Indentation; - while (true) - { - bool result = JsonWriterHelper.TryWriteIndentation(_buffer.Slice(idx), indent, out int bytesWritten); - idx += bytesWritten; - if (result) - { - break; - } - indent -= bytesWritten; - AdvanceAndGrow(ref idx); - } + int idx = WriteCommaAndFormattingPreamble(); WriteNumberValueFormatLoop(value, ref idx); From 6c439544eadf0b0a6a8da769df44f06dcda0f6f0 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Sat, 12 Jan 2019 01:12:55 -0800 Subject: [PATCH 25/33] Change the StandardFormat used for DateTime(Offset) to 'O' --- .../src/System/Text/Json/JsonConstants.cs | 4 ++-- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 12 ++++++----- ...onWriter.WriteProperties.DateTimeOffset.cs | 10 +++++----- .../Utf8JsonWriter.WriteValues.DateTime.cs | 2 +- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 2 +- .../tests/Utf8JsonWriterTests.cs | 20 +++++++++---------- 6 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 201172c67af1..787d73a21d46 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -52,8 +52,8 @@ internal static class JsonConstants public const int MaximumFormatSingleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. public const int MaximumFormatDecimalLength = 29; // default (i.e. 'G') public const int MaximumFormatGuidLength = 36; // default (i.e. 'D'), 8 + 4 + 4 + 4 + 12 + 4 for the hyphens (e.g. 094ffa0a-0442-494d-b452-04003fa755cc) - public const int MaximumFormatDateTimeLength = 19; // default (i.e. 'G'), e.g. 05/25/2017 10:30:15 - public const int MaximumFormatDateTimeOffsetLength = 26; // default (i.e. 'G'), e.g. 05/25/2017 10:30:15 -08:00 + public const int MaximumFormatDateTimeLength = 27; // StandardFormat 'O', e.g. 2017-06-12T05:30:45.7680000 + public const int MaximumFormatDateTimeOffsetLength = 33; // StandardFormat 'O', e.g. 2017-06-12T05:30:45.7680000-07:00 // Encoding Helpers public const char HighSurrogateStart = '\ud800'; diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index ffed84cc5a7a..ab4dadfe410b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); @@ -41,7 +41,7 @@ public void WriteString(string propertyName, DateTime value, bool suppressEscapi /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { @@ -73,7 +73,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) { @@ -267,12 +267,14 @@ private void WriteStringValue(DateTime value, ref int idx) _buffer[idx++] = JsonConstants.Quote; } + private static readonly StandardFormat s_dateTimeStandardFormat = new StandardFormat('O'); + private void FormatLoop(DateTime value, ref int idx) { - if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten, s_dateTimeStandardFormat)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDateTimeLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten, s_dateTimeStandardFormat); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index bfcece86cffd..0cdda4986fcf 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) => WriteString(propertyName.AsSpan(), value, suppressEscaping); @@ -41,7 +41,7 @@ public void WriteString(string propertyName, DateTimeOffset value, bool suppress /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { @@ -73,7 +73,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) { @@ -269,10 +269,10 @@ private void WriteStringValue(DateTimeOffset value, ref int idx) private void FormatLoop(DateTimeOffset value, ref int idx) { - if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) + if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten, s_dateTimeStandardFormat)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDateTimeOffsetLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Utf8Formatter.TryFormat(value, _buffer, out bytesWritten, s_dateTimeStandardFormat); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index e85cb1c6bf1d..4b1fa7363931 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 05/25/2017 10:30:15. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// public void WriteStringValue(DateTime value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 55e2df916b24..8cd8a4fca8bb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default , for example: 05/25/2017 10:30:15 -08:00. + /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteStringValue(DateTimeOffset value) { diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 00dc34eb6620..cb44b2348814 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -144,7 +144,7 @@ public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new FixedSizedBufferWriter(20); + var output = new FixedSizedBufferWriter(28); var jsonUtf8 = new Utf8JsonWriter(output, state); @@ -157,14 +157,14 @@ public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) } catch (ArgumentException) { } - output = new FixedSizedBufferWriter(30); + output = new FixedSizedBufferWriter(29); jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStringValue(date); jsonUtf8.Flush(); string actualStr = Encoding.UTF8.GetString(output.Formatted); - Assert.Equal(21, output.Formatted.Length); - Assert.Equal($"\"{date.ToString("G", DateTimeFormatInfo.InvariantInfo)}\"", actualStr); + Assert.Equal(29, output.Formatted.Length); + Assert.Equal($"\"{date.ToString("O")}\"", actualStr); } [Theory] @@ -176,7 +176,7 @@ public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValida { var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); - var output = new FixedSizedBufferWriter(27); + var output = new FixedSizedBufferWriter(34); var jsonUtf8 = new Utf8JsonWriter(output, state); @@ -189,14 +189,14 @@ public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValida } catch (ArgumentException) { } - output = new FixedSizedBufferWriter(30); + output = new FixedSizedBufferWriter(35); jsonUtf8 = new Utf8JsonWriter(output, state); jsonUtf8.WriteStringValue(date); jsonUtf8.Flush(); string actualStr = Encoding.UTF8.GetString(output.Formatted); - Assert.Equal(28, output.Formatted.Length); - Assert.Equal($"\"{date.ToString("MM/dd/yyyy HH:mm:ss zzz")}\"", actualStr); + Assert.Equal(35, output.Formatted.Length); + Assert.Equal($"\"{date.ToString("O")}\"", actualStr); } [Theory] @@ -3339,7 +3339,7 @@ private static string GetDatesExpectedString(bool prettyPrint, string keyString, { Formatting = prettyPrint ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, - DateFormatString = "G" + DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffffff" }; json.WriteStartObject(); @@ -3372,7 +3372,7 @@ private static string GetDatesExpectedString(bool prettyPrint, string keyString, { Formatting = prettyPrint ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, - DateFormatString = "MM/dd/yyyy HH:mm:ss zzz" + DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffffffzzz" }; json.WriteStartObject(); From eb33db61e0d7cb35e927631e602f0d81bbf54693 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Sat, 12 Jan 2019 01:45:42 -0800 Subject: [PATCH 26/33] Refactor calculating the maximum escaped length to a helper. --- .../Json/Writer/JsonWriterHelper.Escaping.cs | 8 ++++++ ...Utf8JsonWriter.WriteProperties.DateTime.cs | 4 +-- ...onWriter.WriteProperties.DateTimeOffset.cs | 4 +-- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 4 +-- .../Utf8JsonWriter.WriteProperties.Double.cs | 4 +-- .../Utf8JsonWriter.WriteProperties.Float.cs | 4 +-- .../Utf8JsonWriter.WriteProperties.Guid.cs | 4 +-- .../Utf8JsonWriter.WriteProperties.Literal.cs | 4 +-- ...JsonWriter.WriteProperties.SignedNumber.cs | 4 +-- .../Utf8JsonWriter.WriteProperties.String.cs | 25 ++++++++++--------- ...onWriter.WriteProperties.UnsignedNumber.cs | 4 +-- .../Utf8JsonWriter.WriteValues.Comment.cs | 4 +-- .../Utf8JsonWriter.WriteValues.String.cs | 4 +-- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 4 +-- 14 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 2cd357a53c18..a26bb3f21853 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -9,6 +9,7 @@ namespace System.Text.Json { + // TODO: Replace the escaping logic with publicly shipping APIs from https://github.com/dotnet/corefx/issues/33509 internal static partial class JsonWriterHelper { // Only allow ASCII characters between ' ' (0x20) and '~' (0x7E), inclusively, @@ -78,6 +79,13 @@ public static int NeedsEscaping(ReadOnlySpan value) return idx; } + public static int GetMaxEscapedLength(int textLength, int firstIndexToEscape) + { + Debug.Assert(textLength > 0); + Debug.Assert(firstIndexToEscape >= 0 && firstIndexToEscape < textLength); + return firstIndexToEscape + JsonConstants.MaxExpansionFactorWhileEscaping * (textLength - firstIndexToEscape); + } + public static void EscapeString(ReadOnlySpan value, Span destination, int indexOfFirstByteToEscape, out int written) { Debug.Assert(indexOfFirstByteToEscape >= 0 && indexOfFirstByteToEscape < value.Length); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index ab4dadfe410b..feb0640d0cd9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -130,7 +130,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -162,7 +162,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 0cdda4986fcf..1b368df5b600 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -130,7 +130,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -162,7 +162,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 3c9955b0a588..42a02f4dff37 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -130,7 +130,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -162,7 +162,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 04290fa96b08..6c79d78cea14 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -132,7 +132,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -164,7 +164,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 7991de2a1d3d..7ff2d33e192b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -132,7 +132,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -164,7 +164,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index e5f54894ac3e..b8cf676bf0d3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -130,7 +130,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -162,7 +162,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index d255c1fddcc5..1ad89dfdf982 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -198,7 +198,7 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -230,7 +230,7 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 9a6ee12074f7..9d2c2193b022 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -184,7 +184,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -216,7 +216,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 77aa1322e3a6..40e9348fda8e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -271,7 +271,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + char[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); @@ -284,7 +284,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); @@ -297,7 +297,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); @@ -310,7 +310,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - char[] valueArray = ArrayPool.Shared.Rent(firstEscapeIndex + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndex)); + char[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); Span span = valueArray; JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); @@ -405,7 +405,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -428,7 +428,8 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + Span span; if (length > StackallocThreshold) { @@ -471,7 +472,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -494,7 +495,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -537,7 +538,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -560,7 +561,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -603,7 +604,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -626,7 +627,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexProp != -1) { - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index d54260a978d8..d461d3f94b7e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -190,7 +190,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -222,7 +222,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 0af2e965bfc0..106639e87e52 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -113,7 +113,7 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -219,7 +219,7 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 51c33fde0d94..ab82873b7453 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -107,7 +107,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) @@ -220,7 +220,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd if (firstEscapeIndexVal != -1) { - int length = firstEscapeIndexVal + JsonConstants.MaxExpansionFactorWhileEscaping * (value.Length - firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); Span span; if (length > StackallocThreshold) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index b640d03dd77d..2d407e83687e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -415,7 +415,7 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke byte[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { @@ -579,7 +579,7 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke char[] propertyArray = null; - int length = firstEscapeIndexProp + JsonConstants.MaxExpansionFactorWhileEscaping * (propertyName.Length - firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); Span span; if (length > StackallocThreshold) { From 171f6c304f87082e1720a9a8da777a85bc4b63f5 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Sat, 12 Jan 2019 03:44:34 -0800 Subject: [PATCH 27/33] Remove unnecessary checks and rename locals to be more descriptive. --- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 22 ++-- ...onWriter.WriteProperties.DateTimeOffset.cs | 22 ++-- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 22 ++-- .../Utf8JsonWriter.WriteProperties.Double.cs | 22 ++-- .../Utf8JsonWriter.WriteProperties.Float.cs | 22 ++-- .../Utf8JsonWriter.WriteProperties.Guid.cs | 22 ++-- .../Utf8JsonWriter.WriteProperties.Literal.cs | 22 ++-- ...JsonWriter.WriteProperties.SignedNumber.cs | 22 ++-- .../Utf8JsonWriter.WriteProperties.String.cs | 108 +++++++++--------- ...onWriter.WriteProperties.UnsignedNumber.cs | 22 ++-- .../Utf8JsonWriter.WriteValues.Comment.cs | 70 ++++++------ .../Utf8JsonWriter.WriteValues.String.cs | 70 ++++++------ .../System/Text/Json/Writer/Utf8JsonWriter.cs | 22 ++-- 13 files changed, 240 insertions(+), 228 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index feb0640d0cd9..f3c0c9aa8086 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -127,15 +127,16 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTime private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -143,12 +144,12 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStringByOptions(span.Slice(0, written), value); + WriteStringByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -159,15 +160,16 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -175,12 +177,12 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStringByOptions(span.Slice(0, written), value); + WriteStringByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 1b368df5b600..14afc23b6eac 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -127,15 +127,16 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTimeO private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -143,12 +144,12 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStringByOptions(span.Slice(0, written), value); + WriteStringByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -159,15 +160,16 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -175,12 +177,12 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStringByOptions(span.Slice(0, written), value); + WriteStringByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 42a02f4dff37..26c6816818c1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -127,15 +127,16 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, decimal v private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -143,12 +144,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -159,15 +160,16 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -175,12 +177,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 6c79d78cea14..612362c3d4b2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -129,15 +129,16 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, double va private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -145,12 +146,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -161,15 +162,16 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -177,12 +179,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 7ff2d33e192b..e05d4daa0841 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -129,15 +129,16 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, float val private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -145,12 +146,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -161,15 +162,16 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -177,12 +179,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index b8cf676bf0d3..2a01be695801 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -127,15 +127,16 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, Guid valu private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -143,12 +144,12 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStringByOptions(span.Slice(0, written), value); + WriteStringByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -159,15 +160,16 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -175,12 +177,12 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStringByOptions(span.Slice(0, written), value); + WriteStringByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 1ad89dfdf982..78f90e78e811 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -195,15 +195,16 @@ private void WriteLiteralSuppressFalse(ReadOnlySpan propertyName, ReadOnly private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -211,12 +212,12 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteLiteralByOptions(span.Slice(0, written), value); + WriteLiteralByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -227,15 +228,16 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -243,12 +245,12 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteLiteralByOptions(span.Slice(0, written), value); + WriteLiteralByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 9d2c2193b022..50ea38fa6943 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -181,15 +181,16 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, long valu private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -197,12 +198,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -213,15 +214,16 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -229,12 +231,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 40e9348fda8e..6e082397d85e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -270,12 +270,13 @@ private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, Rea private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); char[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); - Span span = valueArray; - JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); + Span escapedValue = valueArray; + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); - WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); + WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } @@ -283,12 +284,13 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); - Span span = valueArray; - JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); + Span escapedValue = valueArray; + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); - WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); + WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } @@ -296,12 +298,13 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); - Span span = valueArray; - JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); + Span escapedValue = valueArray; + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); - WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); + WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } @@ -309,12 +312,13 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); char[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); - Span span = valueArray; - JsonWriterHelper.EscapeString(value, span, firstEscapeIndex, out int written); + Span escapedValue = valueArray; + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); - WriteStringByOptions(escapedPropertyName, span.Slice(0, written)); + WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } @@ -407,11 +411,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R { int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; + Span escapedValue; if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; + escapedValue = valueArray; } else { @@ -419,22 +423,22 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + value = escapedValue.Slice(0, written); } if (firstEscapeIndexProp != -1) { int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -442,11 +446,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + propertyName = escapedPropertyName.Slice(0, written); } WriteStringByOptions(propertyName, value); @@ -474,11 +478,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R { int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; + Span escapedValue; if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; + escapedValue = valueArray; } else { @@ -486,21 +490,21 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + value = escapedValue.Slice(0, written); } if (firstEscapeIndexProp != -1) { int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -508,11 +512,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + propertyName = escapedPropertyName.Slice(0, written); } WriteStringByOptions(propertyName, value); @@ -540,11 +544,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R { int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; + Span escapedValue; if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; + escapedValue = valueArray; } else { @@ -552,21 +556,21 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + value = escapedValue.Slice(0, written); } if (firstEscapeIndexProp != -1) { int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -574,11 +578,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + propertyName = escapedPropertyName.Slice(0, written); } WriteStringByOptions(propertyName, value); @@ -606,11 +610,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R { int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; + Span escapedValue; if (length > StackallocThreshold) { valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; + escapedValue = valueArray; } else { @@ -618,21 +622,21 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + value = escapedValue.Slice(0, written); } if (firstEscapeIndexProp != -1) { int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -640,11 +644,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); - propertyName = span.Slice(0, written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + propertyName = escapedPropertyName.Slice(0, written); } WriteStringByOptions(propertyName, value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index d461d3f94b7e..522c37345aaf 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -187,15 +187,16 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, ulong val private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -203,12 +204,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { @@ -219,15 +220,16 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -235,12 +237,12 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteNumberByOptions(span.Slice(0, written), value); + WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); if (propertyArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 106639e87e52..152fc502ebf1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -108,33 +108,30 @@ private void WriteCommentIndented(ReadOnlySpan escapedValue) private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); char[] valueArray = null; - if (firstEscapeIndexVal != -1) - { - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; - if (length > StackallocThreshold) - { - valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; - } - else + Span escapedValue; + if (length > StackallocThreshold) + { + valueArray = ArrayPool.Shared.Rent(length); + escapedValue = valueArray; + } + else + { + // Cannot create a span directly since it gets passed to instance methods on a ref struct. + unsafe { - // Cannot create a span directly since it gets passed to instance methods on a ref struct. - unsafe - { - char* ptr = stackalloc char[length]; - span = new Span(ptr, length); - } + char* ptr = stackalloc char[length]; + escapedValue = new Span(ptr, length); } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); } + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); - WriteCommentByOptions(value); + WriteCommentByOptions(escapedValue.Slice(0, written)); if (valueArray != null) { @@ -214,33 +211,30 @@ private void WriteCommentIndented(ReadOnlySpan escapedValue) private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); byte[] valueArray = null; - if (firstEscapeIndexVal != -1) - { - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; - if (length > StackallocThreshold) - { - valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; - } - else + Span escapedValue; + if (length > StackallocThreshold) + { + valueArray = ArrayPool.Shared.Rent(length); + escapedValue = valueArray; + } + else + { + // Cannot create a span directly since it gets passed to instance methods on a ref struct. + unsafe { - // Cannot create a span directly since it gets passed to instance methods on a ref struct. - unsafe - { - byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); - } + byte* ptr = stackalloc byte[length]; + escapedValue = new Span(ptr, length); } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); } + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); - WriteCommentByOptions(value); + WriteCommentByOptions(escapedValue.Slice(0, written)); if (valueArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index ab82873b7453..0785334b52be 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -102,33 +102,30 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); char[] valueArray = null; - if (firstEscapeIndexVal != -1) - { - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; - if (length > StackallocThreshold) - { - valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; - } - else + Span escapedValue; + if (length > StackallocThreshold) + { + valueArray = ArrayPool.Shared.Rent(length); + escapedValue = valueArray; + } + else + { + // Cannot create a span directly since it gets passed to instance methods on a ref struct. + unsafe { - // Cannot create a span directly since it gets passed to instance methods on a ref struct. - unsafe - { - char* ptr = stackalloc char[length]; - span = new Span(ptr, length); - } + char* ptr = stackalloc char[length]; + escapedValue = new Span(ptr, length); } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); } + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); - WriteStringByOptions(value); + WriteStringByOptions(escapedValue.Slice(0, written)); if (valueArray != null) { @@ -215,33 +212,30 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); byte[] valueArray = null; - if (firstEscapeIndexVal != -1) - { - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); - Span span; - if (length > StackallocThreshold) - { - valueArray = ArrayPool.Shared.Rent(length); - span = valueArray; - } - else + Span escapedValue; + if (length > StackallocThreshold) + { + valueArray = ArrayPool.Shared.Rent(length); + escapedValue = valueArray; + } + else + { + // Cannot create a span directly since it gets passed to instance methods on a ref struct. + unsafe { - // Cannot create a span directly since it gets passed to instance methods on a ref struct. - unsafe - { - byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); - } + byte* ptr = stackalloc byte[length]; + escapedValue = new Span(ptr, length); } - JsonWriterHelper.EscapeString(value, span, firstEscapeIndexVal, out int written); - value = span.Slice(0, written); } + JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); - WriteStringByOptions(value); + WriteStringByOptions(escapedValue.Slice(0, written)); if (valueArray != null) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 2d407e83687e..459a364751ca 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -412,15 +412,16 @@ private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); byte[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -428,13 +429,13 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke unsafe { byte* ptr = stackalloc byte[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStartByOptions(span.Slice(0, written), token); + WriteStartByOptions(escapedPropertyName.Slice(0, written), token); if (propertyArray != null) { @@ -576,15 +577,16 @@ private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); char[] propertyArray = null; int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); - Span span; + Span escapedPropertyName; if (length > StackallocThreshold) { propertyArray = ArrayPool.Shared.Rent(length); - span = propertyArray; + escapedPropertyName = propertyArray; } else { @@ -592,12 +594,12 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke unsafe { char* ptr = stackalloc char[length]; - span = new Span(ptr, length); + escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, span, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - WriteStartByOptions(span.Slice(0, written), token); + WriteStartByOptions(escapedPropertyName.Slice(0, written), token); if (propertyArray != null) { From a14a57e409b9b0f6b27161f865f3bb099d59f537 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Sat, 12 Jan 2019 04:46:59 -0800 Subject: [PATCH 28/33] Rename suppressEscaping to escape and flip default from false to true. --- src/System.Text.Json/ref/System.Text.Json.cs | 114 ++--- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 26 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 26 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 26 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 26 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 26 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 26 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 48 +-- ...JsonWriter.WriteProperties.SignedNumber.cs | 44 +- .../Utf8JsonWriter.WriteProperties.String.cs | 86 ++-- ...onWriter.WriteProperties.UnsignedNumber.cs | 44 +- .../Utf8JsonWriter.WriteValues.Comment.cs | 26 +- .../Utf8JsonWriter.WriteValues.String.cs | 26 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 48 +-- .../tests/Utf8JsonWriterTests.cs | 392 +++++++++--------- 15 files changed, 492 insertions(+), 492 deletions(-) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index e93157824111..d5e25ac396a2 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -94,46 +94,46 @@ public ref partial struct Utf8JsonWriter public int CurrentDepth { get { throw null; } } public void Flush(bool isFinalBlock = true) { } public System.Text.Json.JsonWriterState GetCurrentState() { throw null; } - public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } - public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) { } - public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) { } + public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool escape = true) { } + public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool escape = true) { } + public void WriteBoolean(string propertyName, bool value, bool escape = true) { } public void WriteBooleanValue(bool value) { } - public void WriteCommentValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteCommentValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteCommentValue(string value, bool suppressEscaping = false) { } + public void WriteCommentValue(System.ReadOnlySpan value, bool escape = true) { } + public void WriteCommentValue(System.ReadOnlySpan value, bool escape = true) { } + public void WriteCommentValue(string value, bool escape = true) { } public void WriteEndArray() { } public void WriteEndObject() { } - public void WriteNull(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } - public void WriteNull(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } - public void WriteNull(string propertyName, bool suppressEscaping = false) { } + public void WriteNull(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteNull(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteNull(string propertyName, bool escape = true) { } public void WriteNullValue() { } - public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool suppressEscaping = false) { } - public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) { } - public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) { } - public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) { } - public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) { } - public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) { } - public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) { } + public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool escape = true) { } + public void WriteNumber(string propertyName, decimal value, bool escape = true) { } + public void WriteNumber(string propertyName, double value, bool escape = true) { } + public void WriteNumber(string propertyName, int value, bool escape = true) { } + public void WriteNumber(string propertyName, long value, bool escape = true) { } + public void WriteNumber(string propertyName, float value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, uint value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) { } + public void WriteNumber(string propertyName, ulong value, bool escape = true) { } public void WriteNumberValue(decimal value) { } public void WriteNumberValue(double value) { } public void WriteNumberValue(int value) { } @@ -144,36 +144,36 @@ public void WriteNumberValue(uint value) { } [System.CLSCompliantAttribute(false)] public void WriteNumberValue(ulong value) { } public void WriteStartArray() { } - public void WriteStartArray(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } - public void WriteStartArray(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } - public void WriteStartArray(string propertyName, bool suppressEscaping = false) { } + public void WriteStartArray(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteStartArray(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteStartArray(string propertyName, bool escape = true) { } public void WriteStartObject() { } - public void WriteStartObject(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } - public void WriteStartObject(System.ReadOnlySpan propertyName, bool suppressEscaping = false) { } - public void WriteStartObject(string propertyName, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteString(System.ReadOnlySpan propertyName, string value, bool suppressEscaping = false) { } - public void WriteString(string propertyName, System.DateTime value, bool suppressEscaping = false) { } - public void WriteString(string propertyName, System.DateTimeOffset value, bool suppressEscaping = false) { } - public void WriteString(string propertyName, System.Guid value, bool suppressEscaping = false) { } - public void WriteString(string propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteString(string propertyName, System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteString(string propertyName, string value, bool suppressEscaping = false) { } + public void WriteStartObject(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteStartObject(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteStartObject(string propertyName, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, string value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, string value, bool escape = true) { } + public void WriteString(string propertyName, System.DateTime value, bool escape = true) { } + public void WriteString(string propertyName, System.DateTimeOffset value, bool escape = true) { } + public void WriteString(string propertyName, System.Guid value, bool escape = true) { } + public void WriteString(string propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(string propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(string propertyName, string value, bool escape = true) { } public void WriteStringValue(System.DateTime value) { } public void WriteStringValue(System.DateTimeOffset value) { } public void WriteStringValue(System.Guid value) { } - public void WriteStringValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteStringValue(System.ReadOnlySpan value, bool suppressEscaping = false) { } - public void WriteStringValue(string value, bool suppressEscaping = false) { } + public void WriteStringValue(System.ReadOnlySpan value, bool escape = true) { } + public void WriteStringValue(System.ReadOnlySpan value, bool escape = true) { } + public void WriteStringValue(string value, bool escape = true) { } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index f3c0c9aa8086..c984770a202c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// - public void WriteString(string propertyName, DateTime value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value, suppressEscaping); + public void WriteString(string propertyName, DateTime value, bool escape = true) + => WriteString(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,13 +43,13 @@ public void WriteString(string propertyName, DateTime value, bool suppressEscapi /// /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// - public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, DateTime value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { @@ -65,7 +65,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -75,13 +75,13 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su /// /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. /// - public void WriteString(ReadOnlySpan propertyName, DateTime value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, DateTime value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { @@ -92,7 +92,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool su _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTime value) + private void WriteStringEscape(ReadOnlySpan propertyName, DateTime value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -108,7 +108,7 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTime } } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTime value) + private void WriteStringEscape(ReadOnlySpan propertyName, DateTime value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 14afc23b6eac..5a34b295aa73 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// - public void WriteString(string propertyName, DateTimeOffset value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value, suppressEscaping); + public void WriteString(string propertyName, DateTimeOffset value, bool escape = true) + => WriteString(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,13 +43,13 @@ public void WriteString(string propertyName, DateTimeOffset value, bool suppress /// /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// - public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { @@ -65,7 +65,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -75,13 +75,13 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. /// - public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { @@ -92,7 +92,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringEscape(ReadOnlySpan propertyName, DateTimeOffset value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -108,7 +108,7 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTimeO } } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringEscape(ReadOnlySpan propertyName, DateTimeOffset value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 26c6816818c1..52657a571420 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(string propertyName, decimal value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + public void WriteNumber(string propertyName, decimal value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,13 +43,13 @@ public void WriteNumber(string propertyName, decimal value, bool suppressEscapin /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -65,7 +65,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -75,13 +75,13 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -92,7 +92,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool sup _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, decimal value) + private void WriteNumberEscape(ReadOnlySpan propertyName, decimal value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -108,7 +108,7 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, decimal v } } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, decimal value) + private void WriteNumberEscape(ReadOnlySpan propertyName, decimal value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 612362c3d4b2..4c47c4eaa657 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(string propertyName, double value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + public void WriteNumber(string propertyName, double value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,14 +43,14 @@ public void WriteNumber(string propertyName, double value, bool suppressEscaping /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, double value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateDouble(value); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -66,7 +66,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -76,14 +76,14 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(ReadOnlySpan propertyName, double value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, double value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateDouble(value); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -94,7 +94,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool supp _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, double value) + private void WriteNumberEscape(ReadOnlySpan propertyName, double value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -110,7 +110,7 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, double va } } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, double value) + private void WriteNumberEscape(ReadOnlySpan propertyName, double value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index e05d4daa0841..9cbe347490e3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(string propertyName, float value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + public void WriteNumber(string propertyName, float value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,14 +43,14 @@ public void WriteNumber(string propertyName, float value, bool suppressEscaping /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, float value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateSingle(value); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -66,7 +66,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -76,14 +76,14 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr /// /// Writes the using the default (i.e. 'G') /// - public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, float value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); JsonWriterHelper.ValidateSingle(value); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -94,7 +94,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool suppr _tokenType = JsonTokenType.Number; } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, float value) + private void WriteNumberEscape(ReadOnlySpan propertyName, float value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -110,7 +110,7 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, float val } } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, float value) + private void WriteNumberEscape(ReadOnlySpan propertyName, float value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 2a01be695801..1bd64e6322da 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. /// - public void WriteString(string propertyName, Guid value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value, suppressEscaping); + public void WriteString(string propertyName, Guid value, bool escape = true) + => WriteString(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,13 +43,13 @@ public void WriteString(string propertyName, Guid value, bool suppressEscaping = /// /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. /// - public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, Guid value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { @@ -65,7 +65,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -75,13 +75,13 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre /// /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. /// - public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, Guid value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { @@ -92,7 +92,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool suppre _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, Guid value) + private void WriteStringEscape(ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -108,7 +108,7 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, Guid valu } } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, Guid value) + private void WriteStringEscape(ReadOnlySpan propertyName, Guid value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index 78f90e78e811..e5a7cedb5cd3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -13,36 +13,36 @@ public ref partial struct Utf8JsonWriter /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteNull(string propertyName, bool suppressEscaping = false) - => WriteNull(propertyName.AsSpan(), suppressEscaping); + public void WriteNull(string propertyName, bool escape = true) + => WriteNull(propertyName.AsSpan(), escape); /// /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) + public void WriteNull(ReadOnlySpan propertyName, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = JsonConstants.NullValue; - if (!suppressEscaping) + if (escape) { - WriteLiteralSuppressFalse(propertyName, span); + WriteLiteralEscape(propertyName, span); } else { @@ -57,22 +57,22 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. /// /// The UTF-8 encoded property name of the JSON object to be written. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = false) + public void WriteNull(ReadOnlySpan propertyName, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = JsonConstants.NullValue; - if (!suppressEscaping) + if (escape) { - WriteLiteralSuppressFalse(propertyName, span); + WriteLiteralEscape(propertyName, span); } else { @@ -88,37 +88,37 @@ public void WriteNull(ReadOnlySpan propertyName, bool suppressEscaping = f /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteBoolean(string propertyName, bool value, bool suppressEscaping = false) - => WriteBoolean(propertyName.AsSpan(), value, suppressEscaping); + public void WriteBoolean(string propertyName, bool value, bool escape = true) + => WriteBoolean(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON literal "true" or "false") as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) + public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; - if (!suppressEscaping) + if (escape) { - WriteLiteralSuppressFalse(propertyName, span); + WriteLiteralEscape(propertyName, span); } else { @@ -134,22 +134,22 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppressEscaping = false) + public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; - if (!suppressEscaping) + if (escape) { - WriteLiteralSuppressFalse(propertyName, span); + WriteLiteralEscape(propertyName, span); } else { @@ -160,7 +160,7 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool suppr _tokenType = value ? JsonTokenType.True : JsonTokenType.False; } - private void WriteLiteralSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteLiteralEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -176,7 +176,7 @@ private void WriteLiteralSuppressFalse(ReadOnlySpan propertyName, ReadOnly } } - private void WriteLiteralSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteLiteralEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 50ea38fa6943..a3703bb9a9a9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -25,15 +25,15 @@ public ref partial struct Utf8JsonWriter /// /// Writes the using the default (i.e. 'G'), for example: 32767 /// - public void WriteNumber(string propertyName, long value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + public void WriteNumber(string propertyName, long value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -43,13 +43,13 @@ public void WriteNumber(string propertyName, long value, bool suppressEscaping = /// /// Writes the using the default (i.e. 'G'), for example: 32767 /// - public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -65,7 +65,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -75,13 +75,13 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// Writes the using the default (i.e. 'G'), for example: 32767 /// - public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -97,7 +97,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -107,15 +107,15 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool suppre /// /// Writes the using the default (i.e. 'G'), for example: 32767 /// - public void WriteNumber(string propertyName, int value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), (long)value, suppressEscaping); + public void WriteNumber(string propertyName, int value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), (long)value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -125,15 +125,15 @@ public void WriteNumber(string propertyName, int value, bool suppressEscaping = /// /// Writes the using the default (i.e. 'G'), for example: 32767 /// - public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) - => WriteNumber(propertyName, (long)value, suppressEscaping); + public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape = true) + => WriteNumber(propertyName, (long)value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -143,10 +143,10 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppres /// /// Writes the using the default (i.e. 'G'), for example: 32767 /// - public void WriteNumber(ReadOnlySpan propertyName, int value, bool suppressEscaping = false) - => WriteNumber(propertyName, (long)value, suppressEscaping); + public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape = true) + => WriteNumber(propertyName, (long)value, escape); - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, long value) + private void WriteNumberEscape(ReadOnlySpan propertyName, long value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -162,7 +162,7 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, long valu } } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, long value) + private void WriteNumberEscape(ReadOnlySpan propertyName, long value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 6e082397d85e..54f0ae9071bb 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -24,15 +24,15 @@ public ref partial struct Utf8JsonWriter /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(string propertyName, string value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value.AsSpan(), suppressEscaping); + public void WriteString(string propertyName, string value, bool escape = true) + => WriteString(propertyName.AsSpan(), value.AsSpan(), escape); /// /// Writes the UTF-16 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -40,17 +40,17 @@ public void WriteString(string propertyName, string value, bool suppressEscaping /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { - WriteStringSuppressTrue(propertyName, value); + WriteStringDontEscape(propertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -62,7 +62,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// The UTF-8 encoded property name of the JSON object to be written. /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -70,17 +70,17 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { - WriteStringSuppressTrue(propertyName, value); + WriteStringDontEscape(propertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -92,7 +92,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -100,15 +100,15 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value, suppressEscaping); + public void WriteString(string propertyName, ReadOnlySpan value, bool escape = true) + => WriteString(propertyName.AsSpan(), value, escape); /// /// Writes the UTF-8 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-8 encoded property name of the JSON object to be written. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -116,17 +116,17 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool supp /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { - WriteStringSuppressTrue(propertyName, value); + WriteStringDontEscape(propertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -138,7 +138,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -146,15 +146,15 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(string propertyName, ReadOnlySpan value, bool suppressEscaping = false) - => WriteString(propertyName.AsSpan(), value, suppressEscaping); + public void WriteString(string propertyName, ReadOnlySpan value, bool escape = true) + => WriteString(propertyName.AsSpan(), value, escape); /// /// Writes the UTF-16 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -162,17 +162,17 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool supp /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool suppressEscaping = false) + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(propertyName, value); + WriteStringEscape(propertyName, value); } else { - WriteStringSuppressTrue(propertyName, value); + WriteStringDontEscape(propertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -184,7 +184,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -192,15 +192,15 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) - => WriteString(propertyName, value.AsSpan(), suppressEscaping); + public void WriteString(ReadOnlySpan propertyName, string value, bool escape = true) + => WriteString(propertyName, value.AsSpan(), escape); /// /// Writes the UTF-8 property name and string text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-8 encoded property name of the JSON object to be written. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// /// Thrown when the specified property name or value is too large. @@ -208,11 +208,11 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool supp /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, string value, bool suppressEscaping = false) - => WriteString(propertyName, value.AsSpan(), suppressEscaping); + public void WriteString(ReadOnlySpan propertyName, string value, bool escape = true) + => WriteString(propertyName, value.AsSpan(), escape); [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) + private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -226,7 +226,7 @@ private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, Rea } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) + private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -240,7 +240,7 @@ private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, Rea } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) + private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -254,7 +254,7 @@ private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, Rea } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringSuppressTrue(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) + private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); if (valueIdx != -1) @@ -323,7 +323,7 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ArrayPool.Shared.Return(valueArray); } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -342,7 +342,7 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlyS } } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -361,7 +361,7 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlyS } } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -380,7 +380,7 @@ private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlyS } } - private void WriteStringSuppressFalse(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 522c37345aaf..124eddc21c84 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -15,7 +15,7 @@ public ref partial struct Utf8JsonWriter /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -26,15 +26,15 @@ public ref partial struct Utf8JsonWriter /// Writes the using the default (i.e. 'G'), for example: 32767 /// [CLSCompliant(false)] - public void WriteNumber(string propertyName, ulong value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), value, suppressEscaping); + public void WriteNumber(string propertyName, ulong value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -45,13 +45,13 @@ public void WriteNumber(string propertyName, ulong value, bool suppressEscaping /// Writes the using the default (i.e. 'G'), for example: 32767 /// [CLSCompliant(false)] - public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -67,7 +67,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -78,13 +78,13 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// Writes the using the default (i.e. 'G'), for example: 32767 /// [CLSCompliant(false)] - public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppressEscaping = false) + public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escape = true) { JsonWriterHelper.ValidateProperty(propertyName); - if (!suppressEscaping) + if (escape) { - WriteNumberSuppressFalse(propertyName, value); + WriteNumberEscape(propertyName, value); } else { @@ -100,7 +100,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -111,15 +111,15 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool suppr /// Writes the using the default (i.e. 'G'), for example: 32767 /// [CLSCompliant(false)] - public void WriteNumber(string propertyName, uint value, bool suppressEscaping = false) - => WriteNumber(propertyName.AsSpan(), (ulong)value, suppressEscaping); + public void WriteNumber(string propertyName, uint value, bool escape = true) + => WriteNumber(propertyName.AsSpan(), (ulong)value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -130,15 +130,15 @@ public void WriteNumber(string propertyName, uint value, bool suppressEscaping = /// Writes the using the default (i.e. 'G'), for example: 32767 /// [CLSCompliant(false)] - public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) - => WriteNumber(propertyName, (ulong)value, suppressEscaping); + public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape = true) + => WriteNumber(propertyName, (ulong)value, escape); /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -149,10 +149,10 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppre /// Writes the using the default (i.e. 'G'), for example: 32767 /// [CLSCompliant(false)] - public void WriteNumber(ReadOnlySpan propertyName, uint value, bool suppressEscaping = false) - => WriteNumber(propertyName, (ulong)value, suppressEscaping); + public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape = true) + => WriteNumber(propertyName, (ulong)value, escape); - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, ulong value) + private void WriteNumberEscape(ReadOnlySpan propertyName, ulong value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -168,7 +168,7 @@ private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, ulong val } } - private void WriteNumberSuppressFalse(ReadOnlySpan propertyName, ulong value) + private void WriteNumberEscape(ReadOnlySpan propertyName, ulong value) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 152fc502ebf1..09da20d6ac30 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -14,28 +14,28 @@ public ref partial struct Utf8JsonWriter /// Writes the string text value (as a JSON comment). /// /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. - /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(string value, bool suppressEscaping = false) - => WriteCommentValue(value.AsSpan(), suppressEscaping); + public void WriteCommentValue(string value, bool escape = true) + => WriteCommentValue(value.AsSpan(), escape); /// /// Writes the UTF-16 text value (as a JSON comment). /// /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON comment within /*..*/. - /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = false) + public void WriteCommentValue(ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidateValue(value); - if (!suppressEscaping) + if (escape) { - WriteCommentSuppressFalse(value); + WriteCommentEscape(value); } else { @@ -43,7 +43,7 @@ public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = } } - private void WriteCommentSuppressFalse(ReadOnlySpan value) + private void WriteCommentEscape(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -143,17 +143,17 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn /// Writes the UTF-8 text value (as a JSON comment). /// /// The UTF-8 encoded value to be written as a JSON comment within /*..*/. - /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = false) + public void WriteCommentValue(ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidateValue(value); - if (!suppressEscaping) + if (escape) { - WriteCommentSuppressFalse(value); + WriteCommentEscape(value); } else { @@ -161,7 +161,7 @@ public void WriteCommentValue(ReadOnlySpan value, bool suppressEscaping = } } - private void WriteCommentSuppressFalse(ReadOnlySpan value) + private void WriteCommentEscape(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 0785334b52be..753f9f423de9 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -13,34 +13,34 @@ public ref partial struct Utf8JsonWriter /// Writes the string text value (as a JSON string) as an element of a JSON array. /// /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. - /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(string value, bool suppressEscaping = false) - => WriteStringValue(value.AsSpan(), suppressEscaping); + public void WriteStringValue(string value, bool escape = true) + => WriteStringValue(value.AsSpan(), escape); /// /// Writes the UTF-16 text value (as a JSON string) as an element of a JSON array. /// /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string element of a JSON array. - /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) + public void WriteStringValue(ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidateValue(value); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(value); + WriteStringEscape(value); } else { @@ -51,7 +51,7 @@ public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = f _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); @@ -137,20 +137,20 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd /// Writes the UTF-8 text value (as a JSON string) as an element of a JSON array. /// /// The UTF-8 encoded value to be written as a JSON string element of a JSON array. - /// If this is set, the writer assumes the value is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = false) + public void WriteStringValue(ReadOnlySpan value, bool escape = true) { JsonWriterHelper.ValidateValue(value); - if (!suppressEscaping) + if (escape) { - WriteStringSuppressFalse(value); + WriteStringEscape(value); } else { @@ -161,7 +161,7 @@ public void WriteStringValue(ReadOnlySpan value, bool suppressEscaping = f _tokenType = JsonTokenType.String; } - private void WriteStringSuppressFalse(ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 459a364751ca..81732682663b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -312,7 +312,7 @@ private void WriteStartIndented(byte token) /// Writes the beginning of a JSON array with a property name as the key. /// /// The UTF-8 encoded property name of the JSON array to be written. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -320,13 +320,13 @@ private void WriteStartIndented(byte token) /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) + public void WriteStartArray(ReadOnlySpan propertyName, bool escape = true) { ValidatePropertyNameAndDepth(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStartSuppressFalse(propertyName, JsonConstants.OpenBracket); + WriteStartEscape(propertyName, JsonConstants.OpenBracket); } else { @@ -343,7 +343,7 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// Writes the beginning of a JSON object with a property name as the key. /// /// The UTF-8 encoded property name of the JSON object to be written. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -351,13 +351,13 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) + public void WriteStartObject(ReadOnlySpan propertyName, bool escape = true) { ValidatePropertyNameAndDepth(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStartSuppressFalse(propertyName, JsonConstants.OpenBrace); + WriteStartEscape(propertyName, JsonConstants.OpenBrace); } else { @@ -370,7 +370,7 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap _tokenType = JsonTokenType.StartObject; } - private void WriteStartSuppressFalse(ReadOnlySpan propertyName, byte token) + private void WriteStartEscape(ReadOnlySpan propertyName, byte token) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); @@ -447,7 +447,7 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke /// Writes the beginning of a JSON array with a property name as the key. /// /// The UTF-16 encoded property name of the JSON array to be transcoded and written as UTF-8. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -455,14 +455,14 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartArray(string propertyName, bool suppressEscaping = false) - => WriteStartArray(propertyName.AsSpan(), suppressEscaping); + public void WriteStartArray(string propertyName, bool escape = true) + => WriteStartArray(propertyName.AsSpan(), escape); /// /// Writes the beginning of a JSON object with a property name as the key. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -470,14 +470,14 @@ public void WriteStartArray(string propertyName, bool suppressEscaping = false) /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartObject(string propertyName, bool suppressEscaping = false) - => WriteStartObject(propertyName.AsSpan(), suppressEscaping); + public void WriteStartObject(string propertyName, bool escape = true) + => WriteStartObject(propertyName.AsSpan(), escape); /// /// Writes the beginning of a JSON array with a property name as the key. /// /// The UTF-16 encoded property name of the JSON array to be transcoded and written as UTF-8. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -485,13 +485,13 @@ public void WriteStartObject(string propertyName, bool suppressEscaping = false) /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscaping = false) + public void WriteStartArray(ReadOnlySpan propertyName, bool escape = true) { ValidatePropertyNameAndDepth(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStartSuppressFalse(propertyName, JsonConstants.OpenBracket); + WriteStartEscape(propertyName, JsonConstants.OpenBracket); } else { @@ -508,7 +508,7 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// Writes the beginning of a JSON object with a property name as the key. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. - /// If this is set, the writer assumes the property name is properly escaped and skips the escaping step. + /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. /// @@ -516,13 +516,13 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool suppressEscapi /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscaping = false) + public void WriteStartObject(ReadOnlySpan propertyName, bool escape = true) { ValidatePropertyNameAndDepth(propertyName); - if (!suppressEscaping) + if (escape) { - WriteStartSuppressFalse(propertyName, JsonConstants.OpenBrace); + WriteStartEscape(propertyName, JsonConstants.OpenBrace); } else { @@ -535,7 +535,7 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool suppressEscap _tokenType = JsonTokenType.StartObject; } - private void WriteStartSuppressFalse(ReadOnlySpan propertyName, byte token) + private void WriteStartEscape(ReadOnlySpan propertyName, byte token) { int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index cb44b2348814..e3233cccadaa 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -229,7 +229,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8 = new Utf8JsonWriter(output, state); try { - jsonUtf8.WriteStartArray("property at start", suppressEscaping: true); + jsonUtf8.WriteStartArray("property at start", escape: false); WriterDidNotThrow(skipValidation); } catch (InvalidOperationException) { } @@ -237,7 +237,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8 = new Utf8JsonWriter(output, state); try { - jsonUtf8.WriteStartObject("property at start", suppressEscaping: true); + jsonUtf8.WriteStartObject("property at start", escape: false); WriterDidNotThrow(skipValidation); } catch (InvalidOperationException) { } @@ -246,7 +246,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartArray(); - jsonUtf8.WriteStartArray("property inside array", suppressEscaping: true); + jsonUtf8.WriteStartArray("property inside array", escape: false); WriterDidNotThrow(skipValidation); } catch (InvalidOperationException) { } @@ -311,7 +311,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartObject(); - jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteStartObject("some object", escape: false); jsonUtf8.WriteEndObject(); jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); @@ -322,7 +322,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartArray(); - jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteStartObject("some object", escape: false); jsonUtf8.WriteEndObject(); jsonUtf8.WriteEndObject(); WriterDidNotThrow(skipValidation); @@ -333,7 +333,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartObject(); - jsonUtf8.WriteStartArray("test array", suppressEscaping: true); + jsonUtf8.WriteStartArray("test array", escape: false); jsonUtf8.WriteEndArray(); jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); @@ -374,7 +374,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartObject(); - jsonUtf8.WriteStartObject("test object", suppressEscaping: true); + jsonUtf8.WriteStartObject("test object", escape: false); jsonUtf8.WriteEndArray(); WriterDidNotThrow(skipValidation); } @@ -427,7 +427,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartObject(); - jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteStartObject("some object", escape: false); jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); } @@ -437,7 +437,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartArray(); - jsonUtf8.WriteStartObject("some object", suppressEscaping: true); + jsonUtf8.WriteStartObject("some object", escape: false); jsonUtf8.WriteEndObject(); jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); @@ -448,7 +448,7 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartObject(); - jsonUtf8.WriteStartArray("test array", suppressEscaping: true); + jsonUtf8.WriteStartArray("test array", escape: false); jsonUtf8.WriteEndArray(); jsonUtf8.Flush(isFinalBlock: true); WriterDidNotThrow(skipValidation); @@ -500,7 +500,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) try { jsonUtf8.WriteNumberValue(12345); - jsonUtf8.WriteStartArray("property name", suppressEscaping: true); + jsonUtf8.WriteStartArray("property name", escape: false); WriterDidNotThrow(skipValidation); } catch (InvalidOperationException) { } @@ -509,7 +509,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) try { jsonUtf8.WriteNumberValue(12345); - jsonUtf8.WriteStartObject("property name", suppressEscaping: true); + jsonUtf8.WriteStartObject("property name", escape: false); WriterDidNotThrow(skipValidation); } catch (InvalidOperationException) { } @@ -518,7 +518,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) try { jsonUtf8.WriteNumberValue(12345); - jsonUtf8.WriteString("property name", "value", suppressEscaping: true); + jsonUtf8.WriteString("property name", "value", escape: false); WriterDidNotThrow(skipValidation); } catch (InvalidOperationException) { } @@ -853,31 +853,31 @@ public void WriteHelloWorld(bool formatted, bool skipValidation) switch (i) { case 0: - jsonUtf8.WriteString("message", "Hello, World!", suppressEscaping: true); + jsonUtf8.WriteString("message", "Hello, World!", escape: false); break; case 1: - jsonUtf8.WriteString("message", "Hello, World!".AsSpan(), suppressEscaping: true); + jsonUtf8.WriteString("message", "Hello, World!".AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteString("message", Encoding.UTF8.GetBytes("Hello, World!"), suppressEscaping: true); + jsonUtf8.WriteString("message", Encoding.UTF8.GetBytes("Hello, World!"), escape: false); break; case 3: - jsonUtf8.WriteString("message".AsSpan(), "Hello, World!", suppressEscaping: true); + jsonUtf8.WriteString("message".AsSpan(), "Hello, World!", escape: false); break; case 4: - jsonUtf8.WriteString("message".AsSpan(), "Hello, World!".AsSpan(), suppressEscaping: true); + jsonUtf8.WriteString("message".AsSpan(), "Hello, World!".AsSpan(), escape: false); break; case 5: - jsonUtf8.WriteString("message".AsSpan(), Encoding.UTF8.GetBytes("Hello, World!"), suppressEscaping: true); + jsonUtf8.WriteString("message".AsSpan(), Encoding.UTF8.GetBytes("Hello, World!"), escape: false); break; case 6: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), "Hello, World!", suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), "Hello, World!", escape: false); break; case 7: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), "Hello, World!".AsSpan(), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), "Hello, World!".AsSpan(), escape: false); break; case 8: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), Encoding.UTF8.GetBytes("Hello, World!"), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes("message"), Encoding.UTF8.GetBytes("Hello, World!"), escape: false); break; } @@ -1228,13 +1228,13 @@ private static void WriteCommentValue(ref Utf8JsonWriter jsonUtf8, int i, string switch (i) { case 0: - jsonUtf8.WriteCommentValue(comment, suppressEscaping: true); + jsonUtf8.WriteCommentValue(comment, escape: false); break; case 1: - jsonUtf8.WriteCommentValue(comment.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteCommentValue(comment.AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteCommentValue(Encoding.UTF8.GetBytes(comment), suppressEscaping: true); + jsonUtf8.WriteCommentValue(Encoding.UTF8.GetBytes(comment), escape: false); break; } } @@ -1272,13 +1272,13 @@ public void WriteStrings(bool formatted, bool skipValidation) jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value)); break; case 3: - jsonUtf8.WriteStringValue(value, suppressEscaping: true); + jsonUtf8.WriteStringValue(value, escape: false); break; case 4: - jsonUtf8.WriteStringValue(value.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteStringValue(value.AsSpan(), escape: false); break; case 5: - jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value), escape: false); break; } } @@ -1333,58 +1333,58 @@ public void WriteHelloWorldEscaped(bool formatted, bool skipValidation, string k switch (i) { case 0: - jsonUtf8.WriteString(key, value, suppressEscaping: false); + jsonUtf8.WriteString(key, value, escape: true); break; case 1: - jsonUtf8.WriteString(key.AsSpan(), value.AsSpan(), suppressEscaping: false); + jsonUtf8.WriteString(key.AsSpan(), value.AsSpan(), escape: true); break; case 2: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), escape: true); break; case 3: - jsonUtf8.WriteString(key, value.AsSpan(), suppressEscaping: false); + jsonUtf8.WriteString(key, value.AsSpan(), escape: true); break; case 4: - jsonUtf8.WriteString(key, Encoding.UTF8.GetBytes(value), suppressEscaping: false); + jsonUtf8.WriteString(key, Encoding.UTF8.GetBytes(value), escape: true); break; case 5: - jsonUtf8.WriteString(key.AsSpan(), value, suppressEscaping: false); + jsonUtf8.WriteString(key.AsSpan(), value, escape: true); break; case 6: - jsonUtf8.WriteString(key.AsSpan(), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + jsonUtf8.WriteString(key.AsSpan(), Encoding.UTF8.GetBytes(value), escape: true); break; case 7: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value, suppressEscaping: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value, escape: true); break; case 8: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value.AsSpan(), suppressEscaping: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value.AsSpan(), escape: true); break; case 9: - jsonUtf8.WriteString(key, value, suppressEscaping: true); + jsonUtf8.WriteString(key, value, escape: false); break; case 10: - jsonUtf8.WriteString(key.AsSpan(), value.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteString(key.AsSpan(), value.AsSpan(), escape: false); break; case 11: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value), escape: false); break; case 12: - jsonUtf8.WriteString(key, value.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteString(key, value.AsSpan(), escape: false); break; case 13: - jsonUtf8.WriteString(key, Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteString(key, Encoding.UTF8.GetBytes(value), escape: false); break; case 14: - jsonUtf8.WriteString(key.AsSpan(), value, suppressEscaping: true); + jsonUtf8.WriteString(key.AsSpan(), value, escape: false); break; case 15: - jsonUtf8.WriteString(key.AsSpan(), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteString(key.AsSpan(), Encoding.UTF8.GetBytes(value), escape: false); break; case 16: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value, suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value, escape: false); break; case 17: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(key), value.AsSpan(), escape: false); break; } @@ -1441,18 +1441,18 @@ public void EscapeAsciiCharacters(bool formatted, bool skipValidation) switch (i) { case 0: - jsonUtf8.WriteString(propertyName, value, suppressEscaping: false); + jsonUtf8.WriteString(propertyName, value, escape: true); break; case 1: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), escape: true); break; case 2: expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml, escape: false); - jsonUtf8.WriteString(propertyName, value, suppressEscaping: true); + jsonUtf8.WriteString(propertyName, value, escape: false); break; case 3: expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml, escape: false); - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), escape: false); break; } @@ -1502,18 +1502,18 @@ public void EscapeCharacters(bool formatted, bool skipValidation) switch (i) { case 0: - jsonUtf8.WriteString(propertyName, value, suppressEscaping: false); + jsonUtf8.WriteString(propertyName, value, escape: true); break; case 1: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), escape: true); break; case 2: expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); - jsonUtf8.WriteString(propertyName, value, suppressEscaping: true); + jsonUtf8.WriteString(propertyName, value, escape: false); break; case 3: expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), escape: false); break; } @@ -1554,18 +1554,18 @@ public void EscapeSurrogatePairs(bool formatted, bool skipValidation) switch (i) { case 0: - jsonUtf8.WriteString(propertyName, value, suppressEscaping: false); + jsonUtf8.WriteString(propertyName, value, escape: true); break; case 1: - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: false); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), escape: true); break; case 2: expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); - jsonUtf8.WriteString(propertyName, value, suppressEscaping: true); + jsonUtf8.WriteString(propertyName, value, escape: false); break; case 3: expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii, escape: false); - jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), suppressEscaping: true); + jsonUtf8.WriteString(Encoding.UTF8.GetBytes(propertyName), Encoding.UTF8.GetBytes(value), escape: false); break; } @@ -1601,35 +1601,35 @@ public void InvalidUTF8(bool formatted, bool skipValidation) switch (i) { case 0: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: true); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0x28 }, escape: false); AssertWriterThrow(noThrow: false); break; case 1: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: true); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0xb1 }, escape: false); AssertWriterThrow(noThrow: true); break; case 2: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: true); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0x28 }, escape: false); AssertWriterThrow(noThrow: false); break; case 3: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: true); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0xb1 }, escape: false); AssertWriterThrow(noThrow: true); break; case 4: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: false); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0x28 }, escape: true); AssertWriterThrow(noThrow: false); break; case 5: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: false); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0x28 }, new byte[2] { 0xc3, 0xb1 }, escape: true); AssertWriterThrow(noThrow: false); break; case 6: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0x28 }, suppressEscaping: false); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0x28 }, escape: true); AssertWriterThrow(noThrow: false); break; case 7: - jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0xb1 }, suppressEscaping: false); + jsonUtf8.WriteString(new byte[2] { 0xc3, 0xb1 }, new byte[2] { 0xc3, 0xb1 }, escape: true); AssertWriterThrow(noThrow: true); break; } @@ -1657,7 +1657,7 @@ public void WriteCustomStrings(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); for (int i = 0; i < 1_000; i++) - jsonUtf8.WriteString("message", "Hello, World!", suppressEscaping: true); + jsonUtf8.WriteString("message", "Hello, World!", escape: false); jsonUtf8.WriteEndObject(); jsonUtf8.Flush(); @@ -1768,22 +1768,22 @@ public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidati switch (i) { case 0: - jsonUtf8.WriteStartArray("property name", suppressEscaping: true); + jsonUtf8.WriteStartArray("property name", escape: false); break; case 1: - jsonUtf8.WriteStartArray("property name".AsSpan(), suppressEscaping: true); + jsonUtf8.WriteStartArray("property name".AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("property name"), suppressEscaping: true); + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("property name"), escape: false); break; case 3: - jsonUtf8.WriteStartArray("property name", suppressEscaping: false); + jsonUtf8.WriteStartArray("property name", escape: true); break; case 4: - jsonUtf8.WriteStartArray("property name".AsSpan(), suppressEscaping: false); + jsonUtf8.WriteStartArray("property name".AsSpan(), escape: true); break; case 5: - jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("property name"), suppressEscaping: false); + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("property name"), escape: true); break; } @@ -1833,22 +1833,22 @@ public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidati switch (i) { case 0: - jsonUtf8.WriteStartArray(key, suppressEscaping: true); + jsonUtf8.WriteStartArray(key, escape: false); break; case 1: - jsonUtf8.WriteStartArray(key.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteStartArray(key.AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes(key), suppressEscaping: true); + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes(key), escape: false); break; case 3: - jsonUtf8.WriteStartArray(key, suppressEscaping: false); + jsonUtf8.WriteStartArray(key, escape: true); break; case 4: - jsonUtf8.WriteStartArray(key.AsSpan(), suppressEscaping: false); + jsonUtf8.WriteStartArray(key.AsSpan(), escape: true); break; case 5: - jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes(key), suppressEscaping: false); + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes(key), escape: true); break; } @@ -1889,22 +1889,22 @@ public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidat switch (i) { case 0: - jsonUtf8.WriteStartObject("property name", suppressEscaping: true); + jsonUtf8.WriteStartObject("property name", escape: false); break; case 1: - jsonUtf8.WriteStartObject("property name".AsSpan(), suppressEscaping: true); + jsonUtf8.WriteStartObject("property name".AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes("property name"), suppressEscaping: true); + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes("property name"), escape: false); break; case 3: - jsonUtf8.WriteStartObject("property name", suppressEscaping: false); + jsonUtf8.WriteStartObject("property name", escape: true); break; case 4: - jsonUtf8.WriteStartObject("property name".AsSpan(), suppressEscaping: false); + jsonUtf8.WriteStartObject("property name".AsSpan(), escape: true); break; case 5: - jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes("property name"), suppressEscaping: false); + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes("property name"), escape: true); break; } @@ -1954,22 +1954,22 @@ public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidat switch (i) { case 0: - jsonUtf8.WriteStartObject(key, suppressEscaping: true); + jsonUtf8.WriteStartObject(key, escape: false); break; case 1: - jsonUtf8.WriteStartObject(key.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteStartObject(key.AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes(key), suppressEscaping: true); + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes(key), escape: false); break; case 3: - jsonUtf8.WriteStartObject(key, suppressEscaping: false); + jsonUtf8.WriteStartObject(key, escape: true); break; case 4: - jsonUtf8.WriteStartObject(key.AsSpan(), suppressEscaping: false); + jsonUtf8.WriteStartObject(key.AsSpan(), escape: true); break; case 5: - jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes(key), suppressEscaping: false); + jsonUtf8.WriteStartObject(Encoding.UTF8.GetBytes(key), escape: true); break; } @@ -2010,13 +2010,13 @@ public void WriteArrayWithProperty(bool formatted, bool skipValidation) switch (i) { case 0: - jsonUtf8.WriteStartArray("message", suppressEscaping: true); + jsonUtf8.WriteStartArray("message", escape: false); break; case 1: - jsonUtf8.WriteStartArray("message".AsSpan(), suppressEscaping: true); + jsonUtf8.WriteStartArray("message".AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("message"), suppressEscaping: true); + jsonUtf8.WriteStartArray(Encoding.UTF8.GetBytes("message"), escape: false); break; } @@ -2075,22 +2075,22 @@ public void WriteBooleanValue(bool formatted, bool skipValidation, bool value, s switch (i) { case 0: - jsonUtf8.WriteBoolean(keyString, value, suppressEscaping: true); + jsonUtf8.WriteBoolean(keyString, value, escape: false); break; case 1: - jsonUtf8.WriteBoolean(keyString.AsSpan(), value, suppressEscaping: true); + jsonUtf8.WriteBoolean(keyString.AsSpan(), value, escape: false); break; case 2: - jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value, suppressEscaping: true); + jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value, escape: false); break; case 3: - jsonUtf8.WriteBoolean(keyString, value, suppressEscaping: false); + jsonUtf8.WriteBoolean(keyString, value, escape: true); break; case 4: - jsonUtf8.WriteBoolean(keyString.AsSpan(), value, suppressEscaping: false); + jsonUtf8.WriteBoolean(keyString.AsSpan(), value, escape: true); break; case 5: - jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value, suppressEscaping: false); + jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value, escape: true); break; } @@ -2146,22 +2146,22 @@ public void WriteNullValue(bool formatted, bool skipValidation, string keyString switch (i) { case 0: - jsonUtf8.WriteNull(keyString, suppressEscaping: true); + jsonUtf8.WriteNull(keyString, escape: false); break; case 1: - jsonUtf8.WriteNull(keyString.AsSpan(), suppressEscaping: true); + jsonUtf8.WriteNull(keyString.AsSpan(), escape: false); break; case 2: - jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString), suppressEscaping: true); + jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString), escape: false); break; case 3: - jsonUtf8.WriteNull(keyString, suppressEscaping: false); + jsonUtf8.WriteNull(keyString, escape: true); break; case 4: - jsonUtf8.WriteNull(keyString.AsSpan(), suppressEscaping: false); + jsonUtf8.WriteNull(keyString.AsSpan(), escape: true); break; case 5: - jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString), suppressEscaping: false); + jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString), escape: true); break; } @@ -2226,13 +2226,13 @@ public void WriteIntegerValue(bool formatted, bool skipValidation, int value) switch (i) { case 0: - jsonUtf8.WriteNumber("message", value, suppressEscaping: true); + jsonUtf8.WriteNumber("message", value, escape: false); break; case 1: - jsonUtf8.WriteNumber("message".AsSpan(), value, suppressEscaping: true); + jsonUtf8.WriteNumber("message".AsSpan(), value, escape: false); break; case 2: - jsonUtf8.WriteNumber(Encoding.UTF8.GetBytes("message"), value, suppressEscaping: true); + jsonUtf8.WriteNumber(Encoding.UTF8.GetBytes("message"), value, escape: false); break; } @@ -2407,105 +2407,105 @@ public void WriteNumbers(bool formatted, bool skipValidation, string keyString) { case 0: for (int i = 0; i < floats.Length; i++) - jsonUtf8.WriteNumber(keyString, floats[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, floats[i], escape: false); for (int i = 0; i < ints.Length; i++) - jsonUtf8.WriteNumber(keyString, ints[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, ints[i], escape: false); for (int i = 0; i < uints.Length; i++) - jsonUtf8.WriteNumber(keyString, uints[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, uints[i], escape: false); for (int i = 0; i < doubles.Length; i++) - jsonUtf8.WriteNumber(keyString, doubles[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, doubles[i], escape: false); for (int i = 0; i < longs.Length; i++) - jsonUtf8.WriteNumber(keyString, longs[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, longs[i], escape: false); for (int i = 0; i < ulongs.Length; i++) - jsonUtf8.WriteNumber(keyString, ulongs[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, ulongs[i], escape: false); for (int i = 0; i < decimals.Length; i++) - jsonUtf8.WriteNumber(keyString, decimals[i], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + jsonUtf8.WriteNumber(keyString, decimals[i], escape: false); + jsonUtf8.WriteStartArray(keyString, escape: false); break; case 1: for (int i = 0; i < floats.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, floats[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, floats[i], escape: false); for (int i = 0; i < ints.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, ints[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, ints[i], escape: false); for (int i = 0; i < uints.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, uints[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, uints[i], escape: false); for (int i = 0; i < doubles.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, doubles[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, doubles[i], escape: false); for (int i = 0; i < longs.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, longs[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, longs[i], escape: false); for (int i = 0; i < ulongs.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, ulongs[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, ulongs[i], escape: false); for (int i = 0; i < decimals.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, decimals[i], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf16, decimals[i], escape: false); + jsonUtf8.WriteStartArray(keyUtf16, escape: false); break; case 2: for (int i = 0; i < floats.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, floats[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, floats[i], escape: false); for (int i = 0; i < ints.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, ints[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, ints[i], escape: false); for (int i = 0; i < uints.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, uints[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, uints[i], escape: false); for (int i = 0; i < doubles.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, doubles[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, doubles[i], escape: false); for (int i = 0; i < longs.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, longs[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, longs[i], escape: false); for (int i = 0; i < ulongs.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, ulongs[i], suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, ulongs[i], escape: false); for (int i = 0; i < decimals.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, decimals[i], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + jsonUtf8.WriteNumber(keyUtf8, decimals[i], escape: false); + jsonUtf8.WriteStartArray(keyUtf8, escape: false); break; case 3: for (int i = 0; i < floats.Length; i++) - jsonUtf8.WriteNumber(keyString, floats[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, floats[i], escape: true); for (int i = 0; i < ints.Length; i++) - jsonUtf8.WriteNumber(keyString, ints[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, ints[i], escape: true); for (int i = 0; i < uints.Length; i++) - jsonUtf8.WriteNumber(keyString, uints[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, uints[i], escape: true); for (int i = 0; i < doubles.Length; i++) - jsonUtf8.WriteNumber(keyString, doubles[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, doubles[i], escape: true); for (int i = 0; i < longs.Length; i++) - jsonUtf8.WriteNumber(keyString, longs[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, longs[i], escape: true); for (int i = 0; i < ulongs.Length; i++) - jsonUtf8.WriteNumber(keyString, ulongs[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, ulongs[i], escape: true); for (int i = 0; i < decimals.Length; i++) - jsonUtf8.WriteNumber(keyString, decimals[i], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + jsonUtf8.WriteNumber(keyString, decimals[i], escape: true); + jsonUtf8.WriteStartArray(keyString, escape: true); break; case 4: for (int i = 0; i < floats.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, floats[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, floats[i], escape: true); for (int i = 0; i < ints.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, ints[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, ints[i], escape: true); for (int i = 0; i < uints.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, uints[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, uints[i], escape: true); for (int i = 0; i < doubles.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, doubles[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, doubles[i], escape: true); for (int i = 0; i < longs.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, longs[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, longs[i], escape: true); for (int i = 0; i < ulongs.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, ulongs[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, ulongs[i], escape: true); for (int i = 0; i < decimals.Length; i++) - jsonUtf8.WriteNumber(keyUtf16, decimals[i], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf16, decimals[i], escape: true); + jsonUtf8.WriteStartArray(keyUtf16, escape: true); break; case 5: for (int i = 0; i < floats.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, floats[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, floats[i], escape: true); for (int i = 0; i < ints.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, ints[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, ints[i], escape: true); for (int i = 0; i < uints.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, uints[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, uints[i], escape: true); for (int i = 0; i < doubles.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, doubles[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, doubles[i], escape: true); for (int i = 0; i < longs.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, longs[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, longs[i], escape: true); for (int i = 0; i < ulongs.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, ulongs[i], suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, ulongs[i], escape: true); for (int i = 0; i < decimals.Length; i++) - jsonUtf8.WriteNumber(keyUtf8, decimals[i], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + jsonUtf8.WriteNumber(keyUtf8, decimals[i], escape: true); + jsonUtf8.WriteStartArray(keyUtf8, escape: true); break; } @@ -2574,33 +2574,33 @@ public void WriteGuidsValue(bool formatted, bool skipValidation, string keyStrin { case 0: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyString, guids[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + jsonUtf8.WriteString(keyString, guids[j], escape: false); + jsonUtf8.WriteStartArray(keyString, escape: false); break; case 1: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf16, guids[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + jsonUtf8.WriteString(keyUtf16, guids[j], escape: false); + jsonUtf8.WriteStartArray(keyUtf16, escape: false); break; case 2: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf8, guids[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + jsonUtf8.WriteString(keyUtf8, guids[j], escape: false); + jsonUtf8.WriteStartArray(keyUtf8, escape: false); break; case 3: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyString, guids[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + jsonUtf8.WriteString(keyString, guids[j], escape: true); + jsonUtf8.WriteStartArray(keyString, escape: true); break; case 4: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf16, guids[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + jsonUtf8.WriteString(keyUtf16, guids[j], escape: true); + jsonUtf8.WriteStartArray(keyUtf16, escape: true); break; case 5: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf8, guids[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + jsonUtf8.WriteString(keyUtf8, guids[j], escape: true); + jsonUtf8.WriteStartArray(keyUtf8, escape: true); break; } @@ -2667,33 +2667,33 @@ public void WriteDateTimesValue(bool formatted, bool skipValidation, string keyS { case 0: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + jsonUtf8.WriteString(keyString, dates[j], escape: false); + jsonUtf8.WriteStartArray(keyString, escape: false); break; case 1: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + jsonUtf8.WriteString(keyUtf16, dates[j], escape: false); + jsonUtf8.WriteStartArray(keyUtf16, escape: false); break; case 2: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + jsonUtf8.WriteString(keyUtf8, dates[j], escape: false); + jsonUtf8.WriteStartArray(keyUtf8, escape: false); break; case 3: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + jsonUtf8.WriteString(keyString, dates[j], escape: true); + jsonUtf8.WriteStartArray(keyString, escape: true); break; case 4: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + jsonUtf8.WriteString(keyUtf16, dates[j], escape: true); + jsonUtf8.WriteStartArray(keyUtf16, escape: true); break; case 5: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + jsonUtf8.WriteString(keyUtf8, dates[j], escape: true); + jsonUtf8.WriteStartArray(keyUtf8, escape: true); break; } @@ -2760,33 +2760,33 @@ public void WriteDateTimeOffsetsValue(bool formatted, bool skipValidation, strin { case 0: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: true); + jsonUtf8.WriteString(keyString, dates[j], escape: false); + jsonUtf8.WriteStartArray(keyString, escape: false); break; case 1: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: true); + jsonUtf8.WriteString(keyUtf16, dates[j], escape: false); + jsonUtf8.WriteStartArray(keyUtf16, escape: false); break; case 2: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: true); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: true); + jsonUtf8.WriteString(keyUtf8, dates[j], escape: false); + jsonUtf8.WriteStartArray(keyUtf8, escape: false); break; case 3: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyString, dates[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyString, suppressEscaping: false); + jsonUtf8.WriteString(keyString, dates[j], escape: true); + jsonUtf8.WriteStartArray(keyString, escape: true); break; case 4: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf16, dates[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf16, suppressEscaping: false); + jsonUtf8.WriteString(keyUtf16, dates[j], escape: true); + jsonUtf8.WriteStartArray(keyUtf16, escape: true); break; case 5: for (int j = 0; j < numberOfItems; j++) - jsonUtf8.WriteString(keyUtf8, dates[j], suppressEscaping: false); - jsonUtf8.WriteStartArray(keyUtf8, suppressEscaping: false); + jsonUtf8.WriteString(keyUtf8, dates[j], escape: true); + jsonUtf8.WriteStartArray(keyUtf8, escape: true); break; } @@ -2830,7 +2830,7 @@ public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartObject(); - jsonUtf8.WriteString(key, DateTime.Now, suppressEscaping: true); + jsonUtf8.WriteString(key, DateTime.Now, escape: false); Assert.True(false, $"Expected ArgumentException for data too large wasn't thrown. KeyLength: {key.Length}"); } catch (ArgumentException) { } @@ -2838,7 +2838,7 @@ public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) try { jsonUtf8.WriteStartArray(); - jsonUtf8.WriteStringValue(value, suppressEscaping: true); + jsonUtf8.WriteStringValue(value, escape: false); Assert.True(false, $"Expected ArgumentException for data too large wasn't thrown. ValueLength: {value.Length}"); } catch (ArgumentException) { } @@ -2876,7 +2876,7 @@ private static void WriteTooLargeHelper(JsonWriterState state, ReadOnlySpan Date: Mon, 14 Jan 2019 17:34:23 -0800 Subject: [PATCH 29/33] Comment cleanup, add debug.asserts, and move transcoding helpers to a separate file. --- .../src/System.Text.Json.csproj | 1 + .../Json/Writer/JsonWriterHelper.Escaping.cs | 9 +- .../Writer/JsonWriterHelper.Transcoding.cs | 334 ++++++++++++++++++ .../Text/Json/Writer/JsonWriterHelper.cs | 322 ----------------- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 9 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 9 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 9 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 9 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 9 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 3 +- ...JsonWriter.WriteProperties.SignedNumber.cs | 15 +- ...onWriter.WriteProperties.UnsignedNumber.cs | 15 +- .../Utf8JsonWriter.WriteValues.DateTime.cs | 2 +- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 2 +- .../Utf8JsonWriter.WriteValues.Decimal.cs | 2 +- .../Utf8JsonWriter.WriteValues.Double.cs | 2 +- .../Utf8JsonWriter.WriteValues.Float.cs | 2 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 4 +- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 4 +- 19 files changed, 393 insertions(+), 369 deletions(-) create mode 100644 src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Transcoding.cs diff --git a/src/System.Text.Json/src/System.Text.Json.csproj b/src/System.Text.Json/src/System.Text.Json.csproj index f0d0617ce453..6d774c2bcc32 100644 --- a/src/System.Text.Json/src/System.Text.Json.csproj +++ b/src/System.Text.Json/src/System.Text.Json.csproj @@ -23,6 +23,7 @@ + diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index a26bb3f21853..4989b21ef223 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -145,7 +145,8 @@ private static int EscapeNextBytes(ReadOnlySpan value, Span destinat destination[written++] = (byte)'u'; if (scalar < JsonConstants.UnicodePlane01StartValue) { - Utf8Formatter.TryFormat(scalar, destination.Slice(written), out int bytesWritten, format: s_hexStandardFormat); + bool result = Utf8Formatter.TryFormat(scalar, destination.Slice(written), out int bytesWritten, format: s_hexStandardFormat); + Debug.Assert(result); Debug.Assert(bytesWritten == 4); written += bytesWritten; } @@ -157,12 +158,14 @@ private static int EscapeNextBytes(ReadOnlySpan value, Span destinat int quotient = Math.DivRem(scalar - JsonConstants.UnicodePlane01StartValue, JsonConstants.ShiftRightBy10, out int remainder); int firstChar = quotient + JsonConstants.HighSurrogateStartValue; int nextChar = remainder + JsonConstants.LowSurrogateStartValue; - Utf8Formatter.TryFormat(firstChar, destination.Slice(written), out int bytesWritten, format: s_hexStandardFormat); + bool result = Utf8Formatter.TryFormat(firstChar, destination.Slice(written), out int bytesWritten, format: s_hexStandardFormat); + Debug.Assert(result); Debug.Assert(bytesWritten == 4); written += bytesWritten; destination[written++] = (byte)'\\'; destination[written++] = (byte)'u'; - Utf8Formatter.TryFormat(nextChar, destination.Slice(written), out bytesWritten, format: s_hexStandardFormat); + result = Utf8Formatter.TryFormat(nextChar, destination.Slice(written), out bytesWritten, format: s_hexStandardFormat); + Debug.Assert(result); Debug.Assert(bytesWritten == 4); written += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Transcoding.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Transcoding.cs new file mode 100644 index 000000000000..9285ee07a5be --- /dev/null +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Transcoding.cs @@ -0,0 +1,334 @@ +// 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. + +using System.Buffers; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Text.Json +{ + internal static partial class JsonWriterHelper + { + // TODO: Replace this with publicly shipping implementation: https://github.com/dotnet/corefx/issues/34094 + /// + /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes. + /// + /// This method will consume as many of the input bytes as possible. + /// + /// On successful exit, the entire input was consumed and encoded successfully. In this case, will be + /// equal to the length of the and will equal the total number of bytes written to + /// the . + /// + /// A span containing a sequence of UTF-16 bytes. + /// A span to write the UTF-8 bytes into. + /// On exit, contains the number of bytes that were consumed from the . + /// On exit, contains the number of bytes written to + /// A value representing the state of the conversion. + public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span utf8Destination, out int bytesConsumed, out int bytesWritten) + { + // + // + // KEEP THIS IMPLEMENTATION IN SYNC WITH https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs#L841 + // + // + fixed (byte* chars = &MemoryMarshal.GetReference(utf16Source)) + fixed (byte* bytes = &MemoryMarshal.GetReference(utf8Destination)) + { + char* pSrc = (char*)chars; + byte* pTarget = bytes; + + char* pEnd = (char*)(chars + utf16Source.Length); + byte* pAllocatedBufferEnd = pTarget + utf8Destination.Length; + + // assume that JIT will enregister pSrc, pTarget and ch + + // Entering the fast encoding loop incurs some overhead that does not get amortized for small + // number of characters, and the slow encoding loop typically ends up running for the last few + // characters anyway since the fast encoding loop needs 5 characters on input at least. + // Thus don't use the fast decoding loop at all if we don't have enough characters. The threashold + // was choosen based on performance testing. + // Note that if we don't have enough bytes, pStop will prevent us from entering the fast loop. + while (pEnd - pSrc > 13) + { + // we need at least 1 byte per character, but Convert might allow us to convert + // only part of the input, so try as much as we can. Reduce charCount if necessary + int available = Math.Min(PtrDiff(pEnd, pSrc), PtrDiff(pAllocatedBufferEnd, pTarget)); + + // FASTLOOP: + // - optimistic range checks + // - fallbacks to the slow loop for all special cases, exception throwing, etc. + + // To compute the upper bound, assume that all characters are ASCII characters at this point, + // the boundary will be decreased for every non-ASCII character we encounter + // Also, we need 5 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates + // If there aren't enough bytes for the output, then pStop will be <= pSrc and will bypass the loop. + char* pStop = pSrc + available - 5; + if (pSrc >= pStop) + break; + + do + { + int ch = *pSrc; + pSrc++; + + if (ch > 0x7F) + { + goto LongCode; + } + *pTarget = (byte)ch; + pTarget++; + + // get pSrc aligned + if ((unchecked((int)pSrc) & 0x2) != 0) + { + ch = *pSrc; + pSrc++; + if (ch > 0x7F) + { + goto LongCode; + } + *pTarget = (byte)ch; + pTarget++; + } + + // Run 4 characters at a time! + while (pSrc < pStop) + { + ch = *(int*)pSrc; + int chc = *(int*)(pSrc + 2); + if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) + { + goto LongCodeWithMask; + } + + // Unfortunately, this is endianess sensitive +#if BIGENDIAN + *pTarget = (byte)(ch >> 16); + *(pTarget + 1) = (byte)ch; + pSrc += 4; + *(pTarget + 2) = (byte)(chc >> 16); + *(pTarget + 3) = (byte)chc; + pTarget += 4; +#else // BIGENDIAN + *pTarget = (byte)ch; + *(pTarget + 1) = (byte)(ch >> 16); + pSrc += 4; + *(pTarget + 2) = (byte)chc; + *(pTarget + 3) = (byte)(chc >> 16); + pTarget += 4; +#endif // BIGENDIAN + } + continue; + + LongCodeWithMask: +#if BIGENDIAN + // be careful about the sign extension + ch = (int)(((uint)ch) >> 16); +#else // BIGENDIAN + ch = (char)ch; +#endif // BIGENDIAN + pSrc++; + + if (ch > 0x7F) + { + goto LongCode; + } + *pTarget = (byte)ch; + pTarget++; + continue; + + LongCode: + // use separate helper variables for slow and fast loop so that the jit optimizations + // won't get confused about the variable lifetimes + int chd; + if (ch <= 0x7FF) + { + // 2 byte encoding + chd = unchecked((sbyte)0xC0) | (ch >> 6); + } + else + { + // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) + if (!IsInRangeInclusive(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + // 3 byte encoding + chd = unchecked((sbyte)0xE0) | (ch >> 12); + } + else + { + // 4 byte encoding - high surrogate + low surrogate + // if (!IsHighSurrogate(ch)) + if (ch > JsonConstants.HighSurrogateEnd) + { + // low without high -> bad + goto InvalidData; + } + + chd = *pSrc; + + // if (!IsLowSurrogate(chd)) { + if (!IsInRangeInclusive(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + // high not followed by low -> bad + goto InvalidData; + } + + pSrc++; + + ch = chd + (ch << 10) + + (0x10000 + - JsonConstants.LowSurrogateStart + - (JsonConstants.HighSurrogateStart << 10)); + + *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18)); + // pStop - this byte is compensated by the second surrogate character + // 2 input chars require 4 output bytes. 2 have been anticipated already + // and 2 more will be accounted for by the 2 pStop-- calls below. + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F; + } + *pTarget = (byte)chd; + pStop--; // 3 byte sequence for 1 char, so need pStop-- and the one below too. + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F; + } + *pTarget = (byte)chd; + pStop--; // 2 byte sequence for 1 char so need pStop--. + + *(pTarget + 1) = (byte)(unchecked((sbyte)0x80) | ch & 0x3F); + // pStop - this byte is already included + + pTarget += 2; + } + while (pSrc < pStop); + + Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd"); + } + + while (pSrc < pEnd) + { + // SLOWLOOP: does all range checks, handles all special cases, but it is slow + + // read next char. The JIT optimization seems to be getting confused when + // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead + int ch = *pSrc; + pSrc++; + + if (ch <= 0x7F) + { + if (pAllocatedBufferEnd - pTarget <= 0) + goto DestinationFull; + + *pTarget = (byte)ch; + pTarget++; + continue; + } + + int chd; + if (ch <= 0x7FF) + { + if (pAllocatedBufferEnd - pTarget <= 1) + goto DestinationFull; + + // 2 byte encoding + chd = unchecked((sbyte)0xC0) | (ch >> 6); + } + else + { + // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) + if (!IsInRangeInclusive(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + if (pAllocatedBufferEnd - pTarget <= 2) + goto DestinationFull; + + // 3 byte encoding + chd = unchecked((sbyte)0xE0) | (ch >> 12); + } + else + { + if (pAllocatedBufferEnd - pTarget <= 3) + goto DestinationFull; + + // 4 byte encoding - high surrogate + low surrogate + // if (!IsHighSurrogate(ch)) + if (ch > JsonConstants.HighSurrogateEnd) + { + // low without high -> bad + goto InvalidData; + } + + if (pSrc >= pEnd) + goto NeedMoreData; + + chd = *pSrc; + + // if (!IsLowSurrogate(chd)) { + if (!IsInRangeInclusive(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) + { + // high not followed by low -> bad + goto InvalidData; + } + + pSrc++; + + ch = chd + (ch << 10) + + (0x10000 + - JsonConstants.LowSurrogateStart + - (JsonConstants.HighSurrogateStart << 10)); + + *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18)); + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F; + } + *pTarget = (byte)chd; + pTarget++; + + chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F; + } + + *pTarget = (byte)chd; + *(pTarget + 1) = (byte)(unchecked((sbyte)0x80) | ch & 0x3F); + + pTarget += 2; + } + + bytesConsumed = (int)((byte*)pSrc - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.Done; + + InvalidData: + bytesConsumed = (int)((byte*)(pSrc - 1) - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.InvalidData; + + DestinationFull: + bytesConsumed = (int)((byte*)(pSrc - 1) - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.DestinationTooSmall; + + NeedMoreData: + bytesConsumed = (int)((byte*)(pSrc - 1) - chars); + bytesWritten = (int)(pTarget - bytes); + return OperationStatus.NeedMoreData; + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private unsafe static int PtrDiff(char* a, char* b) + { + return (int)(((uint)((byte*)a - (byte*)b)) >> 1); + } + + // byte* flavor just for parity + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private unsafe static int PtrDiff(byte* a, byte* b) + { + return (int)(a - b); + } + } +} diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 01fdea2e6dcc..962731efa62b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -2,10 +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.Buffers; using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; namespace System.Text.Json { @@ -117,325 +115,5 @@ public static void ValidatePropertyAndValue(ReadOnlySpan propertyName, Rea if (propertyName.Length > JsonConstants.MaxCharacterTokenSize || value.Length > JsonConstants.MaxCharacterTokenSize) ThrowHelper.ThrowArgumentException(propertyName, value); } - - // TODO: Replace this with publicly shipping implementation: https://github.com/dotnet/corefx/issues/34094 - /// - /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes. - /// - /// This method will consume as many of the input bytes as possible. - /// - /// On successful exit, the entire input was consumed and encoded successfully. In this case, will be - /// equal to the length of the and will equal the total number of bytes written to - /// the . - /// - /// A span containing a sequence of UTF-16 bytes. - /// A span to write the UTF-8 bytes into. - /// On exit, contains the number of bytes that were consumed from the . - /// On exit, contains the number of bytes written to - /// A value representing the state of the conversion. - public unsafe static OperationStatus ToUtf8(ReadOnlySpan utf16Source, Span utf8Destination, out int bytesConsumed, out int bytesWritten) - { - // - // - // KEEP THIS IMPLEMENTATION IN SYNC WITH https://github.com/dotnet/coreclr/blob/master/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs#L841 - // - // - fixed (byte* chars = &MemoryMarshal.GetReference(utf16Source)) - fixed (byte* bytes = &MemoryMarshal.GetReference(utf8Destination)) - { - char* pSrc = (char*)chars; - byte* pTarget = bytes; - - char* pEnd = (char*)(chars + utf16Source.Length); - byte* pAllocatedBufferEnd = pTarget + utf8Destination.Length; - - // assume that JIT will enregister pSrc, pTarget and ch - - // Entering the fast encoding loop incurs some overhead that does not get amortized for small - // number of characters, and the slow encoding loop typically ends up running for the last few - // characters anyway since the fast encoding loop needs 5 characters on input at least. - // Thus don't use the fast decoding loop at all if we don't have enough characters. The threashold - // was choosen based on performance testing. - // Note that if we don't have enough bytes, pStop will prevent us from entering the fast loop. - while (pEnd - pSrc > 13) - { - // we need at least 1 byte per character, but Convert might allow us to convert - // only part of the input, so try as much as we can. Reduce charCount if necessary - int available = Math.Min(PtrDiff(pEnd, pSrc), PtrDiff(pAllocatedBufferEnd, pTarget)); - - // FASTLOOP: - // - optimistic range checks - // - fallbacks to the slow loop for all special cases, exception throwing, etc. - - // To compute the upper bound, assume that all characters are ASCII characters at this point, - // the boundary will be decreased for every non-ASCII character we encounter - // Also, we need 5 chars reserve for the unrolled ansi decoding loop and for decoding of surrogates - // If there aren't enough bytes for the output, then pStop will be <= pSrc and will bypass the loop. - char* pStop = pSrc + available - 5; - if (pSrc >= pStop) - break; - - do - { - int ch = *pSrc; - pSrc++; - - if (ch > 0x7F) - { - goto LongCode; - } - *pTarget = (byte)ch; - pTarget++; - - // get pSrc aligned - if ((unchecked((int)pSrc) & 0x2) != 0) - { - ch = *pSrc; - pSrc++; - if (ch > 0x7F) - { - goto LongCode; - } - *pTarget = (byte)ch; - pTarget++; - } - - // Run 4 characters at a time! - while (pSrc < pStop) - { - ch = *(int*)pSrc; - int chc = *(int*)(pSrc + 2); - if (((ch | chc) & unchecked((int)0xFF80FF80)) != 0) - { - goto LongCodeWithMask; - } - - // Unfortunately, this is endianess sensitive -#if BIGENDIAN - *pTarget = (byte)(ch >> 16); - *(pTarget + 1) = (byte)ch; - pSrc += 4; - *(pTarget + 2) = (byte)(chc >> 16); - *(pTarget + 3) = (byte)chc; - pTarget += 4; -#else // BIGENDIAN - *pTarget = (byte)ch; - *(pTarget + 1) = (byte)(ch >> 16); - pSrc += 4; - *(pTarget + 2) = (byte)chc; - *(pTarget + 3) = (byte)(chc >> 16); - pTarget += 4; -#endif // BIGENDIAN - } - continue; - - LongCodeWithMask: -#if BIGENDIAN - // be careful about the sign extension - ch = (int)(((uint)ch) >> 16); -#else // BIGENDIAN - ch = (char)ch; -#endif // BIGENDIAN - pSrc++; - - if (ch > 0x7F) - { - goto LongCode; - } - *pTarget = (byte)ch; - pTarget++; - continue; - - LongCode: - // use separate helper variables for slow and fast loop so that the jit optimizations - // won't get confused about the variable lifetimes - int chd; - if (ch <= 0x7FF) - { - // 2 byte encoding - chd = unchecked((sbyte)0xC0) | (ch >> 6); - } - else - { - // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) - if (!IsInRangeInclusive(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) - { - // 3 byte encoding - chd = unchecked((sbyte)0xE0) | (ch >> 12); - } - else - { - // 4 byte encoding - high surrogate + low surrogate - // if (!IsHighSurrogate(ch)) - if (ch > JsonConstants.HighSurrogateEnd) - { - // low without high -> bad - goto InvalidData; - } - - chd = *pSrc; - - // if (!IsLowSurrogate(chd)) { - if (!IsInRangeInclusive(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) - { - // high not followed by low -> bad - goto InvalidData; - } - - pSrc++; - - ch = chd + (ch << 10) + - (0x10000 - - JsonConstants.LowSurrogateStart - - (JsonConstants.HighSurrogateStart << 10)); - - *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18)); - // pStop - this byte is compensated by the second surrogate character - // 2 input chars require 4 output bytes. 2 have been anticipated already - // and 2 more will be accounted for by the 2 pStop-- calls below. - pTarget++; - - chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F; - } - *pTarget = (byte)chd; - pStop--; // 3 byte sequence for 1 char, so need pStop-- and the one below too. - pTarget++; - - chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F; - } - *pTarget = (byte)chd; - pStop--; // 2 byte sequence for 1 char so need pStop--. - - *(pTarget + 1) = (byte)(unchecked((sbyte)0x80) | ch & 0x3F); - // pStop - this byte is already included - - pTarget += 2; - } - while (pSrc < pStop); - - Debug.Assert(pTarget <= pAllocatedBufferEnd, "[UTF8Encoding.GetBytes]pTarget <= pAllocatedBufferEnd"); - } - - while (pSrc < pEnd) - { - // SLOWLOOP: does all range checks, handles all special cases, but it is slow - - // read next char. The JIT optimization seems to be getting confused when - // compiling "ch = *pSrc++;", so rather use "ch = *pSrc; pSrc++;" instead - int ch = *pSrc; - pSrc++; - - if (ch <= 0x7F) - { - if (pAllocatedBufferEnd - pTarget <= 0) - goto DestinationFull; - - *pTarget = (byte)ch; - pTarget++; - continue; - } - - int chd; - if (ch <= 0x7FF) - { - if (pAllocatedBufferEnd - pTarget <= 1) - goto DestinationFull; - - // 2 byte encoding - chd = unchecked((sbyte)0xC0) | (ch >> 6); - } - else - { - // if (!IsLowSurrogate(ch) && !IsHighSurrogate(ch)) - if (!IsInRangeInclusive(ch, JsonConstants.HighSurrogateStart, JsonConstants.LowSurrogateEnd)) - { - if (pAllocatedBufferEnd - pTarget <= 2) - goto DestinationFull; - - // 3 byte encoding - chd = unchecked((sbyte)0xE0) | (ch >> 12); - } - else - { - if (pAllocatedBufferEnd - pTarget <= 3) - goto DestinationFull; - - // 4 byte encoding - high surrogate + low surrogate - // if (!IsHighSurrogate(ch)) - if (ch > JsonConstants.HighSurrogateEnd) - { - // low without high -> bad - goto InvalidData; - } - - if (pSrc >= pEnd) - goto NeedMoreData; - - chd = *pSrc; - - // if (!IsLowSurrogate(chd)) { - if (!IsInRangeInclusive(chd, JsonConstants.LowSurrogateStart, JsonConstants.LowSurrogateEnd)) - { - // high not followed by low -> bad - goto InvalidData; - } - - pSrc++; - - ch = chd + (ch << 10) + - (0x10000 - - JsonConstants.LowSurrogateStart - - (JsonConstants.HighSurrogateStart << 10)); - - *pTarget = (byte)(unchecked((sbyte)0xF0) | (ch >> 18)); - pTarget++; - - chd = unchecked((sbyte)0x80) | (ch >> 12) & 0x3F; - } - *pTarget = (byte)chd; - pTarget++; - - chd = unchecked((sbyte)0x80) | (ch >> 6) & 0x3F; - } - - *pTarget = (byte)chd; - *(pTarget + 1) = (byte)(unchecked((sbyte)0x80) | ch & 0x3F); - - pTarget += 2; - } - - bytesConsumed = (int)((byte*)pSrc - chars); - bytesWritten = (int)(pTarget - bytes); - return OperationStatus.Done; - - InvalidData: - bytesConsumed = (int)((byte*)(pSrc - 1) - chars); - bytesWritten = (int)(pTarget - bytes); - return OperationStatus.InvalidData; - - DestinationFull: - bytesConsumed = (int)((byte*)(pSrc - 1) - chars); - bytesWritten = (int)(pTarget - bytes); - return OperationStatus.DestinationTooSmall; - - NeedMoreData: - bytesConsumed = (int)((byte*)(pSrc - 1) - chars); - bytesWritten = (int)(pTarget - bytes); - return OperationStatus.NeedMoreData; - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static int PtrDiff(char* a, char* b) - { - return (int)(((uint)((byte*)a - (byte*)b)) >> 1); - } - - // byte* flavor just for parity - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe static int PtrDiff(byte* a, byte* b) - { - return (int)(a - b); - } } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index c984770a202c..5e7eb2fe7eee 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000. /// public void WriteString(string propertyName, DateTime value, bool escape = true) => WriteString(propertyName.AsSpan(), value, escape); @@ -41,7 +41,7 @@ public void WriteString(string propertyName, DateTime value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000. /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool escape = true) { @@ -73,7 +73,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool es /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000. /// public void WriteString(ReadOnlySpan propertyName, DateTime value, bool escape = true) { @@ -276,7 +276,8 @@ private void FormatLoop(DateTime value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten, s_dateTimeStandardFormat)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDateTimeLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten, s_dateTimeStandardFormat); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten, s_dateTimeStandardFormat); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 5a34b295aa73..906bd98b1c9f 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteString(string propertyName, DateTimeOffset value, bool escape = true) => WriteString(propertyName.AsSpan(), value, escape); @@ -41,7 +41,7 @@ public void WriteString(string propertyName, DateTimeOffset value, bool escape = /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool escape = true) { @@ -73,7 +73,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool escape = true) { @@ -274,7 +274,8 @@ private void FormatLoop(DateTimeOffset value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten, s_dateTimeStandardFormat)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDateTimeOffsetLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten, s_dateTimeStandardFormat); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten, s_dateTimeStandardFormat); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 52657a571420..36a611bf2fc4 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(string propertyName, decimal value, bool escape = true) => WriteNumber(propertyName.AsSpan(), value, escape); @@ -41,7 +41,7 @@ public void WriteNumber(string propertyName, decimal value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool escape = true) { @@ -73,7 +73,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool esc /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool escape = true) { @@ -257,7 +257,8 @@ private void WriteNumberValueFormatLoop(decimal value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDecimalLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 4c47c4eaa657..c0621f0af1fd 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(string propertyName, double value, bool escape = true) => WriteNumber(propertyName.AsSpan(), value, escape); @@ -41,7 +41,7 @@ public void WriteNumber(string propertyName, double value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool escape = true) { @@ -74,7 +74,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool esca /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(ReadOnlySpan propertyName, double value, bool escape = true) { @@ -259,7 +259,8 @@ private void WriteNumberValueFormatLoop(double value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatDoubleLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 9cbe347490e3..48ec6d17a329 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(string propertyName, float value, bool escape = true) => WriteNumber(propertyName.AsSpan(), value, escape); @@ -41,7 +41,7 @@ public void WriteNumber(string propertyName, float value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool escape = true) { @@ -74,7 +74,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool escap /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumber(ReadOnlySpan propertyName, float value, bool escape = true) { @@ -259,7 +259,8 @@ private void WriteNumberValueFormatLoop(float value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatSingleLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 1bd64e6322da..c6feb72f1b9e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -276,7 +276,8 @@ private void FormatLoop(Guid value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatGuidLength); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index a3703bb9a9a9..05e16eda2fb1 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumber(string propertyName, long value, bool escape = true) => WriteNumber(propertyName.AsSpan(), value, escape); @@ -41,7 +41,7 @@ public void WriteNumber(string propertyName, long value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape = true) { @@ -73,7 +73,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape = true) { @@ -105,7 +105,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumber(string propertyName, int value, bool escape = true) => WriteNumber(propertyName.AsSpan(), (long)value, escape); @@ -123,7 +123,7 @@ public void WriteNumber(string propertyName, int value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape = true) => WriteNumber(propertyName, (long)value, escape); @@ -141,7 +141,7 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape = true) => WriteNumber(propertyName, (long)value, escape); @@ -311,7 +311,8 @@ private void WriteNumberValueFormatLoop(long value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatInt64Length); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index 124eddc21c84..f3b241aafefa 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -23,7 +23,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumber(string propertyName, ulong value, bool escape = true) @@ -42,7 +42,7 @@ public void WriteNumber(string propertyName, ulong value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escape = true) @@ -75,7 +75,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escap /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escape = true) @@ -108,7 +108,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escap /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumber(string propertyName, uint value, bool escape = true) @@ -127,7 +127,7 @@ public void WriteNumber(string propertyName, uint value, bool escape = true) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape = true) @@ -146,7 +146,7 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape = true) @@ -317,7 +317,8 @@ private void WriteNumberValueFormatLoop(ulong value, ref int idx) if (!Utf8Formatter.TryFormat(value, _buffer.Slice(idx), out int bytesWritten)) { AdvanceAndGrow(ref idx, JsonConstants.MaximumFormatUInt64Length); - Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + bool result = Utf8Formatter.TryFormat(value, _buffer, out bytesWritten); + Debug.Assert(result); } idx += bytesWritten; } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index 4b1fa7363931..d68d46144e85 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000. /// public void WriteStringValue(DateTime value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 8cd8a4fca8bb..3edbf641d7e5 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the round-trippable 'O' , for example: 2017-06-12T05:30:45.7680000-07:00. + /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000-07:00. /// public void WriteStringValue(DateTimeOffset value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index 382e5be504b7..305cf852ec8a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumberValue(decimal value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 8c19b067dda1..54fc04680c8b 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumberValue(double value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index e2dea1d2384d..ad8dd12cc77a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G') + /// Writes the using the default (i.e. 'G'). /// public void WriteNumberValue(float value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 7b0694c5da0e..d32224db5f0e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumberValue(int value) => WriteNumberValue((long)value); @@ -29,7 +29,7 @@ public void WriteNumberValue(int value) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// public void WriteNumberValue(long value) { diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 335245bbde4f..107bc0ad50b2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -16,7 +16,7 @@ public ref partial struct Utf8JsonWriter /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumberValue(uint value) @@ -30,7 +30,7 @@ public void WriteNumberValue(uint value) /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// /// - /// Writes the using the default (i.e. 'G'), for example: 32767 + /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] public void WriteNumberValue(ulong value) From 56382dbd29b94272e4dc24082f75bcd3a7ce8779 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 14 Jan 2019 18:21:55 -0800 Subject: [PATCH 30/33] Increase the deicmal max size to account for sign and add tests. --- .../src/System/Text/Json/JsonConstants.cs | 2 +- .../tests/Utf8JsonWriterTests.cs | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 787d73a21d46..c56f8d91d15c 100644 --- a/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -50,7 +50,7 @@ internal static class JsonConstants public const int MaximumFormatUInt64Length = 20; // i.e. 18446744073709551615 public const int MaximumFormatDoubleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. public const int MaximumFormatSingleLength = 128; // default (i.e. 'G'), using 128 (rather than say 32) to be future-proof. - public const int MaximumFormatDecimalLength = 29; // default (i.e. 'G') + public const int MaximumFormatDecimalLength = 31; // default (i.e. 'G') public const int MaximumFormatGuidLength = 36; // default (i.e. 'D'), 8 + 4 + 4 + 4 + 12 + 4 for the hyphens (e.g. 094ffa0a-0442-494d-b452-04003fa755cc) public const int MaximumFormatDateTimeLength = 27; // StandardFormat 'O', e.g. 2017-06-12T05:30:45.7680000 public const int MaximumFormatDateTimeOffsetLength = 33; // StandardFormat 'O', e.g. 2017-06-12T05:30:45.7680000-07:00 diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index e3233cccadaa..90ed4cc18c51 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -199,6 +199,98 @@ public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValida Assert.Equal($"\"{date.ToString("O")}\"", actualStr); } + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) + { + var random = new Random(42); + + for (int i = 0; i < 1_000; i++) + { + var output = new FixedSizedBufferWriter(31); + decimal value = JsonTestHelper.NextDecimal(random, 78E14, -78E14); + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteNumberValue(value); + + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.True(output.Formatted.Length <= 31); + Assert.Equal(decimal.Parse(actualStr), value); + } + + for (int i = 0; i < 1_000; i++) + { + var output = new FixedSizedBufferWriter(31); + decimal value = JsonTestHelper.NextDecimal(random, 1_000_000, -1_000_000); + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteNumberValue(value); + + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.True(output.Formatted.Length <= 31); + Assert.Equal(decimal.Parse(actualStr), value); + } + + { + var output = new FixedSizedBufferWriter(31); + decimal value = 9999999999999999999999999999m; + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteNumberValue(value); + + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.Equal(value.ToString().Length, output.Formatted.Length); + Assert.Equal(decimal.Parse(actualStr), value); + } + + { + var output = new FixedSizedBufferWriter(31); + decimal value = -9999999999999999999999999999m; + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteNumberValue(value); + + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.Equal(value.ToString().Length, output.Formatted.Length); + Assert.Equal(decimal.Parse(actualStr), value); + } + + { + var output = new FixedSizedBufferWriter(30); + decimal value = -0.9999999999999999999999999999m; + var state = new JsonWriterState(options: new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }); + var jsonUtf8 = new Utf8JsonWriter(output, state); + + try + { + jsonUtf8.WriteNumberValue(value); + Assert.True(false, "Expected ArgumentException to be thrown when IBufferWriter doesn't have enough space."); + } + catch (ArgumentException) { } + + output = new FixedSizedBufferWriter(31); + jsonUtf8 = new Utf8JsonWriter(output, state); + jsonUtf8.WriteNumberValue(value); + + jsonUtf8.Flush(); + string actualStr = Encoding.UTF8.GetString(output.Formatted); + + Assert.Equal(value.ToString().Length, output.Formatted.Length); + Assert.Equal(decimal.Parse(actualStr), value); + } + } + [Theory] [InlineData(true, true)] [InlineData(true, false)] From 2900bc59aab8d42ffab385c82d8ec9ef2e27f95a Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 14 Jan 2019 18:40:53 -0800 Subject: [PATCH 31/33] Rename ROS property name and value params to include utf8 in the name. --- src/System.Text.Json/ref/System.Text.Json.cs | 42 ++--- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 34 ++-- ...onWriter.WriteProperties.DateTimeOffset.cs | 34 ++-- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 34 ++-- .../Utf8JsonWriter.WriteProperties.Double.cs | 34 ++-- .../Utf8JsonWriter.WriteProperties.Float.cs | 28 +-- .../Utf8JsonWriter.WriteProperties.Guid.cs | 34 ++-- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 6 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 44 ++--- ...JsonWriter.WriteProperties.SignedNumber.cs | 40 ++--- .../Utf8JsonWriter.WriteProperties.String.cs | 168 +++++++++--------- ...onWriter.WriteProperties.UnsignedNumber.cs | 40 ++--- .../Utf8JsonWriter.WriteValues.Comment.cs | 34 ++-- .../Utf8JsonWriter.WriteValues.Literal.cs | 14 +- .../Utf8JsonWriter.WriteValues.String.cs | 34 ++-- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 44 ++--- 16 files changed, 332 insertions(+), 332 deletions(-) diff --git a/src/System.Text.Json/ref/System.Text.Json.cs b/src/System.Text.Json/ref/System.Text.Json.cs index d5e25ac396a2..25aa94e83bc6 100644 --- a/src/System.Text.Json/ref/System.Text.Json.cs +++ b/src/System.Text.Json/ref/System.Text.Json.cs @@ -94,28 +94,28 @@ public ref partial struct Utf8JsonWriter public int CurrentDepth { get { throw null; } } public void Flush(bool isFinalBlock = true) { } public System.Text.Json.JsonWriterState GetCurrentState() { throw null; } - public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool escape = true) { } + public void WriteBoolean(System.ReadOnlySpan utf8PropertyName, bool value, bool escape = true) { } public void WriteBoolean(System.ReadOnlySpan propertyName, bool value, bool escape = true) { } public void WriteBoolean(string propertyName, bool value, bool escape = true) { } public void WriteBooleanValue(bool value) { } - public void WriteCommentValue(System.ReadOnlySpan value, bool escape = true) { } + public void WriteCommentValue(System.ReadOnlySpan utf8Value, bool escape = true) { } public void WriteCommentValue(System.ReadOnlySpan value, bool escape = true) { } public void WriteCommentValue(string value, bool escape = true) { } public void WriteEndArray() { } public void WriteEndObject() { } - public void WriteNull(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteNull(System.ReadOnlySpan utf8PropertyName, bool escape = true) { } public void WriteNull(System.ReadOnlySpan propertyName, bool escape = true) { } public void WriteNull(string propertyName, bool escape = true) { } public void WriteNullValue() { } - public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool escape = true) { } - public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool escape = true) { } - public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool escape = true) { } - public void WriteNumber(System.ReadOnlySpan propertyName, long value, bool escape = true) { } - public void WriteNumber(System.ReadOnlySpan propertyName, float value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, decimal value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, double value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, int value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, long value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, float value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(System.ReadOnlySpan propertyName, uint value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, uint value, bool escape = true) { } [System.CLSCompliantAttribute(false)] - public void WriteNumber(System.ReadOnlySpan propertyName, ulong value, bool escape = true) { } + public void WriteNumber(System.ReadOnlySpan utf8PropertyName, ulong value, bool escape = true) { } public void WriteNumber(System.ReadOnlySpan propertyName, decimal value, bool escape = true) { } public void WriteNumber(System.ReadOnlySpan propertyName, double value, bool escape = true) { } public void WriteNumber(System.ReadOnlySpan propertyName, int value, bool escape = true) { } @@ -144,35 +144,35 @@ public void WriteNumberValue(uint value) { } [System.CLSCompliantAttribute(false)] public void WriteNumberValue(ulong value) { } public void WriteStartArray() { } - public void WriteStartArray(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteStartArray(System.ReadOnlySpan utf8PropertyName, bool escape = true) { } public void WriteStartArray(System.ReadOnlySpan propertyName, bool escape = true) { } public void WriteStartArray(string propertyName, bool escape = true) { } public void WriteStartObject() { } - public void WriteStartObject(System.ReadOnlySpan propertyName, bool escape = true) { } + public void WriteStartObject(System.ReadOnlySpan utf8PropertyName, bool escape = true) { } public void WriteStartObject(System.ReadOnlySpan propertyName, bool escape = true) { } public void WriteStartObject(string propertyName, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, string value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, System.DateTime value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, System.DateTimeOffset value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, System.Guid value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, System.ReadOnlySpan utf8Value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan utf8PropertyName, string value, bool escape = true) { } public void WriteString(System.ReadOnlySpan propertyName, System.DateTime value, bool escape = true) { } public void WriteString(System.ReadOnlySpan propertyName, System.DateTimeOffset value, bool escape = true) { } public void WriteString(System.ReadOnlySpan propertyName, System.Guid value, bool escape = true) { } - public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan utf8Value, bool escape = true) { } public void WriteString(System.ReadOnlySpan propertyName, System.ReadOnlySpan value, bool escape = true) { } public void WriteString(System.ReadOnlySpan propertyName, string value, bool escape = true) { } public void WriteString(string propertyName, System.DateTime value, bool escape = true) { } public void WriteString(string propertyName, System.DateTimeOffset value, bool escape = true) { } public void WriteString(string propertyName, System.Guid value, bool escape = true) { } - public void WriteString(string propertyName, System.ReadOnlySpan value, bool escape = true) { } + public void WriteString(string propertyName, System.ReadOnlySpan utf8Value, bool escape = true) { } public void WriteString(string propertyName, System.ReadOnlySpan value, bool escape = true) { } public void WriteString(string propertyName, string value, bool escape = true) { } public void WriteStringValue(System.DateTime value) { } public void WriteStringValue(System.DateTimeOffset value) { } public void WriteStringValue(System.Guid value) { } - public void WriteStringValue(System.ReadOnlySpan value, bool escape = true) { } + public void WriteStringValue(System.ReadOnlySpan utf8Value, bool escape = true) { } public void WriteStringValue(System.ReadOnlySpan value, bool escape = true) { } public void WriteStringValue(string value, bool escape = true) { } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 5e7eb2fe7eee..1e345c625ad4 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -63,7 +63,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool es /// /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -75,17 +75,17 @@ public void WriteString(ReadOnlySpan propertyName, DateTime value, bool es /// /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000. /// - public void WriteString(ReadOnlySpan propertyName, DateTime value, bool escape = true) + public void WriteString(ReadOnlySpan utf8PropertyName, DateTime value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); if (escape) { - WriteStringEscape(propertyName, value); + WriteStringEscape(utf8PropertyName, value); } else { - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -108,19 +108,19 @@ private void WriteStringEscape(ReadOnlySpan propertyName, DateTime value) } } - private void WriteStringEscape(ReadOnlySpan propertyName, DateTime value) + private void WriteStringEscape(ReadOnlySpan utf8PropertyName, DateTime value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteStringEscapeProperty(propertyName, value, propertyIdx); + WriteStringEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); } } @@ -157,14 +157,14 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime } } - private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, DateTime value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -180,7 +180,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -203,16 +203,16 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime valu } } - private void WriteStringByOptions(ReadOnlySpan propertyName, DateTime value) + private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, DateTime value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteStringIndented(propertyName, value); + WriteStringIndented(utf8PropertyName, value); } else { - WriteStringMinimized(propertyName, value); + WriteStringMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 906bd98b1c9f..16d61c6de8d7 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -63,7 +63,7 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -75,17 +75,17 @@ public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, b /// /// Writes the using the round-trippable ('O') , for example: 2017-06-12T05:30:45.7680000-07:00. /// - public void WriteString(ReadOnlySpan propertyName, DateTimeOffset value, bool escape = true) + public void WriteString(ReadOnlySpan utf8PropertyName, DateTimeOffset value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); if (escape) { - WriteStringEscape(propertyName, value); + WriteStringEscape(utf8PropertyName, value); } else { - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -108,19 +108,19 @@ private void WriteStringEscape(ReadOnlySpan propertyName, DateTimeOffset v } } - private void WriteStringEscape(ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringEscape(ReadOnlySpan utf8PropertyName, DateTimeOffset value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteStringEscapeProperty(propertyName, value, propertyIdx); + WriteStringEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); } } @@ -157,14 +157,14 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime } } - private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTimeOffset value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, DateTimeOffset value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -180,7 +180,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, DateTime escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -203,16 +203,16 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffse } } - private void WriteStringByOptions(ReadOnlySpan propertyName, DateTimeOffset value) + private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, DateTimeOffset value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteStringIndented(propertyName, value); + WriteStringIndented(utf8PropertyName, value); } else { - WriteStringMinimized(propertyName, value); + WriteStringMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 36a611bf2fc4..f03e84d07d11 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -63,7 +63,7 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool esc /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -75,17 +75,17 @@ public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool esc /// /// Writes the using the default (i.e. 'G'). /// - public void WriteNumber(ReadOnlySpan propertyName, decimal value, bool escape = true) + public void WriteNumber(ReadOnlySpan utf8PropertyName, decimal value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); if (escape) { - WriteNumberEscape(propertyName, value); + WriteNumberEscape(utf8PropertyName, value); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -108,19 +108,19 @@ private void WriteNumberEscape(ReadOnlySpan propertyName, decimal value) } } - private void WriteNumberEscape(ReadOnlySpan propertyName, decimal value) + private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, decimal value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteNumberEscapeProperty(propertyName, value, propertyIdx); + WriteNumberEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } } @@ -157,14 +157,14 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal } } - private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, decimal value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -180,7 +180,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, decimal escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -203,16 +203,16 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value } } - private void WriteNumberByOptions(ReadOnlySpan propertyName, decimal value) + private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, decimal value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteNumberIndented(propertyName, value); + WriteNumberIndented(utf8PropertyName, value); } else { - WriteNumberMinimized(propertyName, value); + WriteNumberMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index c0621f0af1fd..ea19ce3a838c 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -64,7 +64,7 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool esca /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -76,18 +76,18 @@ public void WriteNumber(ReadOnlySpan propertyName, double value, bool esca /// /// Writes the using the default (i.e. 'G'). /// - public void WriteNumber(ReadOnlySpan propertyName, double value, bool escape = true) + public void WriteNumber(ReadOnlySpan utf8PropertyName, double value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); JsonWriterHelper.ValidateDouble(value); if (escape) { - WriteNumberEscape(propertyName, value); + WriteNumberEscape(utf8PropertyName, value); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -110,19 +110,19 @@ private void WriteNumberEscape(ReadOnlySpan propertyName, double value) } } - private void WriteNumberEscape(ReadOnlySpan propertyName, double value) + private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, double value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteNumberEscapeProperty(propertyName, value, propertyIdx); + WriteNumberEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } } @@ -159,14 +159,14 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v } } - private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, double value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -182,7 +182,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, double v escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -205,16 +205,16 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) } } - private void WriteNumberByOptions(ReadOnlySpan propertyName, double value) + private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, double value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteNumberIndented(propertyName, value); + WriteNumberIndented(utf8PropertyName, value); } else { - WriteNumberMinimized(propertyName, value); + WriteNumberMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index 48ec6d17a329..5853265c4a68 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -64,7 +64,7 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool escap /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -76,18 +76,18 @@ public void WriteNumber(ReadOnlySpan propertyName, float value, bool escap /// /// Writes the using the default (i.e. 'G'). /// - public void WriteNumber(ReadOnlySpan propertyName, float value, bool escape = true) + public void WriteNumber(ReadOnlySpan utf8PropertyName, float value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); JsonWriterHelper.ValidateSingle(value); if (escape) { - WriteNumberEscape(propertyName, value); + WriteNumberEscape(utf8PropertyName, value); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -110,19 +110,19 @@ private void WriteNumberEscape(ReadOnlySpan propertyName, float value) } } - private void WriteNumberEscape(ReadOnlySpan propertyName, float value) + private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, float value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteNumberEscapeProperty(propertyName, value, propertyIdx); + WriteNumberEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } } @@ -159,14 +159,14 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va } } - private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, float value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -182,7 +182,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, float va escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index c6feb72f1b9e..1011312a6c33 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -63,7 +63,7 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool escape /// /// Writes the property name and value (as a JSON string) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -75,17 +75,17 @@ public void WriteString(ReadOnlySpan propertyName, Guid value, bool escape /// /// Writes the using the default (i.e. 'D'), as the form: nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn. /// - public void WriteString(ReadOnlySpan propertyName, Guid value, bool escape = true) + public void WriteString(ReadOnlySpan utf8PropertyName, Guid value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); if (escape) { - WriteStringEscape(propertyName, value); + WriteStringEscape(utf8PropertyName, value); } else { - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -108,19 +108,19 @@ private void WriteStringEscape(ReadOnlySpan propertyName, Guid value) } } - private void WriteStringEscape(ReadOnlySpan propertyName, Guid value) + private void WriteStringEscape(ReadOnlySpan utf8PropertyName, Guid value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteStringEscapeProperty(propertyName, value, propertyIdx); + WriteStringEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); } } @@ -157,14 +157,14 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val } } - private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid value, int firstEscapeIndexProp) + private void WriteStringEscapeProperty(ReadOnlySpan utf8PropertyName, Guid value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -180,7 +180,7 @@ private void WriteStringEscapeProperty(ReadOnlySpan propertyName, Guid val escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteStringByOptions(escapedPropertyName.Slice(0, written), value); @@ -203,16 +203,16 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) } } - private void WriteStringByOptions(ReadOnlySpan propertyName, Guid value) + private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, Guid value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteStringIndented(propertyName, value); + WriteStringIndented(utf8PropertyName, value); } else { - WriteStringMinimized(propertyName, value); + WriteStringMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index 122d269c8abd..a7191a57e6ec 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -19,10 +19,10 @@ private void ValidatePropertyNameAndDepth(ReadOnlySpan propertyName) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ValidatePropertyNameAndDepth(ReadOnlySpan propertyName) + private void ValidatePropertyNameAndDepth(ReadOnlySpan utf8PropertyName) { - if (propertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) - ThrowHelper.ThrowInvalidOperationOrArgumentException(propertyName, _currentDepth); + if (utf8PropertyName.Length > JsonConstants.MaxTokenSize || CurrentDepth >= JsonConstants.MaxWriterDepth) + ThrowHelper.ThrowInvalidOperationOrArgumentException(utf8PropertyName, _currentDepth); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index e5a7cedb5cd3..13f3a1671aca 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -56,7 +56,7 @@ public void WriteNull(ReadOnlySpan propertyName, bool escape = true) /// /// Writes the property name and the JSON literal "null" as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. @@ -64,19 +64,19 @@ public void WriteNull(ReadOnlySpan propertyName, bool escape = true) /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteNull(ReadOnlySpan propertyName, bool escape = true) + public void WriteNull(ReadOnlySpan utf8PropertyName, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); ReadOnlySpan span = JsonConstants.NullValue; if (escape) { - WriteLiteralEscape(propertyName, span); + WriteLiteralEscape(utf8PropertyName, span); } else { - WriteLiteralByOptions(propertyName, span); + WriteLiteralByOptions(utf8PropertyName, span); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -132,7 +132,7 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool escap /// /// Writes the property name and value (as a JSON literal "true" or "false") as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON literal "true" or "false" as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -141,19 +141,19 @@ public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool escap /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteBoolean(ReadOnlySpan propertyName, bool value, bool escape = true) + public void WriteBoolean(ReadOnlySpan utf8PropertyName, bool value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); ReadOnlySpan span = value ? JsonConstants.TrueValue : JsonConstants.FalseValue; if (escape) { - WriteLiteralEscape(propertyName, span); + WriteLiteralEscape(utf8PropertyName, span); } else { - WriteLiteralByOptions(propertyName, span); + WriteLiteralByOptions(utf8PropertyName, span); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -176,19 +176,19 @@ private void WriteLiteralEscape(ReadOnlySpan propertyName, ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteLiteralEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteLiteralEscapeProperty(propertyName, value, propertyIdx); + WriteLiteralEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteLiteralByOptions(propertyName, value); + WriteLiteralByOptions(utf8PropertyName, value); } } @@ -225,14 +225,14 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl } } - private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp) + private void WriteLiteralEscapeProperty(ReadOnlySpan utf8PropertyName, ReadOnlySpan value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -248,7 +248,7 @@ private void WriteLiteralEscapeProperty(ReadOnlySpan propertyName, ReadOnl escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteLiteralByOptions(escapedPropertyName.Slice(0, written), value); @@ -282,17 +282,17 @@ private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan Advance(idx); } - private void WriteLiteralByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteLiteralByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { ValidateWritingProperty(); int idx; if (_writerOptions.Indented) { - idx = WritePropertyNameIndented(propertyName); + idx = WritePropertyNameIndented(utf8PropertyName); } else { - idx = WritePropertyNameMinimized(propertyName); + idx = WritePropertyNameMinimized(utf8PropertyName); } if (value.Length > _buffer.Length - idx) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 05e16eda2fb1..be106a111daf 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -63,7 +63,7 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -75,17 +75,17 @@ public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape /// /// Writes the using the default (i.e. 'G'), for example: 32767. /// - public void WriteNumber(ReadOnlySpan propertyName, long value, bool escape = true) + public void WriteNumber(ReadOnlySpan utf8PropertyName, long value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); if (escape) { - WriteNumberEscape(propertyName, value); + WriteNumberEscape(utf8PropertyName, value); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -131,7 +131,7 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -143,8 +143,8 @@ public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape /// /// Writes the using the default (i.e. 'G'), for example: 32767. /// - public void WriteNumber(ReadOnlySpan propertyName, int value, bool escape = true) - => WriteNumber(propertyName, (long)value, escape); + public void WriteNumber(ReadOnlySpan utf8PropertyName, int value, bool escape = true) + => WriteNumber(utf8PropertyName, (long)value, escape); private void WriteNumberEscape(ReadOnlySpan propertyName, long value) { @@ -162,19 +162,19 @@ private void WriteNumberEscape(ReadOnlySpan propertyName, long value) } } - private void WriteNumberEscape(ReadOnlySpan propertyName, long value) + private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, long value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteNumberEscapeProperty(propertyName, value, propertyIdx); + WriteNumberEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } } @@ -211,14 +211,14 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val } } - private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, long value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -234,7 +234,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, long val escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -257,16 +257,16 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) } } - private void WriteNumberByOptions(ReadOnlySpan propertyName, long value) + private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, long value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteNumberIndented(propertyName, value); + WriteNumberIndented(utf8PropertyName, value); } else { - WriteNumberMinimized(propertyName, value); + WriteNumberMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 54f0ae9071bb..f90c35b2e56e 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -60,8 +60,8 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Writes the UTF-8 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. - /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. + /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// @@ -70,17 +70,17 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) + public void WriteString(ReadOnlySpan utf8PropertyName, ReadOnlySpan utf8Value, bool escape = true) { - JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); + JsonWriterHelper.ValidatePropertyAndValue(utf8PropertyName, utf8Value); if (escape) { - WriteStringEscape(propertyName, value); + WriteStringEscape(utf8PropertyName, utf8Value); } else { - WriteStringDontEscape(propertyName, value); + WriteStringDontEscape(utf8PropertyName, utf8Value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -106,7 +106,7 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool esca /// /// Writes the UTF-8 property name and UTF-16 text value (as a JSON string) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped @@ -116,17 +116,17 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool esca /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) + public void WriteString(ReadOnlySpan utf8PropertyName, ReadOnlySpan value, bool escape = true) { - JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); + JsonWriterHelper.ValidatePropertyAndValue(utf8PropertyName, value); if (escape) { - WriteStringEscape(propertyName, value); + WriteStringEscape(utf8PropertyName, value); } else { - WriteStringDontEscape(propertyName, value); + WriteStringDontEscape(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -137,7 +137,7 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// Writes the property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. - /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. + /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// @@ -146,14 +146,14 @@ public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan valu /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(string propertyName, ReadOnlySpan value, bool escape = true) - => WriteString(propertyName.AsSpan(), value, escape); + public void WriteString(string propertyName, ReadOnlySpan utf8Value, bool escape = true) + => WriteString(propertyName.AsSpan(), utf8Value, escape); /// /// Writes the UTF-16 property name and UTF-8 text value (as a JSON string) as part of a name/value pair of a JSON object. /// /// The UTF-16 encoded property name of the JSON object to be transcoded and written as UTF-8. - /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. + /// The UTF-8 encoded value to be written as a JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped /// @@ -162,17 +162,17 @@ public void WriteString(string propertyName, ReadOnlySpan value, bool esca /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan value, bool escape = true) + public void WriteString(ReadOnlySpan propertyName, ReadOnlySpan utf8Value, bool escape = true) { - JsonWriterHelper.ValidatePropertyAndValue(propertyName, value); + JsonWriterHelper.ValidatePropertyAndValue(propertyName, utf8Value); if (escape) { - WriteStringEscape(propertyName, value); + WriteStringEscape(propertyName, utf8Value); } else { - WriteStringDontEscape(propertyName, value); + WriteStringDontEscape(propertyName, utf8Value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -198,7 +198,7 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool esca /// /// Writes the UTF-8 property name and string text value (as a JSON string) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The UTF-16 encoded value to be written as a UTF-8 transcoded JSON string as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// The value is always escaped @@ -208,8 +208,8 @@ public void WriteString(ReadOnlySpan propertyName, string value, bool esca /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteString(ReadOnlySpan propertyName, string value, bool escape = true) - => WriteString(propertyName, value.AsSpan(), escape); + public void WriteString(ReadOnlySpan utf8PropertyName, string value, bool escape = true) + => WriteString(utf8PropertyName, value.AsSpan(), escape); [MethodImpl(MethodImplOptions.AggressiveInlining)] private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) @@ -226,30 +226,30 @@ private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadO } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) + private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); if (valueIdx != -1) { - WriteStringEscapeValueOnly(escapedPropertyName, value, valueIdx); + WriteStringEscapeValueOnly(escapedPropertyName, utf8Value, valueIdx); } else { - WriteStringByOptions(escapedPropertyName, value); + WriteStringByOptions(escapedPropertyName, utf8Value); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) + private void WriteStringDontEscape(ReadOnlySpan escapedPropertyName, ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); if (valueIdx != -1) { - WriteStringEscapeValueOnly(escapedPropertyName, value, valueIdx); + WriteStringEscapeValueOnly(escapedPropertyName, utf8Value, valueIdx); } else { - WriteStringByOptions(escapedPropertyName, value); + WriteStringByOptions(escapedPropertyName, utf8Value); } } @@ -281,28 +281,28 @@ private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan utf8Value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); + Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < utf8Value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndex)); Span escapedValue = valueArray; - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndex, out int written); WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); ArrayPool.Shared.Return(valueArray); } - private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan value, int firstEscapeIndex) + private void WriteStringEscapeValueOnly(ReadOnlySpan escapedPropertyName, ReadOnlySpan utf8Value, int firstEscapeIndex) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); + Debug.Assert(firstEscapeIndex >= 0 && firstEscapeIndex < utf8Value.Length); - byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndex)); + byte[] valueArray = ArrayPool.Shared.Rent(JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndex)); Span escapedValue = valueArray; - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndex, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndex, out int written); WriteStringByOptions(escapedPropertyName, escapedValue.Slice(0, written)); @@ -342,10 +342,10 @@ private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); @@ -353,17 +353,17 @@ private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); @@ -372,18 +372,18 @@ private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { int valueIdx = JsonWriterHelper.NeedsEscaping(value); - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); @@ -391,11 +391,11 @@ private void WriteStringEscape(ReadOnlySpan propertyName, ReadOnlySpan propertyName, R } } - private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan utf8PropertyName, ReadOnlySpan utf8Value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); byte[] valueArray = null; byte[] propertyArray = null; if (firstEscapeIndexVal != -1) { - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal); Span escapedValue; if (length > StackallocThreshold) @@ -493,13 +493,13 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); - value = escapedValue.Slice(0, written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, out int written); + utf8Value = escapedValue.Slice(0, written); } if (firstEscapeIndexProp != -1) { - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -515,11 +515,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - propertyName = escapedPropertyName.Slice(0, written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + utf8PropertyName = escapedPropertyName.Slice(0, written); } - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, utf8Value); if (valueArray != null) { @@ -532,9 +532,9 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } } - private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan utf8Value, int firstEscapeIndexProp, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); byte[] valueArray = null; @@ -542,7 +542,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexVal != -1) { - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal); Span escapedValue; if (length > StackallocThreshold) @@ -559,8 +559,8 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); - value = escapedValue.Slice(0, written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, out int written); + utf8Value = escapedValue.Slice(0, written); } if (firstEscapeIndexProp != -1) @@ -585,7 +585,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R propertyName = escapedPropertyName.Slice(0, written); } - WriteStringByOptions(propertyName, value); + WriteStringByOptions(propertyName, utf8Value); if (valueArray != null) { @@ -598,10 +598,10 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R } } - private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) + private void WriteStringEscapePropertyOrValue(ReadOnlySpan utf8PropertyName, ReadOnlySpan value, int firstEscapeIndexProp, int firstEscapeIndexVal) { Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); char[] valueArray = null; byte[] propertyArray = null; @@ -631,7 +631,7 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R if (firstEscapeIndexProp != -1) { - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -647,11 +647,11 @@ private void WriteStringEscapePropertyOrValue(ReadOnlySpan propertyName, R escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); - propertyName = escapedPropertyName.Slice(0, written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + utf8PropertyName = escapedPropertyName.Slice(0, written); } - WriteStringByOptions(propertyName, value); + WriteStringByOptions(utf8PropertyName, value); if (valueArray != null) { @@ -677,42 +677,42 @@ private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan< } } - private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan utf8Value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteStringIndented(propertyName, value); + WriteStringIndented(utf8PropertyName, utf8Value); } else { - WriteStringMinimized(propertyName, value); + WriteStringMinimized(utf8PropertyName, utf8Value); } } - private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan utf8Value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteStringIndented(propertyName, value); + WriteStringIndented(propertyName, utf8Value); } else { - WriteStringMinimized(propertyName, value); + WriteStringMinimized(propertyName, utf8Value); } } - private void WriteStringByOptions(ReadOnlySpan propertyName, ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan utf8PropertyName, ReadOnlySpan value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteStringIndented(propertyName, value); + WriteStringIndented(utf8PropertyName, value); } else { - WriteStringMinimized(propertyName, value); + WriteStringMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index f3b241aafefa..ee85f7d84ee2 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -65,7 +65,7 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escap /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -78,17 +78,17 @@ public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escap /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] - public void WriteNumber(ReadOnlySpan propertyName, ulong value, bool escape = true) + public void WriteNumber(ReadOnlySpan utf8PropertyName, ulong value, bool escape = true) { - JsonWriterHelper.ValidateProperty(propertyName); + JsonWriterHelper.ValidateProperty(utf8PropertyName); if (escape) { - WriteNumberEscape(propertyName, value); + WriteNumberEscape(utf8PropertyName, value); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } SetFlagToAddListSeparatorBeforeNextItem(); @@ -136,7 +136,7 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape /// /// Writes the property name and value (as a JSON number) as part of a name/value pair of a JSON object. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// The value to be written as a JSON number as part of the name/value pair. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// @@ -149,8 +149,8 @@ public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape /// Writes the using the default (i.e. 'G'), for example: 32767. /// [CLSCompliant(false)] - public void WriteNumber(ReadOnlySpan propertyName, uint value, bool escape = true) - => WriteNumber(propertyName, (ulong)value, escape); + public void WriteNumber(ReadOnlySpan utf8PropertyName, uint value, bool escape = true) + => WriteNumber(utf8PropertyName, (ulong)value, escape); private void WriteNumberEscape(ReadOnlySpan propertyName, ulong value) { @@ -168,19 +168,19 @@ private void WriteNumberEscape(ReadOnlySpan propertyName, ulong value) } } - private void WriteNumberEscape(ReadOnlySpan propertyName, ulong value) + private void WriteNumberEscape(ReadOnlySpan utf8PropertyName, ulong value) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteNumberEscapeProperty(propertyName, value, propertyIdx); + WriteNumberEscapeProperty(utf8PropertyName, value, propertyIdx); } else { - WriteNumberByOptions(propertyName, value); + WriteNumberByOptions(utf8PropertyName, value); } } @@ -217,14 +217,14 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va } } - private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong value, int firstEscapeIndexProp) + private void WriteNumberEscapeProperty(ReadOnlySpan utf8PropertyName, ulong value, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -240,7 +240,7 @@ private void WriteNumberEscapeProperty(ReadOnlySpan propertyName, ulong va escapedPropertyName = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteNumberByOptions(escapedPropertyName.Slice(0, written), value); @@ -263,16 +263,16 @@ private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) } } - private void WriteNumberByOptions(ReadOnlySpan propertyName, ulong value) + private void WriteNumberByOptions(ReadOnlySpan utf8PropertyName, ulong value) { ValidateWritingProperty(); if (_writerOptions.Indented) { - WriteNumberIndented(propertyName, value); + WriteNumberIndented(utf8PropertyName, value); } else { - WriteNumberMinimized(propertyName, value); + WriteNumberMinimized(utf8PropertyName, value); } } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 09da20d6ac30..dc749fa65615 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -142,50 +142,50 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn /// /// Writes the UTF-8 text value (as a JSON comment). /// - /// The UTF-8 encoded value to be written as a JSON comment within /*..*/. + /// The UTF-8 encoded value to be written as a JSON comment within /*..*/. /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. /// - public void WriteCommentValue(ReadOnlySpan value, bool escape = true) + public void WriteCommentValue(ReadOnlySpan utf8Value, bool escape = true) { - JsonWriterHelper.ValidateValue(value); + JsonWriterHelper.ValidateValue(utf8Value); if (escape) { - WriteCommentEscape(value); + WriteCommentEscape(utf8Value); } else { - WriteCommentByOptions(value); + WriteCommentByOptions(utf8Value); } } - private void WriteCommentEscape(ReadOnlySpan value) + private void WriteCommentEscape(ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); if (valueIdx != -1) { - WriteCommentEscapeValue(value, valueIdx); + WriteCommentEscapeValue(utf8Value, valueIdx); } else { - WriteCommentByOptions(value); + WriteCommentByOptions(utf8Value); } } - private void WriteCommentByOptions(ReadOnlySpan value) + private void WriteCommentByOptions(ReadOnlySpan utf8Value) { if (_writerOptions.Indented) { - WriteCommentIndented(value); + WriteCommentIndented(utf8Value); } else { - WriteCommentMinimized(value); + WriteCommentMinimized(utf8Value); } } @@ -208,14 +208,14 @@ private void WriteCommentIndented(ReadOnlySpan escapedValue) Advance(idx); } - private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) + private void WriteCommentEscapeValue(ReadOnlySpan utf8Value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); + Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < utf8Value.Length); byte[] valueArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal); Span escapedValue; if (length > StackallocThreshold) @@ -232,7 +232,7 @@ private void WriteCommentEscapeValue(ReadOnlySpan value, int firstEscapeIn escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, out int written); WriteCommentByOptions(escapedValue.Slice(0, written)); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index 303ca4940e31..03d57f2823c0 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -43,34 +43,34 @@ public void WriteBooleanValue(bool value) SetFlagToAddListSeparatorBeforeNextItem(); } - private void WriteLiteralByOptions(ReadOnlySpan value) + private void WriteLiteralByOptions(ReadOnlySpan utf8Value) { ValidateWritingValue(); if (_writerOptions.Indented) { - WriteLiteralIndented(value); + WriteLiteralIndented(utf8Value); } else { - WriteLiteralMinimized(value); + WriteLiteralMinimized(utf8Value); } } - private void WriteLiteralMinimized(ReadOnlySpan value) + private void WriteLiteralMinimized(ReadOnlySpan utf8Value) { int idx = 0; WriteListSeparator(ref idx); - CopyLoop(value, ref idx); + CopyLoop(utf8Value, ref idx); Advance(idx); } - private void WriteLiteralIndented(ReadOnlySpan value) + private void WriteLiteralIndented(ReadOnlySpan utf8Value) { int idx = WriteCommaAndFormattingPreamble(); - CopyLoop(value, ref idx); + CopyLoop(utf8Value, ref idx); Advance(idx); } diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 753f9f423de9..e9513bbfbc60 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -136,7 +136,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd /// /// Writes the UTF-8 text value (as a JSON string) as an element of a JSON array. /// - /// The UTF-8 encoded value to be written as a JSON string element of a JSON array. + /// The UTF-8 encoded value to be written as a JSON string element of a JSON array. /// If this is set to false, the writer assumes the value is properly escaped and skips the escaping step. /// /// Thrown when the specified value is too large. @@ -144,49 +144,49 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd /// /// Thrown if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStringValue(ReadOnlySpan value, bool escape = true) + public void WriteStringValue(ReadOnlySpan utf8Value, bool escape = true) { - JsonWriterHelper.ValidateValue(value); + JsonWriterHelper.ValidateValue(utf8Value); if (escape) { - WriteStringEscape(value); + WriteStringEscape(utf8Value); } else { - WriteStringByOptions(value); + WriteStringByOptions(utf8Value); } SetFlagToAddListSeparatorBeforeNextItem(); _tokenType = JsonTokenType.String; } - private void WriteStringEscape(ReadOnlySpan value) + private void WriteStringEscape(ReadOnlySpan utf8Value) { - int valueIdx = JsonWriterHelper.NeedsEscaping(value); + int valueIdx = JsonWriterHelper.NeedsEscaping(utf8Value); Debug.Assert(valueIdx >= -1 && valueIdx < int.MaxValue / 2); if (valueIdx != -1) { - WriteStringEscapeValue(value, valueIdx); + WriteStringEscapeValue(utf8Value, valueIdx); } else { - WriteStringByOptions(value); + WriteStringByOptions(utf8Value); } } - private void WriteStringByOptions(ReadOnlySpan value) + private void WriteStringByOptions(ReadOnlySpan utf8Value) { ValidateWritingValue(); if (_writerOptions.Indented) { - WriteStringIndented(value); + WriteStringIndented(utf8Value); } else { - WriteStringMinimized(value); + WriteStringMinimized(utf8Value); } } @@ -209,14 +209,14 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) Advance(idx); } - private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeIndexVal) + private void WriteStringEscapeValue(ReadOnlySpan utf8Value, int firstEscapeIndexVal) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= value.Length); - Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < value.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8Value.Length); + Debug.Assert(firstEscapeIndexVal >= 0 && firstEscapeIndexVal < utf8Value.Length); byte[] valueArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal); Span escapedValue; if (length > StackallocThreshold) @@ -233,7 +233,7 @@ private void WriteStringEscapeValue(ReadOnlySpan value, int firstEscapeInd escapedValue = new Span(ptr, length); } } - JsonWriterHelper.EscapeString(value, escapedValue, firstEscapeIndexVal, out int written); + JsonWriterHelper.EscapeString(utf8Value, escapedValue, firstEscapeIndexVal, out int written); WriteStringByOptions(escapedValue.Slice(0, written)); diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index 81732682663b..65763c89be42 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -311,7 +311,7 @@ private void WriteStartIndented(byte token) /// /// Writes the beginning of a JSON array with a property name as the key. /// - /// The UTF-8 encoded property name of the JSON array to be written. + /// The UTF-8 encoded property name of the JSON array to be written. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. @@ -320,17 +320,17 @@ private void WriteStartIndented(byte token) /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartArray(ReadOnlySpan propertyName, bool escape = true) + public void WriteStartArray(ReadOnlySpan utf8PropertyName, bool escape = true) { - ValidatePropertyNameAndDepth(propertyName); + ValidatePropertyNameAndDepth(utf8PropertyName); if (escape) { - WriteStartEscape(propertyName, JsonConstants.OpenBracket); + WriteStartEscape(utf8PropertyName, JsonConstants.OpenBracket); } else { - WriteStartByOptions(propertyName, JsonConstants.OpenBracket); + WriteStartByOptions(utf8PropertyName, JsonConstants.OpenBracket); } _currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -342,7 +342,7 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool escape = true) /// /// Writes the beginning of a JSON object with a property name as the key. /// - /// The UTF-8 encoded property name of the JSON object to be written. + /// The UTF-8 encoded property name of the JSON object to be written. /// If this is set to false, the writer assumes the property name is properly escaped and skips the escaping step. /// /// Thrown when the specified property name is too large. @@ -351,17 +351,17 @@ public void WriteStartArray(ReadOnlySpan propertyName, bool escape = true) /// Thrown when the depth of the JSON has exceeded the maximum depth of 1000 /// OR if this would result in an invalid JSON to be written (while validation is enabled). /// - public void WriteStartObject(ReadOnlySpan propertyName, bool escape = true) + public void WriteStartObject(ReadOnlySpan utf8PropertyName, bool escape = true) { - ValidatePropertyNameAndDepth(propertyName); + ValidatePropertyNameAndDepth(utf8PropertyName); if (escape) { - WriteStartEscape(propertyName, JsonConstants.OpenBrace); + WriteStartEscape(utf8PropertyName, JsonConstants.OpenBrace); } else { - WriteStartByOptions(propertyName, JsonConstants.OpenBrace); + WriteStartByOptions(utf8PropertyName, JsonConstants.OpenBrace); } _currentDepth &= JsonConstants.RemoveFlagsBitMask; @@ -370,33 +370,33 @@ public void WriteStartObject(ReadOnlySpan propertyName, bool escape = true _tokenType = JsonTokenType.StartObject; } - private void WriteStartEscape(ReadOnlySpan propertyName, byte token) + private void WriteStartEscape(ReadOnlySpan utf8PropertyName, byte token) { - int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName); + int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName); Debug.Assert(propertyIdx >= -1 && propertyIdx < int.MaxValue / 2); if (propertyIdx != -1) { - WriteStartEscapeProperty(propertyName, token, propertyIdx); + WriteStartEscapeProperty(utf8PropertyName, token, propertyIdx); } else { - WriteStartByOptions(propertyName, token); + WriteStartByOptions(utf8PropertyName, token); } } - private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) + private void WriteStartByOptions(ReadOnlySpan utf8PropertyName, byte token) { ValidateWritingProperty(token); int idx; if (_writerOptions.Indented) { - idx = WritePropertyNameIndented(propertyName); + idx = WritePropertyNameIndented(utf8PropertyName); } else { - idx = WritePropertyNameMinimized(propertyName); + idx = WritePropertyNameMinimized(utf8PropertyName); } if (1 > _buffer.Length - idx) @@ -409,14 +409,14 @@ private void WriteStartByOptions(ReadOnlySpan propertyName, byte token) Advance(idx); } - private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte token, int firstEscapeIndexProp) + private void WriteStartEscapeProperty(ReadOnlySpan utf8PropertyName, byte token, int firstEscapeIndexProp) { - Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length); - Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < propertyName.Length); + Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length); + Debug.Assert(firstEscapeIndexProp >= 0 && firstEscapeIndexProp < utf8PropertyName.Length); byte[] propertyArray = null; - int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp); + int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp); Span escapedPropertyName; if (length > StackallocThreshold) { @@ -433,7 +433,7 @@ private void WriteStartEscapeProperty(ReadOnlySpan propertyName, byte toke } } - JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written); + JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written); WriteStartByOptions(escapedPropertyName.Slice(0, written), token); From 6f41164c2e21b75710363299e3a22e0032f5bc62 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 14 Jan 2019 18:53:20 -0800 Subject: [PATCH 32/33] Remove redundant code where idx is set to 0 unnecessarily. --- .../Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index 1011312a6c33..c201b6afa1b3 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -257,7 +257,6 @@ private void WriteStringValue(Guid value, ref int idx) if (_buffer.Length <= idx) { AdvanceAndGrow(ref idx); - idx = 0; } _buffer[idx++] = JsonConstants.Quote; @@ -266,7 +265,6 @@ private void WriteStringValue(Guid value, ref int idx) if (_buffer.Length <= idx) { AdvanceAndGrow(ref idx); - idx = 0; } _buffer[idx++] = JsonConstants.Quote; } From c3c83e4f9c1fb933d2edbd8f5c0b53ac1876b1e0 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Mon, 14 Jan 2019 20:11:59 -0800 Subject: [PATCH 33/33] Remove dead code (dont escape forward slash) and make tests culture invariant. --- .../Text/Json/Writer/JsonWriterHelper.Escaping.cs | 6 ------ src/System.Text.Json/tests/Utf8JsonWriterTests.cs | 10 +++++----- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs index 4989b21ef223..18e946272e7a 100644 --- a/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs +++ b/src/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.Escaping.cs @@ -132,9 +132,6 @@ private static int EscapeNextBytes(ReadOnlySpan value, Span destinat case JsonConstants.BackSlash: destination[written++] = (byte)'\\'; break; - case JsonConstants.Slash: - destination[written++] = (byte)'/'; - break; case JsonConstants.BackSpace: destination[written++] = (byte)'b'; break; @@ -446,9 +443,6 @@ private static void EscapeNextChars(ReadOnlySpan value, int firstChar, Spa case JsonConstants.BackSlash: destination[written++] = '\\'; break; - case JsonConstants.Slash: - destination[written++] = '/'; - break; case JsonConstants.BackSpace: destination[written++] = 'b'; break; diff --git a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs index 90ed4cc18c51..43e78ea69e03 100644 --- a/src/System.Text.Json/tests/Utf8JsonWriterTests.cs +++ b/src/System.Text.Json/tests/Utf8JsonWriterTests.cs @@ -220,7 +220,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) string actualStr = Encoding.UTF8.GetString(output.Formatted); Assert.True(output.Formatted.Length <= 31); - Assert.Equal(decimal.Parse(actualStr), value); + Assert.Equal(decimal.Parse(actualStr, CultureInfo.InvariantCulture), value); } for (int i = 0; i < 1_000; i++) @@ -235,7 +235,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) string actualStr = Encoding.UTF8.GetString(output.Formatted); Assert.True(output.Formatted.Length <= 31); - Assert.Equal(decimal.Parse(actualStr), value); + Assert.Equal(decimal.Parse(actualStr, CultureInfo.InvariantCulture), value); } { @@ -249,7 +249,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) string actualStr = Encoding.UTF8.GetString(output.Formatted); Assert.Equal(value.ToString().Length, output.Formatted.Length); - Assert.Equal(decimal.Parse(actualStr), value); + Assert.Equal(decimal.Parse(actualStr, CultureInfo.InvariantCulture), value); } { @@ -263,7 +263,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) string actualStr = Encoding.UTF8.GetString(output.Formatted); Assert.Equal(value.ToString().Length, output.Formatted.Length); - Assert.Equal(decimal.Parse(actualStr), value); + Assert.Equal(decimal.Parse(actualStr, CultureInfo.InvariantCulture), value); } { @@ -287,7 +287,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) string actualStr = Encoding.UTF8.GetString(output.Formatted); Assert.Equal(value.ToString().Length, output.Formatted.Length); - Assert.Equal(decimal.Parse(actualStr), value); + Assert.Equal(decimal.Parse(actualStr, CultureInfo.InvariantCulture), value); } }