1+ #include " env-inl.h"
2+ #include " node.h"
3+ #include " node_external_reference.h"
4+ #include " node_internals.h"
5+ #include " util-inl.h"
6+ #include " v8-fast-api-calls.h"
7+ #include " v8.h"
8+
9+ namespace node {
10+
11+ using v8::ArrayBuffer;
12+ using v8::BackingStore;
13+ using v8::CFunction;
14+ using v8::Context;
15+ using v8::FastApiTypedArray;
16+ using v8::FastApiCallbackOptions;
17+ using v8::FastOneByteString;
18+ using v8::Isolate;
19+ using v8::Local;
20+ using v8::Object;
21+ using v8::String;
22+ using v8::Uint8Array;
23+ using v8::Value;
24+
25+ namespace encoding_methods {
26+
27+ void Encode (Isolate* isolate, Local<String> str, Local<Uint8Array> out) {
28+ Local<ArrayBuffer> buf = out->Buffer ();
29+ size_t out_length = out->ByteLength ();
30+ char * write_result = static_cast <char *>(buf->Data ()) + out->ByteOffset ();
31+
32+ str->WriteUtf8 (isolate,
33+ write_result,
34+ out_length,
35+ nullptr ,
36+ String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
37+ }
38+
39+ void EncodeUtf8 (const v8::FunctionCallbackInfo<Value>& args) {
40+ Environment* env = Environment::GetCurrent (args);
41+ Isolate* isolate = env->isolate ();
42+ CHECK_GE (args.Length (), 2 );
43+ CHECK (args[0 ]->IsString ());
44+ CHECK (args[1 ]->IsUint8Array ());
45+
46+ Local<String> str = args[0 ].As <String>();
47+ Local<Uint8Array> out = args[1 ].As <Uint8Array>();
48+ size_t utf8_length = str->Utf8Length (isolate);
49+
50+ if (utf8_length != out->Length ()) {
51+ auto buf = ArrayBuffer::New (isolate, utf8_length);
52+ auto correct_out = Uint8Array::New (buf, 0 , utf8_length);
53+ Encode (isolate, str, correct_out);
54+ args.GetReturnValue ().Set (correct_out);
55+ return ;
56+ }
57+
58+ Encode (isolate, str, out);
59+ args.GetReturnValue ().Set (out);
60+ }
61+
62+ void latin1_to_utf8 (const char * str, char * c) {
63+ for (; *str; ++str) {
64+ if (*str & 0x80 ) {
65+ *c++ = *str;
66+ } else {
67+ *c++ = (char )(0xc0 | (unsigned )*str >> 6 );
68+ *c++ = (char )(0x80 | (*str & 0x3f ));
69+ }
70+ }
71+ *c++ = ' \0 ' ;
72+ }
73+
74+ void FastEncodeUtf8 (Local<Value> receiver,
75+ const FastOneByteString& source,
76+ const FastApiTypedArray<uint8_t >& output,
77+ FastApiCallbackOptions& options) {
78+ options.fallback = true ;
79+ // uint8_t* storage;
80+ // auto is_available = output.getStorageIfAligned(&storage);
81+ // CHECK(is_available);
82+ // latin1_to_utf8(source.data, reinterpret_cast<char*>(storage));
83+ }
84+
85+ CFunction fast_encode_utf8_ (CFunction::Make(FastEncodeUtf8));
86+
87+ static void Initialize (Local<Object> target,
88+ Local<Value> unused,
89+ Local<Context> context,
90+ void * priv) {
91+ SetFastMethod (context, target, " encodeUtf8" , EncodeUtf8, &fast_encode_utf8_);
92+ }
93+
94+ void RegisterExternalReferences (ExternalReferenceRegistry* registry) {
95+ registry->Register (EncodeUtf8);
96+ registry->Register (FastEncodeUtf8);
97+ registry->Register (fast_encode_utf8_.GetTypeInfo ());
98+ }
99+
100+ } // namespace encoding_methods
101+ } // namespace node
102+
103+ NODE_BINDING_CONTEXT_AWARE_INTERNAL (encoding_methods,
104+ node::encoding_methods::Initialize)
105+ NODE_BINDING_EXTERNAL_REFERENCE(
106+ encoding_methods, node::encoding_methods::RegisterExternalReferences)
0 commit comments