Skip to content

Commit

Permalink
Use char type direcly instead of ushort, as we are not using vectoriz…
Browse files Browse the repository at this point in the history
…ation
  • Loading branch information
buyaa-n committed Jun 19, 2024
1 parent d55a57c commit c1c586b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -853,9 +853,9 @@ public static byte[] DecodeFromUtf8(ReadOnlySpan<byte> source)
/// </remarks>
public static OperationStatus DecodeFromChars(ReadOnlySpan<char> source, Span<byte> destination,
out int charsConsumed, out int bytesWritten, bool isFinalBlock = true) =>
DecodeFromChars(MemoryMarshal.Cast<char, ushort>(source), destination, out charsConsumed, out bytesWritten, isFinalBlock, ignoreWhiteSpace: true);
DecodeFromChars(source, destination, out charsConsumed, out bytesWritten, isFinalBlock, ignoreWhiteSpace: true);

private static unsafe OperationStatus DecodeFromChars(ReadOnlySpan<ushort> source, Span<byte> bytes,
private static unsafe OperationStatus DecodeFromChars(ReadOnlySpan<char> source, Span<byte> bytes,
out int bytesConsumed, out int bytesWritten, bool isFinalBlock, bool ignoreWhiteSpace)
{
if (source.IsEmpty)
Expand All @@ -865,18 +865,18 @@ private static unsafe OperationStatus DecodeFromChars(ReadOnlySpan<ushort> sourc
return OperationStatus.Done;
}

fixed (ushort* srcBytes = &MemoryMarshal.GetReference(source))
fixed (char* srcBytes = &MemoryMarshal.GetReference(source))
fixed (byte* destBytes = &MemoryMarshal.GetReference(bytes))
{
int srcLength = isFinalBlock ? source.Length : source.Length & ~0x3;
int destLength = bytes.Length;
int maxSrcLength = srcLength;
int decodedLength = GetMaxDecodedLength(srcLength);

ushort* src = srcBytes;
char* src = srcBytes;
byte* dest = destBytes;
ushort* srcEnd = srcBytes + (uint)srcLength;
ushort* srcMax = srcBytes + (uint)maxSrcLength;
char* srcEnd = srcBytes + (uint)srcLength;
char* srcMax = srcBytes + (uint)maxSrcLength;

// Last bytes could have padding characters, so process them separately and treat them as valid only if isFinalBlock is true
// if isFinalBlock is false, padding characters are considered invalid
Expand Down Expand Up @@ -1069,7 +1069,7 @@ private static unsafe OperationStatus DecodeFromChars(ReadOnlySpan<ushort> sourc
OperationStatus.InvalidData;
}

static OperationStatus InvalidDataFallback(ReadOnlySpan<ushort> source, Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock)
static OperationStatus InvalidDataFallback(ReadOnlySpan<char> source, Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock)
{
source = source.Slice(bytesConsumed);
bytes = bytes.Slice(bytesWritten);
Expand Down Expand Up @@ -1121,7 +1121,7 @@ static OperationStatus InvalidDataFallback(ReadOnlySpan<ushort> source, Span<byt
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe int DecodeFourElements(ushort* source, ref sbyte decodingMap)
private static unsafe int DecodeFourElements(char* source, ref sbyte decodingMap)
{
// The 'source' span expected to have at least 4 elements, and the 'decodingMap' consists 256 sbytes
uint t0 = source[0];
Expand Down Expand Up @@ -1151,7 +1151,7 @@ private static unsafe int DecodeFourElements(ushort* source, ref sbyte decodingM
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int IndexOfAnyExceptWhiteSpace(ReadOnlySpan<ushort> span)
private static int IndexOfAnyExceptWhiteSpace(ReadOnlySpan<char> span)
{
for (int i = 0; i < span.Length; i++)
{
Expand All @@ -1164,10 +1164,10 @@ private static int IndexOfAnyExceptWhiteSpace(ReadOnlySpan<ushort> span)
return -1;
}

private static OperationStatus DecodeWithWhiteSpaceBlockwise(ReadOnlySpan<ushort> source, Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock = true)
private static OperationStatus DecodeWithWhiteSpaceBlockwise(ReadOnlySpan<char> source, Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock = true)
{
const int BlockSize = 4;
Span<ushort> buffer = stackalloc ushort[BlockSize];
Span<char> buffer = stackalloc char[BlockSize];
OperationStatus status = OperationStatus.Done;

while (!source.IsEmpty)
Expand Down Expand Up @@ -1252,7 +1252,7 @@ private static OperationStatus DecodeWithWhiteSpaceBlockwise(ReadOnlySpan<ushort
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int GetPaddingCount(ref ushort ptrToLastElement)
private static int GetPaddingCount(ref char ptrToLastElement)
{
int padding = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,7 @@ public static byte[] EncodeToUtf8(ReadOnlySpan<byte> source)
/// such as when calling in a loop, subsequent calls with <see langword="false"/> should end with <see langword="true"/> call. The default is <see langword="true" />.</param>
/// <returns>One of the enumeration values that indicates the success or failure of the operation.</returns>
/// <remarks>This implementation of the base64url encoding omits the optional padding characters.</remarks>
public static OperationStatus EncodeToChars(ReadOnlySpan<byte> source, Span<char> destination,
out int bytesConsumed, out int charsWritten, bool isFinalBlock = true) =>
EncodeToChars(source, MemoryMarshal.Cast<char, ushort>(destination), out bytesConsumed, out charsWritten, isFinalBlock);

private static unsafe OperationStatus EncodeToChars(ReadOnlySpan<byte> source, Span<ushort> destination,
public static unsafe OperationStatus EncodeToChars(ReadOnlySpan<byte> source, Span<char> destination,
out int bytesConsumed, out int charsWritten, bool isFinalBlock = true)
{
if (source.IsEmpty)
Expand All @@ -260,14 +256,14 @@ private static unsafe OperationStatus EncodeToChars(ReadOnlySpan<byte> source, S
}

fixed (byte* srcBytes = &MemoryMarshal.GetReference(source))
fixed (ushort* destBytes = &MemoryMarshal.GetReference(destination))
fixed (char* destBytes = &MemoryMarshal.GetReference(destination))
{
int srcLength = source.Length;
int destLength = destination.Length;
int maxSrcLength = GetEncodedLength(srcLength);

byte* src = srcBytes;
ushort* dest = destBytes;
char* dest = destBytes;
byte* srcEnd = srcBytes + (uint)srcLength;
byte* srcMax = srcBytes + (uint)maxSrcLength;

Expand Down Expand Up @@ -327,7 +323,7 @@ private static unsafe OperationStatus EncodeToChars(ReadOnlySpan<byte> source, S
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void EncodeOneAndWriteTwo(byte* oneByte, ushort* dest, ref byte encodingMap)
private static unsafe void EncodeOneAndWriteTwo(byte* oneByte, char* dest, ref byte encodingMap)
{
uint t0 = oneByte[0];

Expand All @@ -338,18 +334,18 @@ private static unsafe void EncodeOneAndWriteTwo(byte* oneByte, ushort* dest, ref

if (BitConverter.IsLittleEndian)
{
dest[0] = (byte)i0;
dest[1] = (byte)i1;
dest[0] = (char)i0;
dest[1] = (char)i1;
}
else
{
dest[1] = (byte)i0;
dest[0] = (byte)i1;
dest[1] = (char)i0;
dest[0] = (char)i1;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void EncodeTwoAndWriteThree(byte* twoBytes, ushort* dest, ref byte encodingMap)
private static unsafe void EncodeTwoAndWriteThree(byte* twoBytes, char* dest, ref byte encodingMap)
{
uint t0 = twoBytes[0];
uint t1 = twoBytes[1];
Expand All @@ -362,20 +358,20 @@ private static unsafe void EncodeTwoAndWriteThree(byte* twoBytes, ushort* dest,

if (BitConverter.IsLittleEndian)
{
dest[0] = (byte)i0;
dest[1] = (byte)i1;
dest[2] = (byte)i2;
dest[0] = (char)i0;
dest[1] = (char)i1;
dest[2] = (char)i2;
}
else
{
dest[2] = (byte)i0;
dest[1] = (byte)i1;
dest[0] = (byte)i2;
dest[2] = (char)i0;
dest[1] = (char)i1;
dest[0] = (char)i2;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void EncodeThreeAndWriteFour(byte* threeBytes, ushort* destination, ref byte encodingMap)
private static unsafe void EncodeThreeAndWriteFour(byte* threeBytes, char* destination, ref byte encodingMap)
{
uint t0 = threeBytes[0];
uint t1 = threeBytes[1];
Expand All @@ -390,17 +386,17 @@ private static unsafe void EncodeThreeAndWriteFour(byte* threeBytes, ushort* des

if (BitConverter.IsLittleEndian)
{
destination[0] = i0;
destination[1] = i1;
destination[2] = i2;
destination[3] = i3;
destination[0] = (char)i0;
destination[1] = (char)i1;
destination[2] = (char)i2;
destination[3] = (char)i3;
}
else
{
destination[3] = i0;
destination[2] = i1;
destination[1] = i2;
destination[0] = i3;
destination[3] = (char)i0;
destination[2] = (char)i1;
destination[1] = (char)i2;
destination[0] = (char)i3;
}
}

Expand Down

0 comments on commit c1c586b

Please sign in to comment.