diff --git a/Base64/FromBase64Transform.cs b/Base64/FromBase64Transform.cs index b87f376..a2c4813 100644 --- a/Base64/FromBase64Transform.cs +++ b/Base64/FromBase64Transform.cs @@ -83,8 +83,9 @@ public unsafe int TransformBlock(Block block) fixed (char* cp = tempCharBuffer) { nWritten = ASCII.GetChars(startPtr, 4 * numBlocks, cp, bufferSize); - } - + } + +#if NETFRAMEWORK fixed (byte* op = block.outputBuffer) { int outputBytes = UnsafeConvert.FromBase64CharArray(tempCharBuffer, 0, nWritten, op + block.outputOffset); @@ -92,8 +93,17 @@ public unsafe int TransformBlock(Block block) block.outputOffset += outputBytes; totalOutputBytes += outputBytes; } - - // If we couldn't write a complete block, try to find 4 bytes starting from the last space. +#endif +#if NET5_0_OR_GREATER + if (!Convert.TryFromBase64Chars(tempCharBuffer.AsSpan().Slice(0, nWritten), block.outputBuffer.AsSpan().Slice(block.outputOffset), out int outputBytes)) + { + throw new FormatException(); + } + + block.outputOffset += outputBytes; + totalOutputBytes += outputBytes; +#endif + // If we couldn't write a complete block, try to find 4 bytes starting from the last space. int remainder = effectiveCount % 4; if (remainder != 0) @@ -119,8 +129,9 @@ public unsafe int TransformBlock(Block block) fixed (byte* tp = this.tempByteBuffer) { nWritten = ASCII.GetChars(tp, 4, cp, bufferSize); - } - + } + +#if NETFRAMEWORK fixed (byte* op = block.outputBuffer) { int outputBytes = UnsafeConvert.FromBase64CharArray(tempCharBuffer, 0, nWritten, op + block.outputOffset); @@ -128,6 +139,16 @@ public unsafe int TransformBlock(Block block) block.outputOffset += outputBytes; totalOutputBytes += outputBytes; } +#endif +#if NET5_0_OR_GREATER + if (!Convert.TryFromBase64Chars(tempCharBuffer.AsSpan().Slice(0, nWritten), block.outputBuffer.AsSpan().Slice(block.outputOffset), out int outputBytes2)) + { + throw new FormatException(); + } + + block.outputOffset += outputBytes2; + totalOutputBytes += outputBytes2; +#endif // advance startPtr past the block just written startPtr = tmpPtr; @@ -223,8 +244,9 @@ private unsafe int FlushTempBuffer(Block block) fixed (byte* tp = this.tempByteBuffer) { nWritten = ASCII.GetChars(tp, 4, cp, bufferSize); - } - + } + +#if NETFRAMEWORK fixed (byte* op = block.outputBuffer) { int outputBytes = UnsafeConvert.FromBase64CharArray(tempCharBuffer, 0, nWritten, op + block.outputOffset); @@ -232,6 +254,16 @@ private unsafe int FlushTempBuffer(Block block) block.outputOffset += outputBytes; totalOutputBytes += outputBytes; } +#endif +#if NET5_0_OR_GREATER + if (!Convert.TryFromBase64Chars(tempCharBuffer.AsSpan().Slice(0, nWritten), block.outputBuffer.AsSpan().Slice(block.outputOffset), out int outputBytes2)) + { + throw new FormatException(); + } + + block.outputOffset += outputBytes2; + totalOutputBytes += outputBytes2; +#endif // advance offset int count = (int)(startPtr - (byte*)(inputPtr + block.inputOffset)); diff --git a/Base64/UnsafeConvert.cs b/Base64/UnsafeConvert.cs index d398dd2..50759b8 100644 --- a/Base64/UnsafeConvert.cs +++ b/Base64/UnsafeConvert.cs @@ -6,7 +6,8 @@ using System.Text; namespace Base64 -{ +{ +#if NETFRAMEWORK public static class UnsafeConvert { /// @@ -59,12 +60,12 @@ private static unsafe int FromBase64CharPtr(char* inputPtr, int inputLength, byt // Note that actualResultLength can differ from resultLength if the caller is modifying the array // as it is being converted. Silently ignore the failure. // Consider throwing exception in an non in-place release. - } - - private static readonly MethodInfo FromBase64_DecodeMethodInfo = typeof(Convert).GetMethod("FromBase64_Decode", BindingFlags.Static | BindingFlags.NonPublic); + } - // no measurable overhead from reflection here - it's not in a tight loop. - // Can we turn this into a func to avoid allocating the args array? Pointers still need to be boxed. + private static readonly MethodInfo FromBase64_DecodeMethodInfo = typeof(Convert).GetMethod("FromBase64_Decode", BindingFlags.Static | BindingFlags.NonPublic); + + // no measurable overhead from reflection here - it's not in a tight loop. + // Can we turn this into a func to avoid allocating the args array? Pointers still need to be boxed. public static unsafe int FromBase64_DecodeReflect( char* startInputPtr, int inputLength, @@ -87,4 +88,5 @@ public static unsafe int FromBase64_DecodeReflect( } } } +#endif }