@@ -1211,6 +1211,63 @@ void DetachArrayBuffer(const FunctionCallbackInfo<Value>& args) {
1211
1211
}
1212
1212
}
1213
1213
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 =
1229
+ simdutf::binary_to_base64 (ext->data (), ext->length (), buffer.out ());
1230
+ } else if (input->IsOneByte ()) {
1231
+ MaybeStackBuffer<uint8_t > stack_buf (input->Length ());
1232
+ input->WriteOneByte (env->isolate (),
1233
+ stack_buf.out (),
1234
+ 0 ,
1235
+ input->Length (),
1236
+ String::NO_NULL_TERMINATION);
1237
+
1238
+ size_t expected_length =
1239
+ simdutf::base64_length_from_binary (input->Length ());
1240
+ buffer.AllocateSufficientStorage (expected_length + 1 );
1241
+ buffer.SetLengthAndZeroTerminate (expected_length);
1242
+ written =
1243
+ simdutf::binary_to_base64 (reinterpret_cast <const char *>(*stack_buf),
1244
+ input->Length (),
1245
+ buffer.out ());
1246
+ } else {
1247
+ String::Value value (env->isolate (), input);
1248
+ MaybeStackBuffer<char > stack_buf (value.length ());
1249
+ size_t out_len = simdutf::convert_utf16_to_latin1 (
1250
+ reinterpret_cast <const char16_t *>(*value),
1251
+ value.length (),
1252
+ stack_buf.out ());
1253
+ if (out_len == 0 ) { // error
1254
+ return args.GetReturnValue ().Set (-1 );
1255
+ }
1256
+ size_t expected_length = simdutf::base64_length_from_binary (out_len);
1257
+ buffer.AllocateSufficientStorage (expected_length + 1 );
1258
+ buffer.SetLengthAndZeroTerminate (expected_length);
1259
+ written = simdutf::binary_to_base64 (*stack_buf, out_len, buffer.out ());
1260
+ }
1261
+
1262
+ auto value =
1263
+ String::NewFromOneByte (env->isolate (),
1264
+ reinterpret_cast <const uint8_t *>(buffer.out ()),
1265
+ NewStringType::kNormal ,
1266
+ written)
1267
+ .ToLocalChecked ();
1268
+ return args.GetReturnValue ().Set (value);
1269
+ }
1270
+
1214
1271
// In case of success, the decoded string is returned.
1215
1272
// In case of error, a negative value is returned:
1216
1273
// * -1 indicates a single character remained,
@@ -1329,6 +1386,7 @@ void Initialize(Local<Object> target,
1329
1386
Isolate* isolate = env->isolate ();
1330
1387
1331
1388
SetMethodNoSideEffect (context, target, " atob" , Atob);
1389
+ SetMethodNoSideEffect (context, target, " btoa" , Btoa);
1332
1390
1333
1391
SetMethod (context, target, " setBufferPrototype" , SetBufferPrototype);
1334
1392
SetMethodNoSideEffect (context, target, " createFromString" , CreateFromString);
@@ -1433,6 +1491,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
1433
1491
registry->Register (CopyArrayBuffer);
1434
1492
1435
1493
registry->Register (Atob);
1494
+ registry->Register (Btoa);
1436
1495
}
1437
1496
1438
1497
} // namespace Buffer
0 commit comments