@@ -346,17 +346,113 @@ 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
+ size_t written_len = buflen;
352
+ auto result = simdutf::base64_to_binary_safe (
353
+ ext->data (), ext->length (), buf, written_len, simdutf::base64_url);
354
+ if (result.error == simdutf::error_code::SUCCESS) {
355
+ nbytes = written_len;
356
+ } else {
357
+ // The input does not follow the WHATWG forgiving-base64 specification
358
+ // adapted for base64url
359
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
360
+ nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
361
+ }
362
+ } else if (str->IsOneByte ()) {
363
+ MaybeStackBuffer<uint8_t > stack_buf (str->Length ());
364
+ str->WriteOneByte (isolate,
365
+ stack_buf.out (),
366
+ 0 ,
367
+ str->Length (),
368
+ String::NO_NULL_TERMINATION);
369
+ size_t written_len = buflen;
370
+ auto result = simdutf::base64_to_binary_safe (
371
+ reinterpret_cast <const char *>(*stack_buf),
372
+ stack_buf.length (),
373
+ buf,
374
+ written_len,
375
+ simdutf::base64_url);
376
+ if (result.error == simdutf::error_code::SUCCESS) {
377
+ nbytes = written_len;
378
+ } else {
379
+ // The input does not follow the WHATWG forgiving-base64 specification
380
+ // (adapted for base64url with + and / replaced by - and _).
381
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
382
+ nbytes = base64_decode (buf, buflen, *stack_buf, stack_buf.length ());
383
+ }
354
384
} else {
355
385
String::Value value (isolate, str);
356
- nbytes = base64_decode (buf, buflen, *value, value.length ());
386
+ size_t written_len = buflen;
387
+ auto result = simdutf::base64_to_binary_safe (
388
+ reinterpret_cast <const char16_t *>(*value),
389
+ value.length (),
390
+ buf,
391
+ written_len,
392
+ simdutf::base64_url);
393
+ if (result.error == simdutf::error_code::SUCCESS) {
394
+ nbytes = written_len;
395
+ } else {
396
+ // The input does not follow the WHATWG forgiving-base64 specification
397
+ // (adapted for base64url with + and / replaced by - and _).
398
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
399
+ nbytes = base64_decode (buf, buflen, *value, value.length ());
400
+ }
357
401
}
358
402
break ;
359
403
404
+ case BASE64: {
405
+ if (str->IsExternalOneByte ()) { // 8-bit case
406
+ auto ext = str->GetExternalOneByteStringResource ();
407
+ size_t written_len = buflen;
408
+ auto result = simdutf::base64_to_binary_safe (
409
+ ext->data (), ext->length (), buf, written_len);
410
+ if (result.error == simdutf::error_code::SUCCESS) {
411
+ nbytes = written_len;
412
+ } else {
413
+ // The input does not follow the WHATWG forgiving-base64 specification
414
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
415
+ nbytes = base64_decode (buf, buflen, ext->data (), ext->length ());
416
+ }
417
+ } else if (str->IsOneByte ()) {
418
+ MaybeStackBuffer<uint8_t > stack_buf (str->Length ());
419
+ str->WriteOneByte (isolate,
420
+ stack_buf.out (),
421
+ 0 ,
422
+ str->Length (),
423
+ String::NO_NULL_TERMINATION);
424
+ size_t written_len = buflen;
425
+ auto result = simdutf::base64_to_binary_safe (
426
+ reinterpret_cast <const char *>(*stack_buf),
427
+ stack_buf.length (),
428
+ buf,
429
+ written_len);
430
+ if (result.error == simdutf::error_code::SUCCESS) {
431
+ nbytes = written_len;
432
+ } else {
433
+ // The input does not follow the WHATWG forgiving-base64 specification
434
+ // (adapted for base64url with + and / replaced by - and _).
435
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
436
+ nbytes = base64_decode (buf, buflen, *stack_buf, stack_buf.length ());
437
+ }
438
+ } else {
439
+ String::Value value (isolate, str);
440
+ size_t written_len = buflen;
441
+ auto result = simdutf::base64_to_binary_safe (
442
+ reinterpret_cast <const char16_t *>(*value),
443
+ value.length (),
444
+ buf,
445
+ written_len);
446
+ if (result.error == simdutf::error_code::SUCCESS) {
447
+ nbytes = written_len;
448
+ } else {
449
+ // The input does not follow the WHATWG base64 specification
450
+ // https://infra.spec.whatwg.org/#forgiving-base64-decode
451
+ nbytes = base64_decode (buf, buflen, *value, value.length ());
452
+ }
453
+ }
454
+ break ;
455
+ }
360
456
case HEX:
361
457
if (str->IsExternalOneByte ()) {
362
458
auto ext = str->GetExternalOneByteStringResource ();
@@ -411,9 +507,12 @@ Maybe<size_t> StringBytes::StorageSize(Isolate* isolate,
411
507
break ;
412
508
413
509
case BASE64URL:
414
- // Fall through
510
+ data_size = simdutf::base64_length_from_binary (str->Length (),
511
+ simdutf::base64_url);
512
+ break ;
513
+
415
514
case BASE64:
416
- data_size = base64_decoded_size_fast (str->Length ());
515
+ data_size = simdutf::base64_length_from_binary (str->Length ());
417
516
break ;
418
517
419
518
case HEX:
@@ -452,11 +551,15 @@ Maybe<size_t> StringBytes::Size(Isolate* isolate,
452
551
case UCS2:
453
552
return Just (str->Length () * sizeof (uint16_t ));
454
553
455
- case BASE64URL:
456
- // Fall through
554
+ case BASE64URL: {
555
+ String::Value value (isolate, str);
556
+ return Just (simdutf::base64_length_from_binary (value.length (),
557
+ simdutf::base64_url));
558
+ }
559
+
457
560
case BASE64: {
458
561
String::Value value (isolate, str);
459
- return Just (base64_decoded_size (*value, value.length ()));
562
+ return Just (simdutf::base64_length_from_binary ( value.length ()));
460
563
}
461
564
462
565
case HEX:
@@ -609,28 +712,30 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
609
712
return ExternOneByteString::NewFromCopy (isolate, buf, buflen, error);
610
713
611
714
case BASE64: {
612
- size_t dlen = base64_encoded_size (buflen);
715
+ size_t dlen = simdutf::base64_length_from_binary (buflen);
613
716
char * dst = node::UncheckedMalloc (dlen);
614
717
if (dst == nullptr ) {
615
718
*error = node::ERR_MEMORY_ALLOCATION_FAILED (isolate);
616
719
return MaybeLocal<Value>();
617
720
}
618
721
619
- size_t written = base64_encode (buf, buflen, dst, dlen );
722
+ size_t written = simdutf::binary_to_base64 (buf, buflen, dst);
620
723
CHECK_EQ (written, dlen);
621
724
622
725
return ExternOneByteString::New (isolate, dst, dlen, error);
623
726
}
624
727
625
728
case BASE64URL: {
626
- size_t dlen = base64_encoded_size (buflen, Base64Mode::URL);
729
+ size_t dlen =
730
+ simdutf::base64_length_from_binary (buflen, simdutf::base64_url);
627
731
char * dst = node::UncheckedMalloc (dlen);
628
732
if (dst == nullptr ) {
629
733
*error = node::ERR_MEMORY_ALLOCATION_FAILED (isolate);
630
734
return MaybeLocal<Value>();
631
735
}
632
736
633
- size_t written = base64_encode (buf, buflen, dst, dlen, Base64Mode::URL);
737
+ size_t written =
738
+ simdutf::binary_to_base64 (buf, buflen, dst, simdutf::base64_url);
634
739
CHECK_EQ (written, dlen);
635
740
636
741
return ExternOneByteString::New (isolate, dst, dlen, error);
0 commit comments