@@ -346,17 +346,65 @@ size_t StringBytes::Write(Isolate* isolate,
346
346
}
347
347
348
348
case BASE64URL:
349
- // Fall through
350
- case BASE64:
351
- if (str->IsExternalOneByte ()) {
349
+ if (str->IsExternalOneByte ()) { // 8-bit case
352
350
auto ext = str->GetExternalOneByteStringResource ();
353
- nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
351
+ auto result = simdutf::base64_to_binary_safe (
352
+ ext->data (), ext->length (), buf, buflen, simdutf::base64_url);
353
+ if (result.error == simdutf::error_code::SUCCESS) {
354
+ nbytes = result.count ;
355
+ } else {
356
+ // The input does not follow the WHATWG forgiving-base64 specification
357
+ // adapted for base64url
358
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
359
+ nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
360
+ }
354
361
} else {
355
362
String::Value value (isolate, str);
356
- nbytes = base64_decode (buf, buflen, *value, value.length ());
363
+ auto result =
364
+ simdutf::base64_to_binary (reinterpret_cast <const char16_t *>(*value),
365
+ value.length (),
366
+ buf,
367
+ simdutf::base64_url);
368
+ if (result.error == simdutf::error_code::SUCCESS) {
369
+ nbytes = result.count ;
370
+ } else {
371
+ // The input does not follow the WHATWG forgiving-base64 specification
372
+ // (adapted for base64url with + and / replaced by - and _).
373
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
374
+ nbytes = base64_decode (buf, buflen, *value, value.length ());
375
+ }
357
376
}
358
377
break ;
359
378
379
+ case BASE64: {
380
+ if (str->IsExternalOneByte ()) { // 8-bit case
381
+ auto ext = str->GetExternalOneByteStringResource ();
382
+ auto result = simdutf::base64_to_binary_safe (
383
+ ext->data (), ext->length (), buf, buflen);
384
+ if (result.error == simdutf::error_code::SUCCESS) {
385
+ nbytes = result.count ;
386
+ } else {
387
+ // The input does not follow the WHATWG forgiving-base64 specification
388
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
389
+ nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
390
+ }
391
+ } else {
392
+ String::Value value (isolate, str);
393
+ auto result = simdutf::base64_to_binary_safe (
394
+ reinterpret_cast <const char16_t *>(*value),
395
+ value.length (),
396
+ buf,
397
+ buflen);
398
+ if (result.error == simdutf::error_code::SUCCESS) {
399
+ nbytes = result.count ;
400
+ } else {
401
+ // The input does not follow the WHATWG base64 specification
402
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
403
+ nbytes = base64_decode (buf, buflen, *value, value.length ());
404
+ }
405
+ }
406
+ break ;
407
+ }
360
408
case HEX:
361
409
if (str->IsExternalOneByte ()) {
362
410
auto ext = str->GetExternalOneByteStringResource ();
@@ -411,9 +459,12 @@ Maybe<size_t> StringBytes::StorageSize(Isolate* isolate,
411
459
break ;
412
460
413
461
case BASE64URL:
414
- // Fall through
462
+ data_size = simdutf::base64_length_from_binary (str->Length (),
463
+ simdutf::base64_url);
464
+ break ;
465
+
415
466
case BASE64:
416
- data_size = base64_decoded_size_fast (str->Length ());
467
+ data_size = simdutf::base64_length_from_binary (str->Length ());
417
468
break ;
418
469
419
470
case HEX:
@@ -452,11 +503,16 @@ Maybe<size_t> StringBytes::Size(Isolate* isolate,
452
503
case UCS2:
453
504
return Just (str->Length () * sizeof (uint16_t ));
454
505
455
- case BASE64URL:
456
- // Fall through
506
+ case BASE64URL: {
507
+ String::Value value (isolate, str);
508
+ return Just (simdutf::base64_length_from_binary (value.length (),
509
+ simdutf::base64_url));
510
+ }
511
+
457
512
case BASE64: {
458
513
String::Value value (isolate, str);
459
- return Just (base64_decoded_size (*value, value.length ()));
514
+ return Just (simdutf::base64_length_from_binary (value.length (),
515
+ simdutf::base64_default));
460
516
}
461
517
462
518
case HEX:
@@ -609,28 +665,32 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
609
665
return ExternOneByteString::NewFromCopy (isolate, buf, buflen, error);
610
666
611
667
case BASE64: {
612
- size_t dlen = base64_encoded_size (buflen);
668
+ size_t dlen =
669
+ simdutf::base64_length_from_binary (buflen, simdutf::base64_default);
613
670
char * dst = node::UncheckedMalloc (dlen);
614
671
if (dst == nullptr ) {
615
672
*error = node::ERR_MEMORY_ALLOCATION_FAILED (isolate);
616
673
return MaybeLocal<Value>();
617
674
}
618
675
619
- size_t written = base64_encode (buf, buflen, dst, dlen);
676
+ size_t written =
677
+ simdutf::binary_to_base64 (buf, buflen, dst, simdutf::base64_default);
620
678
CHECK_EQ (written, dlen);
621
679
622
680
return ExternOneByteString::New (isolate, dst, dlen, error);
623
681
}
624
682
625
683
case BASE64URL: {
626
- size_t dlen = base64_encoded_size (buflen, Base64Mode::URL);
684
+ size_t dlen =
685
+ simdutf::base64_length_from_binary (buflen, simdutf::base64_url);
627
686
char * dst = node::UncheckedMalloc (dlen);
628
687
if (dst == nullptr ) {
629
688
*error = node::ERR_MEMORY_ALLOCATION_FAILED (isolate);
630
689
return MaybeLocal<Value>();
631
690
}
632
691
633
- size_t written = base64_encode (buf, buflen, dst, dlen, Base64Mode::URL);
692
+ size_t written =
693
+ simdutf::binary_to_base64 (buf, buflen, dst, simdutf::base64_url);
634
694
CHECK_EQ (written, dlen);
635
695
636
696
return ExternOneByteString::New (isolate, dst, dlen, error);
0 commit comments