public sealed partial class Utf8JsonWriter
{
/// <summary>
+ /// Writes the pre-encoded property name (as a JSON string) as the first part of a name/value pair of a JSON object.
+ /// </summary>
+ /// <param name="propertyName">The JSON encoded property name of the JSON object to be transcoded and written as UTF-8.</param>
+ /// <remarks>
+ /// The property name should already be escaped when the instance of <see cref="JsonEncodedText"/> was created.
+ /// </remarks>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown if this would result in an invalid JSON to be written (while validation is enabled).
+ /// </exception>
+ public void WritePropertyName(JsonEncodedText propertyName)
+ => WritePropertyNameHelper(propertyName.EncodedUtf8Bytes);
+
+ private void WritePropertyNameHelper(ReadOnlySpan<byte> utf8PropertyName)
+ {
+ Debug.Assert(utf8PropertyName.Length <= JsonConstants.MaxTokenSize);
+
+ WriteStringByOptionsPropertyName(utf8PropertyName);
+
+ _currentDepth &= JsonConstants.RemoveFlagsBitMask;
+ _tokenType = JsonTokenType.PropertyName;
+ }
+
+ /// <summary>
+ /// Writes the property name (as a JSON string) as the first part of a name/value pair of a JSON object.
+ /// </summary>
+ /// <param name="propertyName">The property name of the JSON object to be transcoded and written as UTF-8.</param>
+ /// <remarks>
+ /// The property name is escaped before writing.
+ /// </remarks>
+ /// <exception cref="ArgumentException">
+ /// Thrown when the specified property name is too large.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown if this would result in an invalid JSON to be written (while validation is enabled).
+ /// </exception>
+ public void WritePropertyName(string propertyName)
+ => WritePropertyName(propertyName.AsSpan());
+
+ /// <summary>
+ /// Writes the property name (as a JSON string) as the first part of a name/value pair of a JSON object.
+ /// </summary>
+ /// <param name="propertyName">The property name of the JSON object to be transcoded and written as UTF-8.</param>
+ /// <remarks>
+ /// The property name is escaped before writing.
+ /// </remarks>
+ /// <exception cref="ArgumentException">
+ /// Thrown when the specified property name is too large.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown if this would result in an invalid JSON to be written (while validation is enabled).
+ /// </exception>
+ public void WritePropertyName(ReadOnlySpan<char> propertyName)
+ {
+ JsonWriterHelper.ValidateProperty(propertyName);
+
+ int propertyIdx = JsonWriterHelper.NeedsEscaping(propertyName);
+
+ Debug.Assert(propertyIdx >= -1 && propertyIdx < propertyName.Length && propertyIdx < int.MaxValue / 2);
+
+ if (propertyIdx != -1)
+ {
+ WriteStringEscapeProperty(propertyName, propertyIdx);
+ }
+ else
+ {
+ WriteStringByOptionsPropertyName(propertyName);
+ }
+ _currentDepth &= JsonConstants.RemoveFlagsBitMask;
+ _tokenType = JsonTokenType.PropertyName;
+ }
+
+ private void WriteStringEscapeProperty(ReadOnlySpan<char> propertyName, int firstEscapeIndexProp)
+ {
+ Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length);
+
+ char[] propertyArray = null;
+
+ if (firstEscapeIndexProp != -1)
+ {
+ int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);
+
+ Span<char> escapedPropertyName;
+ if (length > JsonConstants.StackallocThreshold)
+ {
+ propertyArray = ArrayPool<char>.Shared.Rent(length);
+ escapedPropertyName = propertyArray;
+ }
+ else
+ {
+ // Cannot create a span directly since it gets assigned to parameter and passed down.
+ unsafe
+ {
+ char* ptr = stackalloc char[length];
+ escapedPropertyName = new Span<char>(ptr, length);
+ }
+ }
+
+ JsonWriterHelper.EscapeString(propertyName, escapedPropertyName, firstEscapeIndexProp, out int written);
+ propertyName = escapedPropertyName.Slice(0, written);
+ }
+
+ WriteStringByOptionsPropertyName(propertyName);
+
+ if (propertyArray != null)
+ {
+ ArrayPool<char>.Shared.Return(propertyArray);
+ }
+ }
+
+ private void WriteStringByOptionsPropertyName(ReadOnlySpan<char> propertyName)
+ {
+ ValidateWritingProperty();
+ if (Options.Indented)
+ {
+ WriteStringIndentedPropertyName(propertyName);
+ }
+ else
+ {
+ WriteStringMinimizedPropertyName(propertyName);
+ }
+ }
+
+ private void WriteStringMinimizedPropertyName(ReadOnlySpan<char> escapedPropertyName)
+ {
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length < (int.MaxValue - 4) / JsonConstants.MaxExpansionFactorWhileTranscoding);
+
+ // All ASCII, 2 quotes for property name, and 1 colon => escapedPropertyName.Length + 3
+ // Optionally, 1 list separator, and up to 3x growth when transcoding
+ int maxRequired = (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + 4;
+
+ if (_memory.Length - BytesPending < maxRequired)
+ {
+ Grow(maxRequired);
+ }
+
+ Span<byte> output = _memory.Span;
+
+ if (_currentDepth < 0)
+ {
+ output[BytesPending++] = JsonConstants.ListSeparator;
+ }
+ output[BytesPending++] = JsonConstants.Quote;
+
+ TranscodeAndWrite(escapedPropertyName, output);
+
+ output[BytesPending++] = JsonConstants.Quote;
+ output[BytesPending++] = JsonConstants.KeyValueSeperator;
+ }
+
+ private void WriteStringIndentedPropertyName(ReadOnlySpan<char> escapedPropertyName)
+ {
+ int indent = Indentation;
+ Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
+
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length < (int.MaxValue - 5 - indent - s_newLineLength) / JsonConstants.MaxExpansionFactorWhileTranscoding);
+
+ // All ASCII, 2 quotes for property name, 1 colon, and 1 space => escapedPropertyName.Length + 4
+ // Optionally, 1 list separator, 1-2 bytes for new line, and up to 3x growth when transcoding
+ int maxRequired = indent + (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + 5 + s_newLineLength;
+
+ if (_memory.Length - BytesPending < maxRequired)
+ {
+ Grow(maxRequired);
+ }
+
+ Span<byte> output = _memory.Span;
+
+ if (_currentDepth < 0)
+ {
+ output[BytesPending++] = JsonConstants.ListSeparator;
+ }
+
+ if (_tokenType != JsonTokenType.None)
+ {
+ WriteNewLine(output);
+ }
+
+ JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent);
+ BytesPending += indent;
+
+ output[BytesPending++] = JsonConstants.Quote;
+
+ TranscodeAndWrite(escapedPropertyName, output);
+
+ output[BytesPending++] = JsonConstants.Quote;
+ output[BytesPending++] = JsonConstants.KeyValueSeperator;
+ output[BytesPending++] = JsonConstants.Space;
+ }
+
+ /// <summary>
+ /// Writes the UTF-8 property name (as a JSON string) as the first part of a name/value pair of a JSON object.
+ /// </summary>
+ /// <param name="utf8PropertyName">The UTF-8 encoded property name of the JSON object to be written.</param>
+ /// <remarks>
+ /// The property name is escaped before writing.
+ /// </remarks>
+ /// <exception cref="ArgumentException">
+ /// Thrown when the specified property name is too large.
+ /// </exception>
+ /// <exception cref="InvalidOperationException">
+ /// Thrown if this would result in an invalid JSON to be written (while validation is enabled).
+ /// </exception>
+ public void WritePropertyName(ReadOnlySpan<byte> utf8PropertyName)
+ {
+ JsonWriterHelper.ValidateProperty(utf8PropertyName);
+
+ int propertyIdx = JsonWriterHelper.NeedsEscaping(utf8PropertyName);
+
+ Debug.Assert(propertyIdx >= -1 && propertyIdx < utf8PropertyName.Length && propertyIdx < int.MaxValue / 2);
+
+ if (propertyIdx != -1)
+ {
+ WriteStringEscapeProperty(utf8PropertyName, propertyIdx);
+ }
+ else
+ {
+ WriteStringByOptionsPropertyName(utf8PropertyName);
+ }
+ _currentDepth &= JsonConstants.RemoveFlagsBitMask;
+ _tokenType = JsonTokenType.PropertyName;
+ }
+
+ private void WriteStringEscapeProperty(ReadOnlySpan<byte> utf8PropertyName, int firstEscapeIndexProp)
+ {
+ Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length);
+
+ byte[] propertyArray = null;
+
+ if (firstEscapeIndexProp != -1)
+ {
+ int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);
+
+ Span<byte> escapedPropertyName;
+ if (length > JsonConstants.StackallocThreshold)
+ {
+ propertyArray = ArrayPool<byte>.Shared.Rent(length);
+ escapedPropertyName = propertyArray;
+ }
+ else
+ {
+ // Cannot create a span directly since it gets assigned to parameter and passed down.
+ unsafe
+ {
+ byte* ptr = stackalloc byte[length];
+ escapedPropertyName = new Span<byte>(ptr, length);
+ }
+ }
+
+ JsonWriterHelper.EscapeString(utf8PropertyName, escapedPropertyName, firstEscapeIndexProp, out int written);
+ utf8PropertyName = escapedPropertyName.Slice(0, written);
+ }
+
+ WriteStringByOptionsPropertyName(utf8PropertyName);
+
+ if (propertyArray != null)
+ {
+ ArrayPool<byte>.Shared.Return(propertyArray);
+ }
+ }
+
+ private void WriteStringByOptionsPropertyName(ReadOnlySpan<byte> utf8PropertyName)
+ {
+ ValidateWritingProperty();
+ if (Options.Indented)
+ {
+ WriteStringIndentedPropertyName(utf8PropertyName);
+ }
+ else
+ {
+ WriteStringMinimizedPropertyName(utf8PropertyName);
+ }
+ }
+
+ private void WriteStringMinimizedPropertyName(ReadOnlySpan<byte> escapedPropertyName)
+ {
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length < int.MaxValue - 4);
+
+ int minRequired = escapedPropertyName.Length + 3; // 2 quotes for property name, and 1 colon
+ int maxRequired = minRequired + 1; // Optionally, 1 list separator
+
+ if (_memory.Length - BytesPending < maxRequired)
+ {
+ Grow(maxRequired);
+ }
+
+ Span<byte> output = _memory.Span;
+
+ if (_currentDepth < 0)
+ {
+ output[BytesPending++] = JsonConstants.ListSeparator;
+ }
+ output[BytesPending++] = JsonConstants.Quote;
+
+ escapedPropertyName.CopyTo(output.Slice(BytesPending));
+ BytesPending += escapedPropertyName.Length;
+
+ output[BytesPending++] = JsonConstants.Quote;
+ output[BytesPending++] = JsonConstants.KeyValueSeperator;
+ }
+
+ private void WriteStringIndentedPropertyName(ReadOnlySpan<byte> escapedPropertyName)
+ {
+ int indent = Indentation;
+ Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);
+
+ Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxTokenSize);
+ Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - 5 - s_newLineLength);
+
+ int minRequired = indent + escapedPropertyName.Length + 4; // 2 quotes for property name, 1 colon, and 1 space
+ int maxRequired = minRequired + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line
+
+ if (_memory.Length - BytesPending < maxRequired)
+ {
+ Grow(maxRequired);
+ }
+
+ Span<byte> output = _memory.Span;
+
+ if (_currentDepth < 0)
+ {
+ output[BytesPending++] = JsonConstants.ListSeparator;
+ }
+
+ Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName);
+
+ if (_tokenType != JsonTokenType.None)
+ {
+ WriteNewLine(output);
+ }
+
+ JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent);
+ BytesPending += indent;
+
+ output[BytesPending++] = JsonConstants.Quote;
+
+ escapedPropertyName.CopyTo(output.Slice(BytesPending));
+ BytesPending += escapedPropertyName.Length;
+
+ output[BytesPending++] = JsonConstants.Quote;
+ output[BytesPending++] = JsonConstants.KeyValueSeperator;
+ output[BytesPending++] = JsonConstants.Space;
+ }
+
+ /// <summary>
/// Writes the pre-encoded property name and pre-encoded value (as a JSON string) as part of a name/value pair of a JSON object.
/// </summary>
/// <param name="propertyName">The JSON encoded property name of the JSON object to be transcoded and written as UTF-8.</param>
output[BytesPending++] = JsonConstants.ListSeparator;
}
+ Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName);
+
if (_tokenType != JsonTokenType.None)
{
WriteNewLine(output);
output[BytesPending++] = JsonConstants.ListSeparator;
}
+ Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName);
+
if (_tokenType != JsonTokenType.None)
{
WriteNewLine(output);
output[BytesPending++] = JsonConstants.ListSeparator;
}
+ Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName);
+
if (_tokenType != JsonTokenType.None)
{
WriteNewLine(output);
output[BytesPending++] = JsonConstants.ListSeparator;
}
+ Debug.Assert(Options.SkipValidation || _tokenType != JsonTokenType.PropertyName);
+
if (_tokenType != JsonTokenType.None)
{
WriteNewLine(output);
Assert.Equal(2, stream.Position);
}
-#if !netfx
[Theory]
[InlineData(true, true)]
[InlineData(true, false)]
Assert.Equal(0, writeToStream.BytesCommitted);
Assert.Equal(2, stream.Position);
}
-#endif
[Theory]
[InlineData(true, true)]
Assert.Throws<ObjectDisposedException>(() => jsonUtf8.Reset(output));
}
-#if !netfx
[Theory]
[InlineData(true, true)]
[InlineData(true, false)]
Assert.Throws<ObjectDisposedException>(() => jsonUtf8.Reset(output));
}
-#endif
[Theory]
[InlineData(true, true)]
{
const int SyncWriteThreshold = 25_000;
-#if !netfx
- await
-#endif
- using var jsonUtf8 = new Utf8JsonWriter(stream, options);
+ await using var jsonUtf8 = new Utf8JsonWriter(stream, options);
byte[] utf8String = Encoding.UTF8.GetBytes("some string 1234");
}
jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ if (skipValidation)
+ {
+ jsonUtf8.WriteStartArray();
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteStartArray());
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
jsonUtf8.WriteStartArray();
jsonUtf8.WriteStartArray();
jsonUtf8.WriteEndArray();
{
Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteEndArray());
}
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ jsonUtf8.WritePropertyName(JsonEncodedText.Encode("test name"));
+ jsonUtf8.WritePropertyName("test name".AsSpan());
+ jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes("test name"));
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName(JsonEncodedText.Encode("test name")));
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name".AsSpan()));
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes("test name")));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartArray();
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ jsonUtf8.WritePropertyName("first name");
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ jsonUtf8.WritePropertyName("first name");
+ if (skipValidation)
+ {
+ jsonUtf8.WriteStartArray("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteStartArray("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ jsonUtf8.WritePropertyName("first name");
+ if (skipValidation)
+ {
+ jsonUtf8.WriteStartObject("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteStartObject("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ jsonUtf8.WritePropertyName("first name");
+ if (skipValidation)
+ {
+ jsonUtf8.WriteEndObject();
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteEndObject());
+ }
}
[Theory]
{
Assert.Throws<InvalidOperationException>(() => jsonUtf8.WriteEndObject());
}
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteNumberValue(12345);
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteBooleanValue(true);
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteNullValue();
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ }
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStringValue("some string");
+ if (skipValidation)
+ {
+ jsonUtf8.WritePropertyName("test name");
+ }
+ else
+ {
+ Assert.Throws<InvalidOperationException>(() => jsonUtf8.WritePropertyName("test name"));
+ }
}
[Theory]
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(false, false)]
+ public void WriteSeparateProperties(bool formatted, bool skipValidation)
+ {
+ var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
+ var output = new ArrayBufferWriter<byte>(1024);
+
+ var stringWriter = new StringWriter();
+ var json = new JsonTextWriter(stringWriter)
+ {
+ Formatting = formatted ? Formatting.Indented : Formatting.None,
+ };
+
+ json.WriteStartObject();
+ json.WritePropertyName("foo1");
+ json.WriteValue("bar1");
+ json.WritePropertyName("foo2");
+ json.WriteValue("bar2");
+ json.WritePropertyName("foo3");
+ json.WriteValue("bar3");
+ json.WritePropertyName("foo4");
+ json.WriteValue("bar4");
+ json.WritePropertyName("array");
+ json.WriteStartArray();
+ json.WriteEndArray();
+ json.WriteEnd();
+
+ json.Flush();
+
+ string expectedStr = stringWriter.ToString();
+
+ var jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes("foo1"));
+ jsonUtf8.WriteStringValue("bar1");
+ jsonUtf8.WritePropertyName("foo2");
+ jsonUtf8.WriteStringValue("bar2");
+ jsonUtf8.WritePropertyName(JsonEncodedText.Encode("foo3"));
+ jsonUtf8.WriteStringValue("bar3");
+ jsonUtf8.WritePropertyName("foo4".AsSpan());
+ jsonUtf8.WriteStringValue("bar4");
+ jsonUtf8.WritePropertyName("array");
+ jsonUtf8.WriteStartArray();
+ jsonUtf8.WriteEndArray();
+ jsonUtf8.WriteEndObject();
+ jsonUtf8.Flush();
+ Assert.Equal(expectedStr, Encoding.UTF8.GetString(output.WrittenMemory.ToArray()));
+ }
+
+ [Theory]
+ [InlineData(true, true)]
+ [InlineData(true, false)]
+ [InlineData(false, true)]
+ [InlineData(false, false)]
public void WritingTooDeep(bool formatted, bool skipValidation)
{
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(false, false)]
+ public void WritingTooLargePropertyStandalone(bool formatted, bool skipValidation)
+ {
+ byte[] key;
+ char[] keyChars;
+
+ try
+ {
+ key = new byte[1_000_000_000];
+ keyChars = new char[1_000_000_000];
+ }
+ catch (OutOfMemoryException)
+ {
+ return;
+ }
+
+ key.AsSpan().Fill((byte)'a');
+ keyChars.AsSpan().Fill('a');
+
+ var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
+ var output = new ArrayBufferWriter<byte>(1024);
+
+ var jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WritePropertyName(keyChars));
+
+ jsonUtf8 = new Utf8JsonWriter(output, options);
+ jsonUtf8.WriteStartObject();
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WritePropertyName(key));
+ }
+
+ [ConditionalTheory(nameof(IsX64))]
+ [OuterLoop]
+ [InlineData(true, true)]
+ [InlineData(true, false)]
+ [InlineData(false, true)]
+ [InlineData(false, false)]
public void WritingTooLargeBase64Bytes(bool formatted, bool skipValidation)
{
byte[] value;
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 16; i++)
+ for (int i = 0; i < 32; i++)
{
var output = new ArrayBufferWriter<byte>(32);
var jsonUtf8 = new Utf8JsonWriter(output, options);
jsonUtf8.WriteString(utf8PropertyName, encodedValue);
jsonUtf8.WriteString(utf8PropertyName, encodedValue);
break;
+ case 16:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 17:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 18:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(utf8Value);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(utf8Value);
+ break;
+ case 19:
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 20:
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 21:
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(utf8Value);
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(utf8Value);
+ break;
+ case 22:
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 23:
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 24:
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(utf8Value);
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(utf8Value);
+ break;
+ case 25:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 26:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 27:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(utf8Value);
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(utf8Value);
+ break;
+ case 28:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 29:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 30:
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 31:
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(utf8PropertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
}
jsonUtf8.WriteEndObject();
JsonEncodedText encodedPropertyName = JsonEncodedText.Encode(propertyName);
JsonEncodedText encodedValue = JsonEncodedText.Encode(value);
- for (int i = 0; i < 16; i++)
+ for (int i = 0; i < 32; i++)
{
var output = new ArrayBufferWriter<byte>(32);
var jsonUtf8 = new Utf8JsonWriter(output, options);
jsonUtf8.WriteString(propertyNameSpanUtf8, encodedValue);
jsonUtf8.WriteString(propertyNameSpanUtf8, encodedValue);
break;
+ case 16:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 17:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(valueSpan);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(valueSpan);
+ break;
+ case 18:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ break;
+ case 19:
+ jsonUtf8.WritePropertyName(propertyNameSpan);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(propertyNameSpan);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 20:
+ jsonUtf8.WritePropertyName(propertyNameSpan);
+ jsonUtf8.WriteStringValue(valueSpan);
+ jsonUtf8.WritePropertyName(propertyNameSpan);
+ jsonUtf8.WriteStringValue(valueSpan);
+ break;
+ case 21:
+ jsonUtf8.WritePropertyName(propertyNameSpan);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ jsonUtf8.WritePropertyName(propertyNameSpan);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ break;
+ case 22:
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 23:
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(valueSpan);
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(valueSpan);
+ break;
+ case 24:
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ break;
+ case 25:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value);
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 26:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 27:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(valueSpanUtf8);
+ break;
+ case 28:
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(encodedPropertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 29:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 30:
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(propertyName.AsSpan());
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 31:
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(encodedValue);
+ jsonUtf8.WritePropertyName(propertyNameSpanUtf8);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
}
jsonUtf8.WriteEndObject();
JsonEncodedText encodedKey = JsonEncodedText.Encode(key);
JsonEncodedText encodedValue = JsonEncodedText.Encode(value);
- for (int i = 0; i < 16; i++)
+ for (int i = 0; i < 32; i++)
{
var output = new ArrayBufferWriter<byte>(1024);
var jsonUtf8 = new Utf8JsonWriter(output, options);
case 15:
jsonUtf8.WriteString(keyUtf8, encodedValue);
break;
+ case 16:
+ jsonUtf8.WritePropertyName(key);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 17:
+ jsonUtf8.WritePropertyName(key);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 18:
+ jsonUtf8.WritePropertyName(key);
+ jsonUtf8.WriteStringValue(valueUtf8);
+ break;
+ case 19:
+ jsonUtf8.WritePropertyName(key.AsSpan());
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 20:
+ jsonUtf8.WritePropertyName(key.AsSpan());
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 21:
+ jsonUtf8.WritePropertyName(key.AsSpan());
+ jsonUtf8.WriteStringValue(valueUtf8);
+ break;
+ case 22:
+ jsonUtf8.WritePropertyName(keyUtf8);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 23:
+ jsonUtf8.WritePropertyName(keyUtf8);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 24:
+ jsonUtf8.WritePropertyName(keyUtf8);
+ jsonUtf8.WriteStringValue(valueUtf8);
+ break;
+ case 25:
+ jsonUtf8.WritePropertyName(encodedKey);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 26:
+ jsonUtf8.WritePropertyName(encodedKey);
+ jsonUtf8.WriteStringValue(value.AsSpan());
+ break;
+ case 27:
+ jsonUtf8.WritePropertyName(encodedKey);
+ jsonUtf8.WriteStringValue(valueUtf8);
+ break;
+ case 28:
+ jsonUtf8.WritePropertyName(encodedKey);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 29:
+ jsonUtf8.WritePropertyName(key);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 30:
+ jsonUtf8.WritePropertyName(key.AsSpan());
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
+ case 31:
+ jsonUtf8.WritePropertyName(keyUtf8);
+ jsonUtf8.WriteStringValue(encodedValue);
+ break;
}
jsonUtf8.WriteEndObject();
string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml);
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 6; i++)
{
var output = new ArrayBufferWriter<byte>(1024);
var jsonUtf8 = new Utf8JsonWriter(output, options);
case 2:
jsonUtf8.WriteString(JsonEncodedText.Encode(propertyName), JsonEncodedText.Encode(value));
break;
+ case 3:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 4:
+ jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes(propertyName));
+ jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value));
+ break;
+ case 5:
+ jsonUtf8.WritePropertyName(JsonEncodedText.Encode(propertyName));
+ jsonUtf8.WriteStringValue(JsonEncodedText.Encode(value));
+ break;
}
jsonUtf8.WriteEndObject();
string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii);
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 6; i++)
{
var output = new ArrayBufferWriter<byte>(1024);
var jsonUtf8 = new Utf8JsonWriter(output, options);
case 2:
jsonUtf8.WriteString(JsonEncodedText.Encode(propertyName), JsonEncodedText.Encode(value));
break;
+ case 3:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 4:
+ jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes(propertyName));
+ jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value));
+ break;
+ case 5:
+ jsonUtf8.WritePropertyName(JsonEncodedText.Encode(propertyName));
+ jsonUtf8.WriteStringValue(JsonEncodedText.Encode(value));
+ break;
}
jsonUtf8.WriteEndObject();
string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii);
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 6; i++)
{
var output = new ArrayBufferWriter<byte>(1024);
var jsonUtf8 = new Utf8JsonWriter(output, options);
case 2:
jsonUtf8.WriteString(JsonEncodedText.Encode(propertyName), JsonEncodedText.Encode(value));
break;
+ case 3:
+ jsonUtf8.WritePropertyName(propertyName);
+ jsonUtf8.WriteStringValue(value);
+ break;
+ case 4:
+ jsonUtf8.WritePropertyName(Encoding.UTF8.GetBytes(propertyName));
+ jsonUtf8.WriteStringValue(Encoding.UTF8.GetBytes(value));
+ break;
+ case 5:
+ jsonUtf8.WritePropertyName(JsonEncodedText.Encode(propertyName));
+ jsonUtf8.WriteStringValue(JsonEncodedText.Encode(value));
+ break;
}
jsonUtf8.WriteEndObject();
var invalidUtf8 = new byte[2] { 0xc3, 0x28 };
jsonUtf8.WriteStartObject();
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 6; i++)
{
switch (i)
{
case 3:
jsonUtf8.WriteString(validUtf8, validUtf8);
break;
+ case 4:
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WritePropertyName(invalidUtf8));
+ break;
+ case 5:
+ jsonUtf8.WritePropertyName(validUtf8);
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WriteStringValue(invalidUtf8));
+ jsonUtf8.WriteStringValue(validUtf8);
+ break;
+ case 6:
+ jsonUtf8.WritePropertyName(validUtf8);
+ jsonUtf8.WriteStringValue(validUtf8);
+ break;
}
}
jsonUtf8.WriteEndObject();
var invalidUtf16 = new char[2] { (char)0xD801, 'a' };
jsonUtf8.WriteStartObject();
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 7; i++)
{
switch (i)
{
case 3:
jsonUtf8.WriteString(validUtf16, validUtf16);
break;
+ case 4:
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WritePropertyName(invalidUtf16));
+ break;
+ case 5:
+ jsonUtf8.WritePropertyName(validUtf16);
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WriteStringValue(invalidUtf16));
+ jsonUtf8.WriteStringValue(validUtf16);
+ break;
+ case 6:
+ jsonUtf8.WritePropertyName(validUtf16);
+ jsonUtf8.WriteStringValue(validUtf16);
+ break;
}
}
jsonUtf8.WriteEndObject();
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 4; i++)
{
var output = new ArrayBufferWriter<byte>(1024);
var jsonUtf8 = new Utf8JsonWriter(output, options);
case 2:
jsonUtf8.WriteBoolean(Encoding.UTF8.GetBytes(keyString), value);
break;
+ case 3:
+ jsonUtf8.WritePropertyName(keyString);
+ jsonUtf8.WriteBooleanValue(value);
+ break;
}
jsonUtf8.WriteStartArray("temp");
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 4; i++)
{
var output = new ArrayBufferWriter<byte>(16);
var jsonUtf8 = new Utf8JsonWriter(output, options);
jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString));
jsonUtf8.WriteNull(Encoding.UTF8.GetBytes(keyString));
break;
+ case 3:
+ jsonUtf8.WritePropertyName(keyString);
+ jsonUtf8.WriteNullValue();
+ jsonUtf8.WritePropertyName(keyString);
+ jsonUtf8.WriteNullValue();
+ break;
}
jsonUtf8.WriteStartArray("temp");
var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation };
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 4; i++)
{
var output = new ArrayBufferWriter<byte>(1024);
var jsonUtf8 = new Utf8JsonWriter(output, options);
case 2:
jsonUtf8.WriteNumber(Encoding.UTF8.GetBytes("message"), value);
break;
+ case 3:
+ jsonUtf8.WritePropertyName("message");
+ jsonUtf8.WriteNumberValue(value);
+ break;
}
jsonUtf8.WriteEndObject();
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteNumber(bytesTooLarge, (ulong)12345678901));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteBoolean(bytesTooLarge, true));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteNull(bytesTooLarge));
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WritePropertyName(bytesTooLarge));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteStartObject(charsTooLarge));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteString(charsTooLarge, chars));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteNumber(charsTooLarge, (ulong)12345678901));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteBoolean(charsTooLarge, true));
Assert.Throws<ArgumentException>(() => jsonUtf8.WriteNull(charsTooLarge));
+ Assert.Throws<ArgumentException>(() => jsonUtf8.WritePropertyName(charsTooLarge));
jsonUtf8.Flush();
Assert.Equal(1, jsonUtf8.BytesCommitted);