@@ -190,36 +190,6 @@ public static int GetArraySizeRequiredToDecode(int count)
190
190
return checked ( count + numPaddingCharsToAdd ) ;
191
191
}
192
192
193
- /// <summary>
194
- /// Encodes <paramref name="input"/> using base64url encoding.
195
- /// </summary>
196
- /// <param name="input">The binary input to encode.</param>
197
- /// <returns>The base64url-encoded form of <paramref name="input"/>.</returns>
198
- public static string Base64UrlEncode ( ReadOnlySpan < byte > input )
199
- {
200
- if ( input . IsEmpty )
201
- {
202
- return string . Empty ;
203
- }
204
-
205
- int bufferSize = GetArraySizeRequiredToEncode ( input . Length ) ;
206
-
207
- char [ ] bufferToReturnToPool = null ;
208
- Span < char > buffer = bufferSize <= 128
209
- ? stackalloc char [ bufferSize ]
210
- : bufferToReturnToPool = ArrayPool < char > . Shared . Rent ( bufferSize ) ;
211
-
212
- var numBase64Chars = Base64UrlEncode ( input , buffer ) ;
213
- var base64Url = new string ( buffer . Slice ( 0 , numBase64Chars ) ) ;
214
-
215
- if ( bufferToReturnToPool != null )
216
- {
217
- ArrayPool < char > . Shared . Return ( bufferToReturnToPool ) ;
218
- }
219
-
220
- return base64Url ;
221
- }
222
-
223
193
/// <summary>
224
194
/// Encodes <paramref name="input"/> using base64url encoding.
225
195
/// </summary>
@@ -251,7 +221,20 @@ public static string Base64UrlEncode(byte[] input, int offset, int count)
251
221
252
222
ValidateParameters ( input . Length , nameof ( input ) , offset , count ) ;
253
223
224
+ #if NETCOREAPP3_0
254
225
return Base64UrlEncode ( input . AsSpan ( offset , count ) ) ;
226
+ #else
227
+ // Special-case empty input
228
+ if ( count == 0 )
229
+ {
230
+ return string . Empty ;
231
+ }
232
+
233
+ var buffer = new char [ GetArraySizeRequiredToEncode ( count ) ] ;
234
+ var numBase64Chars = Base64UrlEncode ( input , offset , buffer , outputOffset : 0 , count : count ) ;
235
+
236
+ return new string ( buffer , startIndex : 0 , length : numBase64Chars ) ;
237
+ #endif
255
238
}
256
239
257
240
/// <summary>
@@ -302,7 +285,41 @@ public static int Base64UrlEncode(byte[] input, int offset, char[] output, int o
302
285
nameof ( count ) ) ;
303
286
}
304
287
288
+ #if NETCOREAPP3_0
305
289
return Base64UrlEncode ( input . AsSpan ( offset , count ) , output . AsSpan ( outputOffset ) ) ;
290
+ #else
291
+ // Special-case empty input.
292
+ if ( count == 0 )
293
+ {
294
+ return 0 ;
295
+ }
296
+
297
+ // Use base64url encoding with no padding characters. See RFC 4648, Sec. 5.
298
+
299
+ // Start with default Base64 encoding.
300
+ var numBase64Chars = Convert . ToBase64CharArray ( input , offset , count , output , outputOffset ) ;
301
+
302
+ // Fix up '+' -> '-' and '/' -> '_'. Drop padding characters.
303
+ for ( var i = outputOffset ; i - outputOffset < numBase64Chars ; i ++ )
304
+ {
305
+ var ch = output [ i ] ;
306
+ if ( ch == '+' )
307
+ {
308
+ output [ i ] = '-' ;
309
+ }
310
+ else if ( ch == '/' )
311
+ {
312
+ output [ i ] = '_' ;
313
+ }
314
+ else if ( ch == '=' )
315
+ {
316
+ // We've reached a padding character; truncate the remainder.
317
+ return i - outputOffset ;
318
+ }
319
+ }
320
+
321
+ return numBase64Chars ;
322
+ #endif
306
323
}
307
324
308
325
/// <summary>
@@ -319,6 +336,37 @@ public static int GetArraySizeRequiredToEncode(int count)
319
336
return checked ( numWholeOrPartialInputBlocks * 4 ) ;
320
337
}
321
338
339
+ #if NETCOREAPP3_0
340
+ /// <summary>
341
+ /// Encodes <paramref name="input"/> using base64url encoding.
342
+ /// </summary>
343
+ /// <param name="input">The binary input to encode.</param>
344
+ /// <returns>The base64url-encoded form of <paramref name="input"/>.</returns>
345
+ public static string Base64UrlEncode ( ReadOnlySpan < byte > input )
346
+ {
347
+ if ( input . IsEmpty )
348
+ {
349
+ return string . Empty ;
350
+ }
351
+
352
+ int bufferSize = GetArraySizeRequiredToEncode ( input . Length ) ;
353
+
354
+ char [ ] bufferToReturnToPool = null ;
355
+ Span < char > buffer = bufferSize <= 128
356
+ ? stackalloc char [ bufferSize ]
357
+ : bufferToReturnToPool = ArrayPool < char > . Shared . Rent ( bufferSize ) ;
358
+
359
+ var numBase64Chars = Base64UrlEncode ( input , buffer ) ;
360
+ var base64Url = new string ( buffer . Slice ( 0 , numBase64Chars ) ) ;
361
+
362
+ if ( bufferToReturnToPool != null )
363
+ {
364
+ ArrayPool < char > . Shared . Return ( bufferToReturnToPool ) ;
365
+ }
366
+
367
+ return base64Url ;
368
+ }
369
+
322
370
private static int Base64UrlEncode ( ReadOnlySpan < byte > input , Span < char > output )
323
371
{
324
372
Debug . Assert ( output . Length >= GetArraySizeRequiredToEncode ( input . Length ) ) ;
@@ -353,6 +401,7 @@ private static int Base64UrlEncode(ReadOnlySpan<byte> input, Span<char> output)
353
401
354
402
return charsWritten ;
355
403
}
404
+ #endif
356
405
357
406
private static int GetNumBase64PaddingCharsInString ( string str )
358
407
{
0 commit comments