writer.WriteEndArray();
continue;
case JsonTokenType.PropertyName:
- {
- DbRow propertyValue = _parsedData.Get(i + DbRow.Size);
-
- ReadOnlySpan<byte> propertyName =
- _utf8Json.Slice(row.Location, row.SizeOrLength).Span;
-
- // "Move" to the value.
- i += DbRow.Size;
-
- switch (propertyValue.TokenType)
- {
- case JsonTokenType.String:
- WriteString(propertyName, propertyValue, writer);
- continue;
- case JsonTokenType.Number:
- writer.WriteNumber(
- propertyName,
- _utf8Json.Slice(propertyValue.Location, propertyValue.SizeOrLength).Span);
- continue;
- case JsonTokenType.True:
- writer.WriteBoolean(propertyName, value: true);
- continue;
- case JsonTokenType.False:
- writer.WriteBoolean(propertyName, value: false);
- continue;
- case JsonTokenType.Null:
- writer.WriteNull(propertyName);
- continue;
- case JsonTokenType.StartObject:
- writer.WriteStartObject(propertyName);
- continue;
- case JsonTokenType.StartArray:
- writer.WriteStartArray(propertyName);
- continue;
- }
-
- Debug.Fail($"Unexpected encounter with JsonTokenType {row.TokenType}");
- break;
- }
+ WritePropertyName(row, writer);
+ continue;
}
Debug.Fail($"Unexpected encounter with JsonTokenType {row.TokenType}");
private ReadOnlySpan<byte> UnescapeString(in DbRow row, out ArraySegment<byte> rented)
{
- Debug.Assert(row.TokenType == JsonTokenType.String);
+ Debug.Assert(row.TokenType == JsonTokenType.String || row.TokenType == JsonTokenType.PropertyName);
int loc = row.Location;
int length = row.SizeOrLength;
ReadOnlySpan<byte> text = _utf8Json.Slice(loc, length).Span;
}
}
- private void WriteString(ReadOnlySpan<byte> propertyName, in DbRow row, Utf8JsonWriter writer)
+ private void WritePropertyName(in DbRow row, Utf8JsonWriter writer)
{
ArraySegment<byte> rented = default;
try
{
- writer.WriteString(
- propertyName,
- UnescapeString(row, out rented));
+ writer.WritePropertyName(UnescapeString(row, out rented));
}
finally
{
[Theory]
[InlineData(false)]
[InlineData(true)]
+ public void ReadWriteEscapedPropertyNames(bool indented)
+ {
+ const string jsonIn = " { \"p\\u0069zza\": 1, \"hello\\u003c\\u003e\": 2, \"normal\": 3 }";
+
+ WriteComplexValue(
+ indented,
+ jsonIn,
+ @"{
+ ""pizza"": 1,
+ ""hello\u003c\u003e"": 2,
+ ""normal"": 3
+}",
+ "{\"pizza\":1,\"hello\\u003c\\u003e\":2,\"normal\":3}");
+ }
+
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
public void WriteNumberAsProperty(bool indented)
{
WritePropertyValueBothForms(
string expectedMinimal)
{
var buffer = new ArrayBufferWriter<byte>(1024);
+ byte[] bufferOutput;
- using (JsonDocument doc = PrepareDocument(jsonIn))
+ var options = new JsonWriterOptions
{
- var options = new JsonWriterOptions
- {
- Indented = indented
- };
+ Indented = indented
+ };
+ using (JsonDocument doc = PrepareDocument(jsonIn))
+ {
using (var writer = new Utf8JsonWriter(buffer, options))
{
WriteSingleValue(doc, writer);
}
JsonTestHelper.AssertContents(indented ? expectedIndent : expectedMinimal, buffer);
+
+ bufferOutput = buffer.WrittenSpan.ToArray();
+ }
+
+ // After reading the output and writing it again, it should be byte-for-byte identical.
+ {
+ string bufferString = Encoding.UTF8.GetString(bufferOutput);
+ buffer.Clear();
+
+ using (JsonDocument doc2 = PrepareDocument(bufferString))
+ {
+ using (var writer = new Utf8JsonWriter(buffer, options))
+ {
+ WriteSingleValue(doc2, writer);
+ }
+ }
+
+ Assert.True(buffer.WrittenSpan.SequenceEqual(bufferOutput));
}
}