@@ -129,14 +129,14 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(TBase64Deco
129129
130130 while ( src < srcMax )
131131 {
132- int result = decoder . DecodeFourElements ( src , ref decodingMap ) ;
132+ int result = decoder . DecodeFourElements ( new ReadOnlySpan < T > ( src , 4 ) , ref decodingMap ) ;
133133
134134 if ( result < 0 )
135135 {
136136 goto InvalidDataExit ;
137137 }
138138
139- WriteThreeLowOrderBytes ( dest , result ) ;
139+ WriteThreeLowOrderBytes ( new Span < byte > ( dest , 3 ) , result ) ;
140140 src += 4 ;
141141 dest += 3 ;
142142 }
@@ -166,7 +166,7 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(TBase64Deco
166166 // If more than 4 bytes remained it will end up in DestinationTooSmallExit or InvalidDataExit (might succeed after whitespace removed)
167167 long remaining = srcEnd - src ;
168168 Debug . Assert ( typeof ( TBase64Decoder ) == typeof ( Base64DecoderByte ) ? remaining == 4 : remaining < 8 ) ;
169- int i0 = decoder . DecodeRemaining ( srcEnd , ref decodingMap , remaining , out uint t2 , out uint t3 ) ;
169+ int i0 = decoder . DecodeRemaining ( new ReadOnlySpan < T > ( src , ( int ) remaining ) , ref decodingMap , out uint t2 , out uint t3 ) ;
170170
171171 if ( i0 < 0 )
172172 {
@@ -194,7 +194,7 @@ internal static unsafe OperationStatus DecodeFrom<TBase64Decoder, T>(TBase64Deco
194194 goto DestinationTooSmallExit ;
195195 }
196196
197- WriteThreeLowOrderBytes ( dest , i0 ) ;
197+ WriteThreeLowOrderBytes ( new Span < byte > ( dest , 3 ) , i0 ) ;
198198 dest += 3 ;
199199 src += 4 ;
200200 }
@@ -331,7 +331,7 @@ static OperationStatus InvalidDataFallback(TBase64Decoder decoder, ReadOnlySpan<
331331 }
332332 }
333333
334- internal static unsafe OperationStatus DecodeFromUtf8InPlace < TBase64Decoder > ( TBase64Decoder decoder , Span < byte > buffer , out int bytesWritten , bool ignoreWhiteSpace )
334+ internal static OperationStatus DecodeFromUtf8InPlace < TBase64Decoder > ( TBase64Decoder decoder , Span < byte > buffer , out int bytesWritten , bool ignoreWhiteSpace )
335335 where TBase64Decoder : IBase64Decoder < byte >
336336 {
337337 if ( buffer . IsEmpty )
@@ -340,64 +340,63 @@ internal static unsafe OperationStatus DecodeFromUtf8InPlace<TBase64Decoder>(TBa
340340 return OperationStatus . Done ;
341341 }
342342
343- fixed ( byte * bufferBytes = & MemoryMarshal . GetReference ( buffer ) )
344- {
345- uint bufferLength = ( uint ) buffer . Length ;
346- uint sourceIndex = 0 ;
347- uint destIndex = 0 ;
343+ uint bufferLength = ( uint ) buffer . Length ;
344+ uint sourceIndex = 0 ;
345+ uint destIndex = 0 ;
348346
349- if ( decoder . IsInvalidLength ( buffer . Length ) )
350- {
351- goto InvalidExit ;
352- }
347+ if ( decoder . IsInvalidLength ( buffer . Length ) )
348+ {
349+ goto InvalidExit ;
350+ }
353351
354- ref sbyte decodingMap = ref MemoryMarshal . GetReference ( decoder . DecodingMap ) ;
352+ ref sbyte decodingMap = ref MemoryMarshal . GetReference ( decoder . DecodingMap ) ;
355353
356- if ( bufferLength > 4 )
354+ if ( bufferLength > 4 )
355+ {
356+ while ( sourceIndex < bufferLength - 4 )
357357 {
358- while ( sourceIndex < bufferLength - 4 )
358+ int result = decoder . DecodeFourElements ( buffer . Slice ( ( int ) sourceIndex , 4 ) , ref decodingMap ) ;
359+ if ( result < 0 )
359360 {
360- int result = decoder . DecodeFourElements ( bufferBytes + sourceIndex , ref decodingMap ) ;
361- if ( result < 0 )
362- {
363- goto InvalidExit ;
364- }
365-
366- WriteThreeLowOrderBytes ( bufferBytes + destIndex , result ) ;
367- destIndex += 3 ;
368- sourceIndex += 4 ;
361+ goto InvalidExit ;
369362 }
363+
364+ WriteThreeLowOrderBytes ( buffer . Slice ( ( int ) destIndex , 3 ) , result ) ;
365+ destIndex += 3 ;
366+ sourceIndex += 4 ;
370367 }
368+ }
371369
372- uint t0 ;
373- uint t1 ;
374- uint t2 ;
375- uint t3 ;
370+ uint t0 ;
371+ uint t1 ;
372+ uint t2 ;
373+ uint t3 ;
376374
377- switch ( bufferLength - sourceIndex )
378- {
379- case 2 :
380- t0 = bufferBytes [ bufferLength - 2 ] ;
381- t1 = bufferBytes [ bufferLength - 1 ] ;
382- t2 = EncodingPad ;
383- t3 = EncodingPad ;
384- break ;
385- case 3 :
386- t0 = bufferBytes [ bufferLength - 3 ] ;
387- t1 = bufferBytes [ bufferLength - 2 ] ;
388- t2 = bufferBytes [ bufferLength - 1 ] ;
389- t3 = EncodingPad ;
390- break ;
391- case 4 :
392- t0 = bufferBytes [ bufferLength - 4 ] ;
393- t1 = bufferBytes [ bufferLength - 3 ] ;
394- t2 = bufferBytes [ bufferLength - 2 ] ;
395- t3 = bufferBytes [ bufferLength - 1 ] ;
396- break ;
397- default :
398- goto InvalidExit ;
399- }
375+ switch ( bufferLength - sourceIndex )
376+ {
377+ case 2 :
378+ t0 = buffer [ ( int ) ( bufferLength - 2 ) ] ;
379+ t1 = buffer [ ( int ) ( bufferLength - 1 ) ] ;
380+ t2 = EncodingPad ;
381+ t3 = EncodingPad ;
382+ break ;
383+ case 3 :
384+ t0 = buffer [ ( int ) ( bufferLength - 3 ) ] ;
385+ t1 = buffer [ ( int ) ( bufferLength - 2 ) ] ;
386+ t2 = buffer [ ( int ) ( bufferLength - 1 ) ] ;
387+ t3 = EncodingPad ;
388+ break ;
389+ case 4 :
390+ t0 = buffer [ ( int ) ( bufferLength - 4 ) ] ;
391+ t1 = buffer [ ( int ) ( bufferLength - 3 ) ] ;
392+ t2 = buffer [ ( int ) ( bufferLength - 2 ) ] ;
393+ t3 = buffer [ ( int ) ( bufferLength - 1 ) ] ;
394+ break ;
395+ default :
396+ goto InvalidExit ;
397+ }
400398
399+ {
401400 int i0 = Unsafe . Add ( ref decodingMap , ( int ) t0 ) ;
402401 int i1 = Unsafe . Add ( ref decodingMap , ( int ) t1 ) ;
403402
@@ -421,7 +420,7 @@ internal static unsafe OperationStatus DecodeFromUtf8InPlace<TBase64Decoder>(TBa
421420 goto InvalidExit ;
422421 }
423422
424- WriteThreeLowOrderBytes ( bufferBytes + destIndex , i0 ) ;
423+ WriteThreeLowOrderBytes ( buffer . Slice ( ( int ) destIndex , 3 ) , i0 ) ;
425424 destIndex += 3 ;
426425 }
427426 else if ( ! decoder . IsValidPadding ( t2 ) )
@@ -437,8 +436,8 @@ internal static unsafe OperationStatus DecodeFromUtf8InPlace<TBase64Decoder>(TBa
437436 goto InvalidExit ;
438437 }
439438
440- bufferBytes [ destIndex ] = ( byte ) ( i0 >> 16 ) ;
441- bufferBytes [ destIndex + 1 ] = ( byte ) ( i0 >> 8 ) ;
439+ buffer [ ( int ) destIndex ] = ( byte ) ( i0 >> 16 ) ;
440+ buffer [ ( int ) ( destIndex + 1 ) ] = ( byte ) ( i0 >> 8 ) ;
442441 destIndex += 2 ;
443442 }
444443 else
@@ -448,19 +447,19 @@ internal static unsafe OperationStatus DecodeFromUtf8InPlace<TBase64Decoder>(TBa
448447 goto InvalidExit ;
449448 }
450449
451- bufferBytes [ destIndex ] = ( byte ) ( i0 >> 16 ) ;
450+ buffer [ ( int ) destIndex ] = ( byte ) ( i0 >> 16 ) ;
452451 destIndex += 1 ;
453452 }
453+ }
454454
455- bytesWritten = ( int ) destIndex ;
456- return OperationStatus . Done ;
455+ bytesWritten = ( int ) destIndex ;
456+ return OperationStatus . Done ;
457457
458- InvalidExit :
459- bytesWritten = ( int ) destIndex ;
460- return ignoreWhiteSpace ?
461- DecodeWithWhiteSpaceFromUtf8InPlace < TBase64Decoder > ( decoder , buffer , ref bytesWritten , sourceIndex ) : // The input may have whitespace, attempt to decode while ignoring whitespace.
462- OperationStatus . InvalidData ;
463- }
458+ InvalidExit :
459+ bytesWritten = ( int ) destIndex ;
460+ return ignoreWhiteSpace ?
461+ DecodeWithWhiteSpaceFromUtf8InPlace < TBase64Decoder > ( decoder , buffer , ref bytesWritten , sourceIndex ) : // The input may have whitespace, attempt to decode while ignoring whitespace.
462+ OperationStatus . InvalidData ;
464463 }
465464
466465 internal static OperationStatus DecodeWithWhiteSpaceBlockwise < TBase64Decoder > ( TBase64Decoder decoder , ReadOnlySpan < byte > source , Span < byte > bytes , ref int bytesConsumed , ref int bytesWritten , bool isFinalBlock = true )
@@ -1300,7 +1299,7 @@ private static unsafe void Vector128Decode<TBase64Decoder, T>(TBase64Decoder dec
13001299#endif
13011300
13021301 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1303- private static unsafe void WriteThreeLowOrderBytes ( byte * destination , int value )
1302+ private static void WriteThreeLowOrderBytes ( Span < byte > destination , int value )
13041303 {
13051304 destination [ 0 ] = ( byte ) ( value >> 16 ) ;
13061305 destination [ 1 ] = ( byte ) ( value >> 8 ) ;
@@ -1514,7 +1513,7 @@ public unsafe bool TryLoadArmVector128x4(byte* src, byte* srcStart, int sourceLe
15141513#endif // NET
15151514
15161515 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1517- public unsafe int DecodeFourElements ( byte * source , ref sbyte decodingMap )
1516+ public int DecodeFourElements ( ReadOnlySpan < byte > source , ref sbyte decodingMap )
15181517 {
15191518 // The 'source' span expected to have at least 4 elements, and the 'decodingMap' consists 256 sbytes
15201519 uint t0 = source [ 0 ] ;
@@ -1539,28 +1538,28 @@ public unsafe int DecodeFourElements(byte* source, ref sbyte decodingMap)
15391538 }
15401539
15411540 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1542- public unsafe int DecodeRemaining ( byte * srcEnd , ref sbyte decodingMap , long remaining , out uint t2 , out uint t3 )
1541+ public int DecodeRemaining ( ReadOnlySpan < byte > source , ref sbyte decodingMap , out uint t2 , out uint t3 )
15431542 {
15441543 uint t0 ;
15451544 uint t1 ;
15461545 t2 = EncodingPad ;
15471546 t3 = EncodingPad ;
1548- switch ( remaining )
1547+ switch ( source . Length )
15491548 {
15501549 case 2 :
1551- t0 = srcEnd [ - 2 ] ;
1552- t1 = srcEnd [ - 1 ] ;
1550+ t0 = source [ 0 ] ;
1551+ t1 = source [ 1 ] ;
15531552 break ;
15541553 case 3 :
1555- t0 = srcEnd [ - 3 ] ;
1556- t1 = srcEnd [ - 2 ] ;
1557- t2 = srcEnd [ - 1 ] ;
1554+ t0 = source [ 0 ] ;
1555+ t1 = source [ 1 ] ;
1556+ t2 = source [ 2 ] ;
15581557 break ;
15591558 case 4 :
1560- t0 = srcEnd [ - 4 ] ;
1561- t1 = srcEnd [ - 3 ] ;
1562- t2 = srcEnd [ - 2 ] ;
1563- t3 = srcEnd [ - 1 ] ;
1559+ t0 = source [ 0 ] ;
1560+ t1 = source [ 1 ] ;
1561+ t2 = source [ 2 ] ;
1562+ t3 = source [ 3 ] ;
15641563 break ;
15651564 default :
15661565 return - 1 ;
@@ -1720,7 +1719,7 @@ public unsafe bool TryLoadArmVector128x4(ushort* src, ushort* srcStart, int sour
17201719#endif // NET
17211720
17221721 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1723- public unsafe int DecodeFourElements ( ushort * source , ref sbyte decodingMap )
1722+ public int DecodeFourElements ( ReadOnlySpan < ushort > source , ref sbyte decodingMap )
17241723 {
17251724 // The 'source' span expected to have at least 4 elements, and the 'decodingMap' consists 256 sbytes
17261725 uint t0 = source [ 0 ] ;
@@ -1750,28 +1749,28 @@ public unsafe int DecodeFourElements(ushort* source, ref sbyte decodingMap)
17501749 }
17511750
17521751 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
1753- public unsafe int DecodeRemaining ( ushort * srcEnd , ref sbyte decodingMap , long remaining , out uint t2 , out uint t3 )
1752+ public int DecodeRemaining ( ReadOnlySpan < ushort > source , ref sbyte decodingMap , out uint t2 , out uint t3 )
17541753 {
17551754 uint t0 ;
17561755 uint t1 ;
17571756 t2 = EncodingPad ;
17581757 t3 = EncodingPad ;
1759- switch ( remaining )
1758+ switch ( source . Length )
17601759 {
17611760 case 2 :
1762- t0 = srcEnd [ - 2 ] ;
1763- t1 = srcEnd [ - 1 ] ;
1761+ t0 = source [ 0 ] ;
1762+ t1 = source [ 1 ] ;
17641763 break ;
17651764 case 3 :
1766- t0 = srcEnd [ - 3 ] ;
1767- t1 = srcEnd [ - 2 ] ;
1768- t2 = srcEnd [ - 1 ] ;
1765+ t0 = source [ 0 ] ;
1766+ t1 = source [ 1 ] ;
1767+ t2 = source [ 2 ] ;
17691768 break ;
17701769 case 4 :
1771- t0 = srcEnd [ - 4 ] ;
1772- t1 = srcEnd [ - 3 ] ;
1773- t2 = srcEnd [ - 2 ] ;
1774- t3 = srcEnd [ - 1 ] ;
1770+ t0 = source [ 0 ] ;
1771+ t1 = source [ 1 ] ;
1772+ t2 = source [ 2 ] ;
1773+ t3 = source [ 3 ] ;
17751774 break ;
17761775 default :
17771776 return - 1 ;
0 commit comments