DefaultUrlEncoder
using System.Buffers;
using System.Text.Unicode;
namespace System.Text.Encodings.Web
{
internal sealed class DefaultUrlEncoder : UrlEncoder
{
private sealed class EscaperImplementation : ScalarEscaperBase
{
internal static readonly EscaperImplementation Singleton = new EscaperImplementation();
private EscaperImplementation()
{
}
internal override int EncodeUtf8(System.Text.Rune value, Span<byte> destination)
{
uint utf8RepresentationForScalarValue = (uint)UnicodeHelpers.GetUtf8RepresentationForScalarValue((uint)value.Value);
if (SpanUtility.IsValidIndex(destination, 2)) {
destination[0] = 37;
System.HexConverter.ToBytesBuffer((byte)utf8RepresentationForScalarValue, destination, 1, System.HexConverter.Casing.Upper);
if ((utf8RepresentationForScalarValue >>= 8) == 0)
return 3;
if (SpanUtility.IsValidIndex(destination, 5)) {
destination[3] = 37;
System.HexConverter.ToBytesBuffer((byte)utf8RepresentationForScalarValue, destination, 4, System.HexConverter.Casing.Upper);
if ((utf8RepresentationForScalarValue >>= 8) == 0)
return 6;
if (SpanUtility.IsValidIndex(destination, 8)) {
destination[6] = 37;
System.HexConverter.ToBytesBuffer((byte)utf8RepresentationForScalarValue, destination, 7, System.HexConverter.Casing.Upper);
if ((utf8RepresentationForScalarValue >>= 8) == 0)
return 9;
if (SpanUtility.IsValidIndex(destination, 11)) {
destination[9] = 37;
System.HexConverter.ToBytesBuffer((byte)utf8RepresentationForScalarValue, destination, 10, System.HexConverter.Casing.Upper);
return 12;
}
}
}
}
return -1;
}
internal override int EncodeUtf16(System.Text.Rune value, Span<char> destination)
{
uint utf8RepresentationForScalarValue = (uint)UnicodeHelpers.GetUtf8RepresentationForScalarValue((uint)value.Value);
if (SpanUtility.IsValidIndex(destination, 2)) {
destination[0] = '%';
System.HexConverter.ToCharsBuffer((byte)utf8RepresentationForScalarValue, destination, 1, System.HexConverter.Casing.Upper);
if ((utf8RepresentationForScalarValue >>= 8) == 0)
return 3;
if (SpanUtility.IsValidIndex(destination, 5)) {
destination[3] = '%';
System.HexConverter.ToCharsBuffer((byte)utf8RepresentationForScalarValue, destination, 4, System.HexConverter.Casing.Upper);
if ((utf8RepresentationForScalarValue >>= 8) == 0)
return 6;
if (SpanUtility.IsValidIndex(destination, 8)) {
destination[6] = '%';
System.HexConverter.ToCharsBuffer((byte)utf8RepresentationForScalarValue, destination, 7, System.HexConverter.Casing.Upper);
if ((utf8RepresentationForScalarValue >>= 8) == 0)
return 9;
if (SpanUtility.IsValidIndex(destination, 11)) {
destination[9] = '%';
System.HexConverter.ToCharsBuffer((byte)utf8RepresentationForScalarValue, destination, 10, System.HexConverter.Casing.Upper);
return 12;
}
}
}
}
return -1;
}
}
internal static readonly DefaultUrlEncoder BasicLatinSingleton = new DefaultUrlEncoder(new TextEncoderSettings(UnicodeRanges.BasicLatin));
private readonly OptimizedInboxTextEncoder _innerEncoder;
public override int MaxOutputCharactersPerInputCharacter => 9;
internal DefaultUrlEncoder(TextEncoderSettings settings)
{
if (settings == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.settings);
EscaperImplementation singleton = EscaperImplementation.Singleton;
ref AllowedBmpCodePointsBitmap allowedCodePointsBitmap = ref settings.GetAllowedCodePointsBitmap();
object obj = global::<PrivateImplementationDetails>.40DFDA6D4ED43D4879E2A200D2471641FC15E1C25DAB5D4D491BD811F7727FCC_A1;
if (obj == null) {
obj = new char[31] {
' ',
'#',
'%',
'/',
':',
'=',
'?',
'[',
'\\',
']',
'^',
'`',
'{',
'|',
'}',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'',
'�',
'',
''
};
global::<PrivateImplementationDetails>.40DFDA6D4ED43D4879E2A200D2471641FC15E1C25DAB5D4D491BD811F7727FCC_A1 = (char[])obj;
}
_innerEncoder = new OptimizedInboxTextEncoder(singleton, ref allowedCodePointsBitmap, true, new ReadOnlySpan<char>((char[])obj));
}
private protected override OperationStatus EncodeCore(ReadOnlySpan<char> source, Span<char> destination, out int charsConsumed, out int charsWritten, bool isFinalBlock)
{
return _innerEncoder.Encode(source, destination, out charsConsumed, out charsWritten, isFinalBlock);
}
private protected override OperationStatus EncodeUtf8Core(ReadOnlySpan<byte> utf8Source, Span<byte> utf8Destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock)
{
return _innerEncoder.EncodeUtf8(utf8Source, utf8Destination, out bytesConsumed, out bytesWritten, isFinalBlock);
}
private protected override int FindFirstCharacterToEncode(ReadOnlySpan<char> text)
{
return _innerEncoder.GetIndexOfFirstCharToEncode(text);
}
public unsafe override int FindFirstCharacterToEncode(char* text, int textLength)
{
return _innerEncoder.FindFirstCharacterToEncode(text, textLength);
}
public override int FindFirstCharacterToEncodeUtf8(ReadOnlySpan<byte> utf8Text)
{
return _innerEncoder.GetIndexOfFirstByteToEncode(utf8Text);
}
public unsafe override bool TryEncodeUnicodeScalar(int unicodeScalar, char* buffer, int bufferLength, out int numberOfCharactersWritten)
{
return _innerEncoder.TryEncodeUnicodeScalar(unicodeScalar, buffer, bufferLength, out numberOfCharactersWritten);
}
public override bool WillEncode(int unicodeScalar)
{
return !_innerEncoder.IsScalarValueAllowed(new System.Text.Rune(unicodeScalar));
}
}
}