@@ -1211,6 +1211,40 @@ void DetachArrayBuffer(const FunctionCallbackInfo<Value>& args) {
12111211 }
12121212}
12131213
1214+ static void Btoa (const FunctionCallbackInfo<Value>& args) {
1215+ CHECK_EQ (args.Length (), 1 );
1216+ Environment* env = Environment::GetCurrent (args);
1217+ THROW_AND_RETURN_IF_NOT_STRING (env, args[0 ], " argument" );
1218+
1219+ Local<String> input = args[0 ].As <String>();
1220+ MaybeStackBuffer<char > buffer;
1221+ size_t written;
1222+
1223+ if (input->IsExternalOneByte ()) { // 8-bit case
1224+ auto ext = input->GetExternalOneByteStringResource ();
1225+ size_t expected_length = simdutf::base64_length_from_binary (ext->length ());
1226+ buffer.AllocateSufficientStorage (expected_length + 1 );
1227+ buffer.SetLengthAndZeroTerminate (expected_length);
1228+ written = simdutf::binary_to_base64 (
1229+ ext->data (), ext->length (), buffer.out (), simdutf::base64_default);
1230+ } else { // UTF-8 case
1231+ Utf8Value value (env->isolate (), input);
1232+ size_t expected_length = simdutf::base64_length_from_binary (value.length ());
1233+ buffer.AllocateSufficientStorage (expected_length + 1 );
1234+ buffer.SetLengthAndZeroTerminate (expected_length);
1235+ written = simdutf::binary_to_base64 (
1236+ value.out (), value.length (), buffer.out (), simdutf::base64_default);
1237+ }
1238+
1239+ auto value =
1240+ String::NewFromOneByte (env->isolate (),
1241+ reinterpret_cast <const uint8_t *>(buffer.out ()),
1242+ NewStringType::kNormal ,
1243+ written)
1244+ .ToLocalChecked ();
1245+ return args.GetReturnValue ().Set (value);
1246+ }
1247+
12141248// In case of success, the decoded string is returned.
12151249// In case of error, a negative value is returned:
12161250// * -1 indicates a single character remained,
@@ -1329,6 +1363,7 @@ void Initialize(Local<Object> target,
13291363 Isolate* isolate = env->isolate ();
13301364
13311365 SetMethodNoSideEffect (context, target, " atob" , Atob);
1366+ SetMethodNoSideEffect (context, target, " btoa" , Btoa);
13321367
13331368 SetMethod (context, target, " setBufferPrototype" , SetBufferPrototype);
13341369 SetMethodNoSideEffect (context, target, " createFromString" , CreateFromString);
@@ -1433,6 +1468,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
14331468 registry->Register (CopyArrayBuffer);
14341469
14351470 registry->Register (Atob);
1471+ registry->Register (Btoa);
14361472}
14371473
14381474} // namespace Buffer
0 commit comments