in Microsoft.Azure.Cosmos/src/Json/JsonWriter.JsonBinaryWriter.cs [1376:1475]
private void WriteFieldNameOrString(bool isFieldName, Utf8Span utf8Span)
{
this.binaryWriter.EnsureRemainingBufferSpace(TypeMarkerLength + JsonBinaryEncoding.FourByteLength + utf8Span.Length);
this.JsonObjectState.RegisterToken(isFieldName ? JsonTokenType.FieldName : JsonTokenType.String);
if (JsonBinaryEncoding.TryGetEncodedStringTypeMarker(
utf8Span,
this.JsonObjectState.CurrentTokenType == JsonTokenType.FieldName ? this.jsonStringDictionary : null,
out JsonBinaryEncoding.MultiByteTypeMarker multiByteTypeMarker))
{
switch (multiByteTypeMarker.Length)
{
case 1:
this.binaryWriter.Write(multiByteTypeMarker.One);
break;
case 2:
this.binaryWriter.Write(multiByteTypeMarker.One);
this.binaryWriter.Write(multiByteTypeMarker.Two);
break;
default:
throw new InvalidOperationException($"Unable to serialize a {nameof(JsonBinaryEncoding.MultiByteTypeMarker)} of length: {multiByteTypeMarker.Length}");
}
}
else if (this.enableEncodedStrings
&& isFieldName
&& (utf8Span.Length >= MinReferenceStringLength)
&& this.TryRegisterStringValue(utf8Span))
{
// Work is done in the check
}
else if (this.enableEncodedStrings
&& !isFieldName
&& (utf8Span.Length == JsonBinaryEncoding.GuidLength)
&& JsonBinaryEncoding.TryEncodeGuidString(utf8Span.Span, this.binaryWriter.Cursor))
{
// Encoded value as guid string
this.binaryWriter.Position += JsonBinaryEncoding.EncodedGuidLength;
}
else if (this.enableEncodedStrings
&& !isFieldName
&& (utf8Span.Length == JsonBinaryEncoding.GuidWithQuotesLength)
&& (utf8Span.Span[0] == '"')
&& (utf8Span.Span[JsonBinaryEncoding.GuidWithQuotesLength - 1] == '"')
&& JsonBinaryEncoding.TryEncodeGuidString(utf8Span.Span.Slice(start: 1), this.binaryWriter.Cursor)
&& (this.binaryWriter.Cursor[0] == TypeMarker.LowercaseGuidString))
{
// Encoded value as lowercase double quote guid
this.binaryWriter.Cursor[0] = TypeMarker.DoubleQuotedLowercaseGuidString;
this.binaryWriter.Position += JsonBinaryEncoding.EncodedGuidLength;
}
else if (this.enableEncodedStrings
&& !isFieldName
&& JsonBinaryEncoding.TryEncodeCompressedString(utf8Span.Span, this.binaryWriter.Cursor, out int bytesWritten))
{
// Encoded value as a compressed string
this.binaryWriter.Position += bytesWritten;
}
else if (this.enableEncodedStrings
&& !isFieldName
&& (utf8Span.Length >= MinReferenceStringLength)
&& (utf8Span.Length <= MaxReferenceStringLength)
&& this.TryRegisterStringValue(utf8Span))
{
// Work is done in the check
}
else if (TypeMarker.TryGetEncodedStringLengthTypeMarker(utf8Span.Length, out byte typeMarker))
{
// Write with type marker that encodes the length
this.binaryWriter.Write(typeMarker);
this.binaryWriter.Write(utf8Span.Span);
}
// Just write it out as a regular string with type marker and length prefix
else if (utf8Span.Length < byte.MaxValue)
{
this.binaryWriter.Write(TypeMarker.StrL1);
this.binaryWriter.Write((byte)utf8Span.Length);
this.binaryWriter.Write(utf8Span.Span);
}
else if (utf8Span.Length < ushort.MaxValue)
{
this.binaryWriter.Write(TypeMarker.StrL2);
this.binaryWriter.Write((ushort)utf8Span.Length);
this.binaryWriter.Write(utf8Span.Span);
}
else
{
// (utf8String.Length < uint.MaxValue)
this.binaryWriter.Write(TypeMarker.StrL4);
this.binaryWriter.Write((uint)utf8Span.Length);
this.binaryWriter.Write(utf8Span.Span);
}
if (!isFieldName)
{
// If we just wrote a string then increment the count (we don't increment for field names, since we need to wait for the corresponding property value).
this.bufferedContexts.Peek().Count++;
}
}