@@ -112,63 +112,51 @@ private static string ComputeFinalKey(byte[] preKey, ComponentState componentSta
112112 try
113113 {
114114 Span < byte > keyBuffer = stackalloc byte [ 1024 ] ;
115+ var currentBuffer = keyBuffer ;
115116 preKey . CopyTo ( keyBuffer ) ;
117+ currentBuffer = currentBuffer [ preKey . Length ..] ;
116118 if ( key is IUtf8SpanFormattable spanFormattable )
117119 {
118120 var wroteKey = false ;
119121 while ( ! wroteKey )
120122 {
121- wroteKey = spanFormattable . TryFormat ( keyBuffer [ preKey . Length .. ] , out var written , "" , CultureInfo . InvariantCulture ) ;
123+ wroteKey = spanFormattable . TryFormat ( currentBuffer , out var written , "" , CultureInfo . InvariantCulture ) ;
122124 if ( ! wroteKey )
123125 {
124126 // It is really unlikely that we will enter here, but we need to handle this case
125127 Debug . Assert ( written == 0 ) ;
126- GrowBuffer ( preKey , ref pool , ref keyBuffer ) ;
128+ GrowBuffer ( ref pool , ref keyBuffer ) ;
127129 }
128130 else
129131 {
130- keyBuffer = keyBuffer [ ..( preKey . Length + written ) ] ;
132+ currentBuffer = currentBuffer [ ..written ] ;
131133 }
132134 }
133135 }
134- else if ( key is IFormattable formattable )
136+ else
135137 {
136- var keyString = formattable . ToString ( "" , CultureInfo . InvariantCulture ) ;
138+ var keySpan = ResolveKeySpan ( key ) ;
137139 var wroteKey = false ;
138140 while ( ! wroteKey )
139141 {
140- wroteKey = Encoding . UTF8 . TryGetBytes ( keyString , keyBuffer [ preKey . Length ..] , out var written ) ;
141- if ( ! wroteKey )
142- {
143- Debug . Assert ( written == 0 ) ;
144- GrowBuffer ( preKey , ref pool , ref keyBuffer ) ;
145- }
146- else
147- {
148- keyBuffer = keyBuffer [ ..( preKey . Length + written ) ] ;
149- }
150- }
151- }
152- else if ( key is IConvertible convertible )
153- {
154- var keyString = convertible . ToString ( CultureInfo . InvariantCulture ) ;
155- var wroteKey = false ;
156- while ( ! wroteKey )
157- {
158- wroteKey = Encoding . UTF8 . TryGetBytes ( keyString , keyBuffer [ preKey . Length ..] , out var written ) ;
142+ wroteKey = Encoding . UTF8 . TryGetBytes ( keySpan , currentBuffer , out var written ) ;
159143 if ( ! wroteKey )
160144 {
145+ // It is really unlikely that we will enter here, but we need to handle this case
161146 Debug . Assert ( written == 0 ) ;
162- GrowBuffer ( preKey , ref pool , ref keyBuffer ) ;
147+ GrowBuffer ( ref pool , ref keyBuffer ) ;
163148 }
164149 else
165150 {
166- keyBuffer = keyBuffer [ ..( preKey . Length + written ) ] ;
151+ currentBuffer = currentBuffer [ ..written ] ;
167152 }
168153 }
169154 }
170155
171- Debug . Assert ( SHA256 . TryHashData ( keyBuffer , keyHash , out _ ) ) ;
156+ keyBuffer = keyBuffer [ ..( keyBuffer . Length - currentBuffer . Length ) ] ;
157+
158+ var hashSucceeded = SHA256 . TryHashData ( keyBuffer , keyHash , out _ ) ;
159+ Debug . Assert ( hashSucceeded ) ;
172160 return Convert . ToBase64String ( keyHash ) ;
173161 }
174162 finally
@@ -180,10 +168,25 @@ private static string ComputeFinalKey(byte[] preKey, ComponentState componentSta
180168 }
181169 }
182170
183- private static void GrowBuffer ( byte [ ] preKey , ref byte [ ] ? pool , ref Span < byte > keyBuffer )
171+ private static ReadOnlySpan < char > ResolveKeySpan ( object ? key )
172+ {
173+ if ( key is IFormattable formattable )
174+ {
175+ var keyString = formattable . ToString ( "" , CultureInfo . InvariantCulture ) ;
176+ return keyString . AsSpan ( ) ;
177+ }
178+ else if ( key is IConvertible convertible )
179+ {
180+ var keyString = convertible . ToString ( CultureInfo . InvariantCulture ) ;
181+ return keyString . AsSpan ( ) ;
182+ }
183+ return default ;
184+ }
185+
186+ private static void GrowBuffer ( ref byte [ ] ? pool , ref Span < byte > keyBuffer )
184187 {
185188 var newPool = pool == null ? ArrayPool < byte > . Shared . Rent ( 2048 ) : ArrayPool < byte > . Shared . Rent ( pool . Length * 2 ) ;
186- keyBuffer [ 0 .. preKey . Length ] . CopyTo ( newPool ) ;
189+ keyBuffer . CopyTo ( newPool ) ;
187190 keyBuffer = newPool ;
188191 if ( pool != null )
189192 {
0 commit comments