@@ -78,7 +78,7 @@ private string EncodeGenericToString(ReadOnlySpan<byte> data)
7878 {
7979 Span < byte > digits = stackalloc byte [ size ] ;
8080 int digitCount = ComputeGenericDigits ( inputSpan , digits ) ;
81- var state = new EncodeState ( digits , 0 , digitCount , TAlphabet . Characters , TAlphabet . FirstCharacter , leadingZeros ) ;
81+ var state = new EncodeState < TAlphabet > ( digits , 0 , digitCount , leadingZeros ) ;
8282 return string . Create ( state . OutputLength , state , static ( span , s ) => s . EmitReverse ( span ) ) ;
8383 }
8484
@@ -91,7 +91,7 @@ private string EncodeGenericToStringLarge(ReadOnlySpan<byte> inputSpan, int lead
9191 try
9292 {
9393 int digitCount = ComputeGenericDigits ( inputSpan , rented ) ;
94- var state = new EncodeState ( rented , 0 , digitCount , TAlphabet . Characters , TAlphabet . FirstCharacter , leadingZeros ) ;
94+ var state = new EncodeState < TAlphabet > ( rented , 0 , digitCount , leadingZeros ) ;
9595 return string . Create ( state . OutputLength , state , static ( span , s ) => s . EmitReverse ( span ) ) ;
9696 }
9797 finally
@@ -129,7 +129,7 @@ private int EncodeGenericToBytes(ReadOnlySpan<byte> data, Span<byte> destination
129129 ThrowHelper . ThrowDestinationTooSmall ( nameof ( destination ) ) ;
130130 }
131131
132- var state = new EncodeState ( digits , 0 , digitCount , TAlphabet . Characters , TAlphabet . FirstCharacter , leadingZeros ) ;
132+ var state = new EncodeState < TAlphabet > ( digits , 0 , digitCount , leadingZeros ) ;
133133 state . EmitReverse ( destination ) ;
134134 return outputLength ;
135135 }
@@ -149,7 +149,7 @@ private int EncodeGenericToBytesLarge(ReadOnlySpan<byte> inputSpan, int leadingZ
149149 ThrowHelper . ThrowDestinationTooSmall ( nameof ( destination ) ) ;
150150 }
151151
152- var state = new EncodeState ( rented , 0 , digitCount , TAlphabet . Characters , TAlphabet . FirstCharacter , leadingZeros ) ;
152+ var state = new EncodeState < TAlphabet > ( rented , 0 , digitCount , leadingZeros ) ;
153153 state . EmitReverse ( destination ) ;
154154 return outputLength ;
155155 }
@@ -202,7 +202,7 @@ internal static string EncodeBitcoin32FastToString(ReadOnlySpan<byte> data)
202202 Debug . Assert ( skip >= 0 , "rawLeadingZeros should always be >= inLeadingZeros by Base58 math" ) ;
203203 int digitCount = Base58BitcoinTables . Raw58Sz32 - rawLeadingZeros ;
204204
205- var state = new EncodeState ( rawBase58 , rawLeadingZeros , digitCount , Base58BitcoinTables . BitcoinChars , ( byte ) '1' , inLeadingZeros ) ;
205+ var state = new EncodeState < TAlphabet > ( rawBase58 , rawLeadingZeros , digitCount , inLeadingZeros ) ;
206206 return string . Create ( state . OutputLength , state , static ( span , s ) => s . EmitForward ( span ) ) ;
207207 }
208208
@@ -235,7 +235,7 @@ private static int EncodeBitcoin32FastToBytes(ReadOnlySpan<byte> data, Span<byte
235235 ThrowHelper . ThrowDestinationTooSmall ( nameof ( destination ) ) ;
236236 }
237237
238- var state = new EncodeState ( rawBase58 , rawLeadingZeros , digitCount , Base58BitcoinTables . BitcoinChars , ( byte ) '1' , inLeadingZeros ) ;
238+ var state = new EncodeState < TAlphabet > ( rawBase58 , rawLeadingZeros , digitCount , inLeadingZeros ) ;
239239 state . EmitForward ( destination ) ;
240240 return outputLength ;
241241 }
@@ -311,7 +311,7 @@ internal static string EncodeBitcoin64FastToString(ReadOnlySpan<byte> data)
311311 Debug . Assert ( skip >= 0 , "rawLeadingZeros should always be >= inLeadingZeros by Base58 math" ) ;
312312 int digitCount = Base58BitcoinTables . Raw58Sz64 - rawLeadingZeros ;
313313
314- var state = new EncodeState ( rawBase58 , rawLeadingZeros , digitCount , Base58BitcoinTables . BitcoinChars , ( byte ) '1' , inLeadingZeros ) ;
314+ var state = new EncodeState < TAlphabet > ( rawBase58 , rawLeadingZeros , digitCount , inLeadingZeros ) ;
315315 return string . Create ( state . OutputLength , state , static ( span , s ) => s . EmitForward ( span ) ) ;
316316 }
317317
@@ -344,7 +344,7 @@ private static int EncodeBitcoin64FastToBytes(ReadOnlySpan<byte> data, Span<byte
344344 ThrowHelper . ThrowDestinationTooSmall ( nameof ( destination ) ) ;
345345 }
346346
347- var state = new EncodeState ( rawBase58 , rawLeadingZeros , digitCount , Base58BitcoinTables . BitcoinChars , ( byte ) '1' , inLeadingZeros ) ;
347+ var state = new EncodeState < TAlphabet > ( rawBase58 , rawLeadingZeros , digitCount , inLeadingZeros ) ;
348348 state . EmitForward ( destination ) ;
349349 return outputLength ;
350350 }
@@ -419,28 +419,23 @@ private static int ComputeBitcoin64FastRaw(ReadOnlySpan<byte> data, Span<byte> r
419419 return rawLeadingZeros ;
420420 }
421421
422- private readonly ref struct EncodeState
422+ private readonly ref struct EncodeState < T >
423+ where T : struct , IBase58Alphabet
423424 {
424425 public readonly ReadOnlySpan < byte > Digits ;
425- public readonly ReadOnlySpan < byte > Alphabet ;
426426 public readonly int DigitStart ;
427427 public readonly int DigitCount ;
428- public readonly byte LeadingFill ;
429428 public readonly int LeadingCount ;
430429
431430 public EncodeState (
432431 ReadOnlySpan < byte > digits ,
433432 int digitStart ,
434433 int digitCount ,
435- ReadOnlySpan < byte > alphabet ,
436- byte leadingFill ,
437434 int leadingCount )
438435 {
439436 Digits = digits ;
440437 DigitStart = digitStart ;
441438 DigitCount = digitCount ;
442- Alphabet = alphabet ;
443- LeadingFill = leadingFill ;
444439 LeadingCount = leadingCount ;
445440 }
446441
@@ -451,14 +446,15 @@ public void EmitForward<TChar>(Span<TChar> destination)
451446 {
452447 if ( LeadingCount > 0 )
453448 {
454- destination [ ..LeadingCount ] . Fill ( TChar . CreateTruncating ( LeadingFill ) ) ;
449+ destination [ ..LeadingCount ] . Fill ( TChar . CreateTruncating ( T . FirstCharacter ) ) ;
455450 }
456451
457452 int index = LeadingCount ;
458453 int end = DigitStart + DigitCount ;
454+ ReadOnlySpan < byte > alphabet = T . Characters ;
459455 for ( int i = DigitStart ; i < end ; i ++ )
460456 {
461- destination [ index ++ ] = TChar . CreateTruncating ( ( ushort ) Alphabet [ Digits [ i ] ] ) ;
457+ destination [ index ++ ] = TChar . CreateTruncating ( ( ushort ) alphabet [ Digits [ i ] ] ) ;
462458 }
463459 }
464460
@@ -467,13 +463,14 @@ public void EmitReverse<TChar>(Span<TChar> destination)
467463 {
468464 if ( LeadingCount > 0 )
469465 {
470- destination [ ..LeadingCount ] . Fill ( TChar . CreateTruncating ( LeadingFill ) ) ;
466+ destination [ ..LeadingCount ] . Fill ( TChar . CreateTruncating ( T . FirstCharacter ) ) ;
471467 }
472468
473469 int index = LeadingCount ;
470+ ReadOnlySpan < byte > alphabet = T . Characters ;
474471 for ( int i = DigitStart + DigitCount - 1 ; i >= DigitStart ; i -- )
475472 {
476- destination [ index ++ ] = TChar . CreateTruncating ( ( ushort ) Alphabet [ Digits [ i ] ] ) ;
473+ destination [ index ++ ] = TChar . CreateTruncating ( ( ushort ) alphabet [ Digits [ i ] ] ) ;
477474 }
478475 }
479476 }
0 commit comments