in Microsoft.Azure.Cosmos/src/Json/JsonBinaryEncoding.Strings.cs [994:1127]
private static bool EncodedStringEqualsTo(byte typeMarker, ReadOnlySpan<byte> encodedStringValue, ReadOnlySpan<byte> stringValue)
{
if (encodedStringValue.Length != GetEncodedStringValueLength(stringValue))
{
return false;
}
switch (typeMarker)
{
case JsonBinaryEncoding.TypeMarker.CompressedLowercaseHexString:
case JsonBinaryEncoding.TypeMarker.CompressedUppercaseHexString:
case JsonBinaryEncoding.TypeMarker.CompressedDateTimeString:
{
encodedStringValue = encodedStringValue.Slice(start: 2);
Span<byte> buffer = stackalloc byte[8];
int index = 0;
for (; index < stringValue.Length / 8 * 8; index++)
{
if (typeMarker == JsonBinaryEncoding.TypeMarker.CompressedLowercaseHexString)
{
Decode4BitCharacterStringValue(StringCompressionLookupTables.LowercaseHex, encodedStringValue, buffer);
}
else if (typeMarker == JsonBinaryEncoding.TypeMarker.CompressedUppercaseHexString)
{
Decode4BitCharacterStringValue(StringCompressionLookupTables.UppercaseHex, encodedStringValue, buffer);
}
else
{
Decode4BitCharacterStringValue(StringCompressionLookupTables.DateTime, encodedStringValue, buffer);
}
if (!buffer.SequenceEqual(stringValue.Slice(start: 0, length: 8)))
{
return false;
}
stringValue = stringValue.Slice(start: 8);
encodedStringValue = encodedStringValue.Slice(start: 4);
}
if (index < stringValue.Length)
{
Span<byte> input = stackalloc byte[8];
encodedStringValue.CopyTo(input);
if (typeMarker == JsonBinaryEncoding.TypeMarker.CompressedLowercaseHexString)
{
Decode4BitCharacterStringValue(StringCompressionLookupTables.LowercaseHex, input, buffer);
}
else if (typeMarker == JsonBinaryEncoding.TypeMarker.CompressedUppercaseHexString)
{
Decode4BitCharacterStringValue(StringCompressionLookupTables.UppercaseHex, input, buffer);
}
else
{
Decode4BitCharacterStringValue(StringCompressionLookupTables.DateTime, input, buffer);
}
return input.SequenceEqual(stringValue.Slice(start: index));
}
return true;
}
case JsonBinaryEncoding.TypeMarker.Packed4BitString:
case JsonBinaryEncoding.TypeMarker.Packed5BitString:
case JsonBinaryEncoding.TypeMarker.Packed6BitString:
case JsonBinaryEncoding.TypeMarker.Packed7BitStringLength1:
case JsonBinaryEncoding.TypeMarker.Packed7BitStringLength2:
{
byte numberOfBits = typeMarker switch
{
JsonBinaryEncoding.TypeMarker.Packed4BitString => 4,
JsonBinaryEncoding.TypeMarker.Packed5BitString => 5,
JsonBinaryEncoding.TypeMarker.Packed6BitString => 6,
_ => 7,
};
byte baseChar = GetEncodedStringBaseChar(stringValue);
encodedStringValue = encodedStringValue.Slice(start: (typeMarker == JsonBinaryEncoding.TypeMarker.Packed7BitStringLength1) ? 2 : 3);
Span<byte> buffer = stackalloc byte[8];
int index = 0;
for (; index < stringValue.Length / 8 * 8; index++)
{
DecodeCompressedStringValue(numberOfBits, encodedStringValue, baseChar, buffer);
if (!buffer.SequenceEqual(stringValue.Slice(start: 0, length: 8)))
{
return false;
}
stringValue = stringValue.Slice(start: 8);
encodedStringValue = encodedStringValue.Slice(start: numberOfBits);
}
if (index < stringValue.Length)
{
Span<byte> input = stackalloc byte[8];
encodedStringValue.CopyTo(input);
DecodeCompressedStringValue(numberOfBits, input, baseChar, buffer);
return buffer.SequenceEqual(stringValue.Slice(start: 0, length: 8));
}
return true;
}
case JsonBinaryEncoding.TypeMarker.LowercaseGuidString:
case JsonBinaryEncoding.TypeMarker.UppercaseGuidString:
{
Span<byte> guidBuffer = stackalloc byte[GuidLength];
DecodeGuidStringValue(encodedStringValue, isUpperCaseGuid: typeMarker == JsonBinaryEncoding.TypeMarker.UppercaseGuidString, guidBuffer);
return guidBuffer.SequenceEqual(stringValue);
}
case JsonBinaryEncoding.TypeMarker.DoubleQuotedLowercaseGuidString:
{
if ((stringValue[0] != '"') || (stringValue[GuidWithQuotesLength - 1] != '"'))
{
return false;
}
Span<byte> guidBuffer = stackalloc byte[GuidLength];
DecodeGuidStringValue(encodedStringValue, isUpperCaseGuid: false, guidBuffer);
return guidBuffer.SequenceEqual(stringValue.Slice(start: 1, length: stringValue.Length - 2));
}
default:
throw new ArgumentOutOfRangeException($"Unrecognized {nameof(typeMarker)}: {typeMarker}.");
}
}