|
24 | 24 | #include "node_blob.h"
|
25 | 25 | #include "node_errors.h"
|
26 | 26 | #include "node_external_reference.h"
|
| 27 | +#include "node_i18n.h" |
27 | 28 | #include "node_internals.h"
|
28 | 29 |
|
29 | 30 | #include "env-inl.h"
|
@@ -565,6 +566,48 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
|
565 | 566 | args.GetReturnValue().Set(ret);
|
566 | 567 | }
|
567 | 568 |
|
| 569 | +// Convert the input into an encoded string |
| 570 | +void DecodeUTF8(const FunctionCallbackInfo<Value>& args) { |
| 571 | + Environment* env = Environment::GetCurrent(args); // list, flags |
| 572 | + |
| 573 | + if (!(args[0]->IsArrayBuffer() || args[0]->IsSharedArrayBuffer() || |
| 574 | + args[0]->IsArrayBufferView())) { |
| 575 | + return node::THROW_ERR_INVALID_ARG_TYPE( |
| 576 | + env->isolate(), |
| 577 | + "The \"list\" argument must be an instance of SharedArrayBuffer, " |
| 578 | + "ArrayBuffer or ArrayBufferView."); |
| 579 | + } |
| 580 | + |
| 581 | + ArrayBufferViewContents<char> buffer(args[0]); |
| 582 | + |
| 583 | + CHECK(args[1]->IsBoolean()); |
| 584 | + bool ignore_bom = args[1]->IsTrue(); |
| 585 | + |
| 586 | + const char* data = buffer.data(); |
| 587 | + size_t length = buffer.length(); |
| 588 | + |
| 589 | + if (!ignore_bom && length >= 3) { |
| 590 | + if (memcmp(data, "\xEF\xBB\xBF", 3) == 0) { |
| 591 | + data += 3; |
| 592 | + length -= 3; |
| 593 | + } |
| 594 | + } |
| 595 | + |
| 596 | + if (length == 0) return args.GetReturnValue().SetEmptyString(); |
| 597 | + |
| 598 | + Local<Value> error; |
| 599 | + MaybeLocal<Value> maybe_ret = |
| 600 | + StringBytes::Encode(env->isolate(), data, length, UTF8, &error); |
| 601 | + Local<Value> ret; |
| 602 | + |
| 603 | + if (!maybe_ret.ToLocal(&ret)) { |
| 604 | + CHECK(!error.IsEmpty()); |
| 605 | + env->isolate()->ThrowException(error); |
| 606 | + return; |
| 607 | + } |
| 608 | + |
| 609 | + args.GetReturnValue().Set(ret); |
| 610 | +} |
568 | 611 |
|
569 | 612 | // bytesCopied = copy(buffer, target[, targetStart][, sourceStart][, sourceEnd])
|
570 | 613 | void Copy(const FunctionCallbackInfo<Value> &args) {
|
@@ -1282,6 +1325,7 @@ void Initialize(Local<Object> target,
|
1282 | 1325 |
|
1283 | 1326 | SetMethod(context, target, "setBufferPrototype", SetBufferPrototype);
|
1284 | 1327 | SetMethodNoSideEffect(context, target, "createFromString", CreateFromString);
|
| 1328 | + SetMethodNoSideEffect(context, target, "decodeUTF8", DecodeUTF8); |
1285 | 1329 |
|
1286 | 1330 | SetMethodNoSideEffect(context, target, "byteLengthUtf8", ByteLengthUtf8);
|
1287 | 1331 | SetMethod(context, target, "copy", Copy);
|
@@ -1339,6 +1383,7 @@ void Initialize(Local<Object> target,
|
1339 | 1383 | void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
|
1340 | 1384 | registry->Register(SetBufferPrototype);
|
1341 | 1385 | registry->Register(CreateFromString);
|
| 1386 | + registry->Register(DecodeUTF8); |
1342 | 1387 |
|
1343 | 1388 | registry->Register(ByteLengthUtf8);
|
1344 | 1389 | registry->Register(Copy);
|
|
0 commit comments