Skip to content

Commit

Permalink
Rename utf8 -> source/destintion
Browse files Browse the repository at this point in the history
  • Loading branch information
buyaa-n committed Jun 11, 2024
1 parent dea9006 commit e617b8f
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ internal interface IBase64Decoder<T> where T : unmanaged
static abstract ReadOnlySpan<uint> Vector128LutShift { get; }
static abstract ReadOnlySpan<uint> AdvSimdLutOne3 { get; }
static abstract uint AdvSimdLutTwo3Uint1 { get; }
static abstract int SrcLength(bool isFinalBlock, int utf8Length);
static abstract int GetMaxDecodedLength(int utf8Length);
static abstract int SrcLength(bool isFinalBlock, int sourceLength);
static abstract int GetMaxDecodedLength(int sourceLength);
static abstract bool IsInvalidLength(int bufferLength);
static abstract bool IsValidPadding(uint padChar);
static abstract bool TryDecode128Core(
Expand All @@ -127,7 +127,7 @@ static abstract bool TryDecode256Core(
static abstract unsafe int Decode(T* encodedBytes, ref sbyte decodingMap);
static abstract unsafe int DecodeRemaining(T* srcEnd, ref sbyte decodingMap, long remaining, out uint t2, out uint t3);
static abstract int IndexOfAnyExceptWhiteSpace(ReadOnlySpan<T> span);
static abstract OperationStatus DecodeWithWhiteSpaceBlockwiseWrapper<TTBase64Decoder>(ReadOnlySpan<T> utf8,
static abstract OperationStatus DecodeWithWhiteSpaceBlockwiseWrapper<TTBase64Decoder>(ReadOnlySpan<T> source,
Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock = true)
where TTBase64Decoder : IBase64Decoder<T>;
static abstract unsafe bool TryLoadVector512(T* src, T* srcStart, int sourceLength, out Vector512<sbyte> str);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,22 @@ public static partial class Base64
public static OperationStatus DecodeFromUtf8(ReadOnlySpan<byte> utf8, Span<byte> bytes, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) =>
DecodeFrom<Base64DecoderByte, byte>(utf8, bytes, out bytesConsumed, out bytesWritten, isFinalBlock, ignoreWhiteSpace: true);

internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(ReadOnlySpan<T> utf8, Span<byte> bytes,
internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(ReadOnlySpan<T> source, Span<byte> bytes,
out int bytesConsumed, out int bytesWritten, bool isFinalBlock, bool ignoreWhiteSpace)
where TBase64Decoder : IBase64Decoder<T>
where T : unmanaged
{
if (utf8.IsEmpty)
if (source.IsEmpty)
{
bytesConsumed = 0;
bytesWritten = 0;
return OperationStatus.Done;
}

fixed (T* srcBytes = &MemoryMarshal.GetReference(utf8))
fixed (T* srcBytes = &MemoryMarshal.GetReference(source))
fixed (byte* destBytes = &MemoryMarshal.GetReference(bytes))
{
int srcLength = TBase64Decoder.SrcLength(isFinalBlock, utf8.Length);
int srcLength = TBase64Decoder.SrcLength(isFinalBlock, source.Length);
int destLength = bytes.Length;
int maxSrcLength = srcLength;
int decodedLength = TBase64Decoder.GetMaxDecodedLength(srcLength);
Expand Down Expand Up @@ -166,7 +166,7 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(ReadOnlySpa
goto InvalidDataExit;
}

if (src == srcBytes + utf8.Length)
if (src == srcBytes + source.Length)
{
goto DoneExit;
}
Expand Down Expand Up @@ -244,7 +244,7 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(ReadOnlySpa
src += remaining;
}

if (srcLength != utf8.Length)
if (srcLength != source.Length)
{
goto InvalidDataExit;
}
Expand All @@ -255,7 +255,7 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(ReadOnlySpa
return OperationStatus.Done;

DestinationTooSmallExit:
if (srcLength != utf8.Length && isFinalBlock)
if (srcLength != source.Length && isFinalBlock)
{
goto InvalidDataExit; // if input is not a multiple of 4, and there is no more data, return invalid data instead
}
Expand All @@ -273,7 +273,7 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(ReadOnlySpa
bytesConsumed = (int)(src - srcBytes);
bytesWritten = (int)(dest - destBytes);
return ignoreWhiteSpace ?
InvalidDataFallback(utf8, bytes, ref bytesConsumed, ref bytesWritten, isFinalBlock) :
InvalidDataFallback(source, bytes, ref bytesConsumed, ref bytesWritten, isFinalBlock) :
OperationStatus.InvalidData;
}

Expand Down Expand Up @@ -492,33 +492,33 @@ internal static unsafe OperationStatus DecodeFromUtf8InPlace<TBase64Decoder>(Spa
}
}

internal static OperationStatus DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(ReadOnlySpan<byte> utf8, Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock = true)
internal static OperationStatus DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(ReadOnlySpan<byte> source, Span<byte> bytes, ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock = true)
where TBase64Decoder : IBase64Decoder<byte>
{
const int BlockSize = 4;
Span<byte> buffer = stackalloc byte[BlockSize];
OperationStatus status = OperationStatus.Done;

while (!utf8.IsEmpty)
while (!source.IsEmpty)
{
int encodedIdx = 0;
int bufferIdx = 0;
int skipped = 0;

for (; encodedIdx < utf8.Length && (uint)bufferIdx < (uint)buffer.Length; ++encodedIdx)
for (; encodedIdx < source.Length && (uint)bufferIdx < (uint)buffer.Length; ++encodedIdx)
{
if (IsWhiteSpace(utf8[encodedIdx]))
if (IsWhiteSpace(source[encodedIdx]))
{
skipped++;
}
else
{
buffer[bufferIdx] = utf8[encodedIdx];
buffer[bufferIdx] = source[encodedIdx];
bufferIdx++;
}
}

utf8 = utf8.Slice(encodedIdx);
source = source.Slice(encodedIdx);
bytesConsumed += skipped;

if (bufferIdx == 0)
Expand All @@ -530,11 +530,11 @@ internal static OperationStatus DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(Re

if (typeof(TBase64Decoder) == typeof(Base64DecoderByte) || bufferIdx == 1)
{
hasAnotherBlock = utf8.Length >= BlockSize && bufferIdx == BlockSize;
hasAnotherBlock = source.Length >= BlockSize && bufferIdx == BlockSize;
}
else
{
hasAnotherBlock = utf8.Length > 1;
hasAnotherBlock = source.Length > 1;
}

bool localIsFinalBlock = !hasAnotherBlock;
Expand Down Expand Up @@ -567,9 +567,9 @@ internal static OperationStatus DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(Re
// The remaining data must all be whitespace in order to be valid.
if (!hasAnotherBlock)
{
for (int i = 0; i < utf8.Length; ++i)
for (int i = 0; i < source.Length; ++i)
{
if (!IsWhiteSpace(utf8[i]))
if (!IsWhiteSpace(source[i]))
{
// Revert previous dest increment, since an invalid state followed.
bytesConsumed -= localConsumed;
Expand All @@ -596,32 +596,39 @@ private static int GetPaddingCount<TBase64Decoder>(ref byte ptrToLastElement)
{
int padding = 0;

if (TBase64Decoder.IsValidPadding(ptrToLastElement)) padding++;
if (TBase64Decoder.IsValidPadding(Unsafe.Subtract(ref ptrToLastElement, 1))) padding++;
if (TBase64Decoder.IsValidPadding(ptrToLastElement))
{
padding++;
}

if (TBase64Decoder.IsValidPadding(Unsafe.Subtract(ref ptrToLastElement, 1)))
{
padding++;
}

return padding;
}

private static OperationStatus DecodeWithWhiteSpaceFromUtf8InPlace<TBase64Decoder>(Span<byte> utf8, ref int destIndex, uint sourceIndex)
private static OperationStatus DecodeWithWhiteSpaceFromUtf8InPlace<TBase64Decoder>(Span<byte> source, ref int destIndex, uint sourceIndex)
where TBase64Decoder : IBase64Decoder<byte>
{
int BlockSize = Math.Min(utf8.Length - (int)sourceIndex, 4);
int BlockSize = Math.Min(source.Length - (int)sourceIndex, 4);
Span<byte> buffer = stackalloc byte[BlockSize];

OperationStatus status = OperationStatus.Done;
int localDestIndex = destIndex;
bool hasPaddingBeenProcessed = false;
int localBytesWritten = 0;

while (sourceIndex < (uint)utf8.Length)
while (sourceIndex < (uint)source.Length)
{
int bufferIdx = 0;

while (bufferIdx < BlockSize && sourceIndex < (uint)utf8.Length)
while (bufferIdx < BlockSize && sourceIndex < (uint)source.Length)
{
if (!IsWhiteSpace(utf8[(int)sourceIndex]))
if (!IsWhiteSpace(source[(int)sourceIndex]))
{
buffer[bufferIdx] = utf8[(int)sourceIndex];
buffer[bufferIdx] = source[(int)sourceIndex];
bufferIdx++;
}

Expand All @@ -645,7 +652,7 @@ private static OperationStatus DecodeWithWhiteSpaceFromUtf8InPlace<TBase64Decode
{
while (bufferIdx < BlockSize) // Can happen only for last block
{
Debug.Assert(utf8.Length == sourceIndex);
Debug.Assert(source.Length == sourceIndex);
buffer[bufferIdx++] = (byte)EncodingPad;
}
}
Expand All @@ -672,7 +679,7 @@ private static OperationStatus DecodeWithWhiteSpaceFromUtf8InPlace<TBase64Decode
// Write result to source span in place.
for (int i = 0; i < localBytesWritten; i++)
{
utf8[localDestIndex - localBytesWritten + i] = buffer[i];
source[localDestIndex - localBytesWritten + i] = buffer[i];
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,23 @@ public static partial class Base64
public static unsafe OperationStatus EncodeToUtf8(ReadOnlySpan<byte> bytes, Span<byte> utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) =>
EncodeTo<Base64EncoderByte, byte>(bytes, utf8, out bytesConsumed, out bytesWritten, isFinalBlock);

internal static unsafe OperationStatus EncodeTo<TBase64Encoder, T>(ReadOnlySpan<byte> bytes,
Span<T> utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true)
internal static unsafe OperationStatus EncodeTo<TBase64Encoder, T>(ReadOnlySpan<byte> source,
Span<T> destination, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true)
where TBase64Encoder : IBase64Encoder<T>
where T : unmanaged
{
if (bytes.IsEmpty)
if (source.IsEmpty)
{
bytesConsumed = 0;
bytesWritten = 0;
return OperationStatus.Done;
}

fixed (byte* srcBytes = &MemoryMarshal.GetReference(bytes))
fixed (T* destBytes = &MemoryMarshal.GetReference(utf8))
fixed (byte* srcBytes = &MemoryMarshal.GetReference(source))
fixed (T* destBytes = &MemoryMarshal.GetReference(destination))
{
int srcLength = bytes.Length;
int destLength = utf8.Length;
int srcLength = source.Length;
int destLength = destination.Length;
int maxSrcLength = TBase64Encoder.GetMaxSrcLength(srcLength, destLength);

byte* src = srcBytes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,41 +186,41 @@ public static OperationStatus DecodeFromChars(ReadOnlySpan<char> source, Span<by
out int charsConsumed, out int bytesWritten, bool isFinalBlock = true) =>
DecodeFrom<Base64UrlDecoderChar, ushort>(MemoryMarshal.Cast<char, ushort>(source), destination, out charsConsumed, out bytesWritten, isFinalBlock, ignoreWhiteSpace: true);

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

while (!utf8.IsEmpty)
while (!source.IsEmpty)
{
int encodedIdx = 0;
int bufferIdx = 0;
int skipped = 0;

for (; encodedIdx < utf8.Length && (uint)bufferIdx < (uint)buffer.Length; ++encodedIdx)
for (; encodedIdx < source.Length && (uint)bufferIdx < (uint)buffer.Length; ++encodedIdx)
{
if (IsWhiteSpace(utf8[encodedIdx]))
if (IsWhiteSpace(source[encodedIdx]))
{
skipped++;
}
else
{
buffer[bufferIdx] = utf8[encodedIdx];
buffer[bufferIdx] = source[encodedIdx];
bufferIdx++;
}
}

utf8 = utf8.Slice(encodedIdx);
source = source.Slice(encodedIdx);
bytesConsumed += skipped;

if (bufferIdx == 0)
{
continue;
}

bool hasAnotherBlock = utf8.Length >= BlockSize && bufferIdx == BlockSize;
bool hasAnotherBlock = source.Length >= BlockSize && bufferIdx == BlockSize;
bool localIsFinalBlock = !hasAnotherBlock;

// If this block contains padding and there's another block, then only whitespace may follow for being valid.
Expand Down Expand Up @@ -251,9 +251,9 @@ private static OperationStatus DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(Rea
// The remaining data must all be whitespace in order to be valid.
if (!hasAnotherBlock)
{
for (int i = 0; i < utf8.Length; ++i)
for (int i = 0; i < source.Length; ++i)
{
if (!IsWhiteSpace(utf8[i]))
if (!IsWhiteSpace(source[i]))
{
// Revert previous dest increment, since an invalid state followed.
bytesConsumed -= localConsumed;
Expand Down Expand Up @@ -454,13 +454,13 @@ public static byte[] DecodeFromChars(ReadOnlySpan<char> source)

public static uint AdvSimdLutTwo3Uint1 => 0x1B1AFF3F;

public static int GetMaxDecodedLength(int utf8Length) => Base64Url.GetMaxDecodedLength(utf8Length);
public static int GetMaxDecodedLength(int sourceLength) => Base64Url.GetMaxDecodedLength(sourceLength);

public static bool IsInvalidLength(int bufferLength) => (bufferLength & 3) == 1; // One byte cannot be decoded completely

public static bool IsValidPadding(uint padChar) => padChar == EncodingPad || padChar == UrlEncodingPad;

public static int SrcLength(bool isFinalBlock, int utf8Length) => isFinalBlock ? utf8Length : utf8Length & ~0x3;
public static int SrcLength(bool isFinalBlock, int sourceLength) => isFinalBlock ? sourceLength : sourceLength & ~0x3;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CompExactlyDependsOn(typeof(AdvSimd.Arm64))]
Expand Down Expand Up @@ -596,13 +596,13 @@ public static unsafe bool TryLoadArmVector128x4(byte* src, byte* srcStart, int s

public static uint AdvSimdLutTwo3Uint1 => Base64UrlDecoderByte.AdvSimdLutTwo3Uint1;

public static int GetMaxDecodedLength(int utf8Length) => Base64UrlDecoderByte.GetMaxDecodedLength(utf8Length);
public static int GetMaxDecodedLength(int sourceLength) => Base64UrlDecoderByte.GetMaxDecodedLength(sourceLength);

public static bool IsInvalidLength(int bufferLength) => Base64DecoderByte.IsInvalidLength(bufferLength);

public static bool IsValidPadding(uint padChar) => Base64UrlDecoderByte.IsValidPadding(padChar);

public static int SrcLength(bool isFinalBlock, int utf8Length) => Base64UrlDecoderByte.SrcLength(isFinalBlock, utf8Length);
public static int SrcLength(bool isFinalBlock, int sourceLength) => Base64UrlDecoderByte.SrcLength(isFinalBlock, sourceLength);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CompExactlyDependsOn(typeof(AdvSimd.Arm64))]
Expand Down Expand Up @@ -704,9 +704,9 @@ public static int IndexOfAnyExceptWhiteSpace(ReadOnlySpan<ushort> span)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static OperationStatus DecodeWithWhiteSpaceBlockwiseWrapper<TBase64Decoder>(ReadOnlySpan<ushort> utf8, Span<byte> bytes,
public static OperationStatus DecodeWithWhiteSpaceBlockwiseWrapper<TBase64Decoder>(ReadOnlySpan<ushort> source, Span<byte> bytes,
ref int bytesConsumed, ref int bytesWritten, bool isFinalBlock = true) where TBase64Decoder : IBase64Decoder<ushort> =>
DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(utf8, bytes, ref bytesConsumed, ref bytesWritten, isFinalBlock);
DecodeWithWhiteSpaceBlockwise<TBase64Decoder>(source, bytes, ref bytesConsumed, ref bytesWritten, isFinalBlock);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe bool TryLoadVector512(ushort* src, ushort* srcStart, int sourceLength, out Vector512<sbyte> str)
Expand Down

0 comments on commit e617b8f

Please sign in to comment.