private void WriteFieldNameOrString(bool isFieldName, ReadOnlySpan <byte> utf8String) { // String dictionary encoding is currently performed only for field names. // This would be changed later, so that the writer can control which strings need to be encoded. this.JsonObjectState.RegisterToken(isFieldName ? JsonTokenType.FieldName : JsonTokenType.String); if (JsonBinaryEncoding.TryGetEncodedStringTypeMarker( utf8String, 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 ArgumentOutOfRangeException($"Unable to serialize a {nameof(JsonBinaryEncoding.MultiByteTypeMarker)} of length: {multiByteTypeMarker.Length}"); } } else { // See if the string length can be encoded into a single type marker byte typeMarker = JsonBinaryEncoding.TypeMarker.GetEncodedStringLengthTypeMarker(utf8String.Length); if (JsonBinaryEncoding.TypeMarker.IsValid(typeMarker)) { this.binaryWriter.Write(typeMarker); } else { // Just write the type marker and the corresponding length if (utf8String.Length < byte.MaxValue) { this.binaryWriter.Write(JsonBinaryEncoding.TypeMarker.String1ByteLength); this.binaryWriter.Write((byte)utf8String.Length); } else if (utf8String.Length < ushort.MaxValue) { this.binaryWriter.Write(JsonBinaryEncoding.TypeMarker.String2ByteLength); this.binaryWriter.Write((ushort)utf8String.Length); } else { // (utf8String.Length < uint.MaxValue) this.binaryWriter.Write(JsonBinaryEncoding.TypeMarker.String4ByteLength); this.binaryWriter.Write((uint)utf8String.Length); } } // Finally write the string itself. this.binaryWriter.Write(utf8String); } 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++; } }