| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,20 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + const common = require('../common.js'); | ||
| 3 | + const assert = require('node:assert'); | ||
| 4 | + | ||
| 5 | + const bench = common.createBenchmark(main, { | ||
| 6 | + size: [16, 32, 64, 128, 256, 1024], | ||
| 7 | + n: [1e6], | ||
| 8 | + }); | ||
| 9 | + | ||
| 10 | + function main({ n, size }) { | ||
| 11 | + const input = 'A'.repeat(size); | ||
| 12 | + let out = 0; | ||
| 13 | + | ||
| 14 | + bench.start(); | ||
| 15 | + for (let i = 0; i < n; i++) { | ||
| 16 | + out += btoa(input).length; | ||
| 17 | + } | ||
| 18 | + bench.end(n); | ||
| 19 | + assert(out > 0); | ||
| 20 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -69,6 +69,7 @@ const { | |||
| 69 | 69 | kMaxLength, | |
| 70 | 70 | kStringMaxLength, | |
| 71 | 71 | atob: _atob, | |
| 72 | + btoa: _btoa, | ||
| 72 | 73 | } = internalBinding('buffer'); | |
| 73 | 74 | const { | |
| 74 | 75 | constants: { | |
@@ -1249,13 +1250,11 @@ function btoa(input) { | |||
| 1249 | 1250 | if (arguments.length === 0) { | |
| 1250 | 1251 | throw new ERR_MISSING_ARGS('input'); | |
| 1251 | 1252 | } | |
| 1252 | - input = `${input}`; | ||
| 1253 | - for (let n = 0; n < input.length; n++) { | ||
| 1254 | - if (input[n].charCodeAt(0) > 0xff) | ||
| 1255 | - throw lazyDOMException('Invalid character', 'InvalidCharacterError'); | ||
| 1253 | + const result = _btoa(`${input}`); | ||
| 1254 | + if (result === -1) { | ||
| 1255 | + throw lazyDOMException('Invalid character', 'InvalidCharacterError'); | ||
| 1256 | 1256 | } | |
| 1257 | - const buf = Buffer.from(input, 'latin1'); | ||
| 1258 | - return buf.toString('base64'); | ||
| 1257 | + return result; | ||
| 1259 | 1258 | } | |
| 1260 | 1259 | ||
| 1261 | 1260 | function atob(input) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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 | |
| Back | FazBrowse Home | New Git URL |
0 commit comments