1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <algorithm>
17 #include <codecvt>
18 #include <iostream>
19 #include <locale>
20 #include <vector>
21 
22 #include "commonlibrary/ets_utils/js_api_module/buffer/js_blob.h"
23 #include "commonlibrary/ets_utils/js_api_module/buffer/js_buffer.h"
24 #include "napi/native_api.h"
25 #include "napi/native_node_api.h"
26 
27 using namespace std;
28 
29 extern const char _binary_js_buffer_js_start[];
30 extern const char _binary_js_buffer_js_end[];
31 extern const char _binary_buffer_abc_start[];
32 extern const char _binary_buffer_abc_end[];
33 
34 namespace OHOS::buffer {
35 enum class ParaType:int32_t {
36     NUMBER = 0,
37     BUFFER,
38     UINT8ARRAY,
39     ARRAYBUFFER,
40     NUMBERS,
41     STRING
42 };
FinalizeBufferCallback(napi_env env,void * finalizeData,void * finalizeHint)43 void FinalizeBufferCallback(napi_env env, void *finalizeData, void *finalizeHint)
44 {
45     if (finalizeData != nullptr) {
46         auto obj = reinterpret_cast<Buffer *>(finalizeData);
47         delete obj;
48         obj = nullptr;
49     }
50 }
51 
FinalizeBlobCallback(napi_env env,void * finalizeData,void * finalizeHint)52 void FinalizeBlobCallback(napi_env env, void *finalizeData, void *finalizeHint)
53 {
54     if (finalizeData != nullptr) {
55         auto obj = reinterpret_cast<Blob *>(finalizeData);
56         delete obj;
57         obj = nullptr;
58     }
59 }
60 
GetStringUtf8(napi_env env,napi_value strValue)61 static string GetStringUtf8(napi_env env, napi_value strValue)
62 {
63     string str = "";
64     size_t strSize = 0;
65     NAPI_CALL(env, napi_get_value_string_utf8(env, strValue, nullptr, 0, &strSize));
66     str.reserve(strSize + 1);
67     str.resize(strSize);
68     NAPI_CALL(env, napi_get_value_string_utf8(env, strValue, const_cast<char *>(str.data()), strSize + 1, &strSize));
69     int pos = count(str.begin(), str.end(), '\0');
70     if (pos != 0) {
71         str.resize(strSize);
72     }
73     return str;
74 }
75 
GetStringASCII(napi_env env,napi_value strValue)76 static string GetStringASCII(napi_env env, napi_value strValue)
77 {
78     string str = "";
79     size_t strSize = 0;
80     NAPI_CALL(env, napi_get_value_string_latin1(env, strValue, nullptr, 0, &strSize));
81     str.reserve(strSize + 1);
82     str.resize(strSize);
83     NAPI_CALL(env, napi_get_value_string_latin1(env, strValue, const_cast<char *>(str.data()), strSize + 1, &strSize));
84     return str;
85 }
86 
GetString(napi_env env,EncodingType encodingType,napi_value strValue)87 static string GetString(napi_env env, EncodingType encodingType, napi_value strValue)
88 {
89     if (encodingType == BASE64 || encodingType == BASE64URL) {
90         return GetStringASCII(env, strValue);
91     } else {
92         return GetStringUtf8(env, strValue);
93     }
94 }
95 
FromStringUtf8(napi_env env,napi_value thisVar,napi_value str)96 static napi_value FromStringUtf8(napi_env env, napi_value thisVar, napi_value str)
97 {
98     string utf8Str = GetStringUtf8(env, str);
99     Buffer *buffer = nullptr;
100     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buffer)));
101     buffer->WriteString(utf8Str, utf8Str.length());
102 
103     return thisVar;
104 }
105 
FromStringASCII(napi_env env,napi_value thisVar,napi_value str,uint32_t size)106 static napi_value FromStringASCII(napi_env env, napi_value thisVar, napi_value str, uint32_t size)
107 {
108     string asciiStr = GetStringASCII(env, str);
109     Buffer *buffer = nullptr;
110     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buffer)));
111 
112     buffer->WriteString(asciiStr, size);
113     return thisVar;
114 }
115 
GetStringUtf16LE(napi_env env,napi_value strValue)116 static std::u16string GetStringUtf16LE(napi_env env, napi_value strValue)
117 {
118     string utf8Str = GetStringUtf8(env, strValue);
119     u16string u16Str = Utf8ToUtf16BE(utf8Str);
120     return Utf16BEToLE(u16Str);
121 }
122 
FromStringUtf16LE(napi_env env,napi_value thisVar,napi_value str)123 static napi_value FromStringUtf16LE(napi_env env, napi_value thisVar, napi_value str)
124 {
125     string utf8Str = GetStringUtf8(env, str);
126     Buffer *buffer = nullptr;
127     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buffer)));
128     u16string u16Str = Utf8ToUtf16BE(utf8Str);
129     // 2 : the size of string is 2 times of u16str's length
130     buffer->WriteString(u16Str, 0, u16Str.size() * 2);
131 
132     return thisVar;
133 }
134 
GetStringBase64(napi_env env,napi_value str,EncodingType type)135 static std::string GetStringBase64(napi_env env, napi_value str, EncodingType type)
136 {
137     string base64Str = GetStringASCII(env, str);
138     string strDecoded = Base64Decode(base64Str, type);
139     return strDecoded;
140 }
141 
FromStringBase64(napi_env env,napi_value thisVar,napi_value str,uint32_t size,EncodingType type)142 static napi_value FromStringBase64(napi_env env, napi_value thisVar, napi_value str, uint32_t size, EncodingType type)
143 {
144     string strDecoded = GetStringBase64(env, str, type);
145     Buffer *buffer = nullptr;
146     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buffer)));
147     size = (size < strDecoded.length()) ? size : strDecoded.length();
148     buffer->WriteString(strDecoded, size);
149     return thisVar;
150 }
151 
GetStringHex(napi_env env,napi_value str)152 static std::string GetStringHex(napi_env env, napi_value str)
153 {
154     string hexStr = GetStringASCII(env, str);
155     string strDecoded = HexDecode(hexStr);
156     return strDecoded;
157 }
158 
FromStringHex(napi_env env,napi_value thisVar,napi_value str)159 static napi_value FromStringHex(napi_env env, napi_value thisVar, napi_value str)
160 {
161     string hexStr = GetStringASCII(env, str);
162     Buffer *buffer = nullptr;
163     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buffer)));
164 
165     string strDecoded = HexDecode(hexStr);
166     buffer->WriteString(strDecoded, strDecoded.length());
167     buffer->SetLength(strDecoded.length());
168 
169     return thisVar;
170 }
171 
FromString(napi_env env,napi_callback_info info)172 static napi_value FromString(napi_env env, napi_callback_info info)
173 {
174     napi_value thisVar = nullptr;
175     size_t argc = 3;
176     napi_value args[3] = { nullptr };
177     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
178     // 2 : the third argument
179     NAPI_ASSERT(env, argc > 2, "Wrong number of arguments");
180 
181     uint32_t size = 0;
182     // 2 : the third argument
183     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &size));
184 
185     string type = GetStringASCII(env, args[1]);
186     EncodingType eType = Buffer::GetEncodingType(type);
187     switch (eType) {
188         case ASCII:
189         case LATIN1:
190         case BINARY:
191             return FromStringASCII(env, thisVar, args[0], size);
192         case UTF8:
193             return FromStringUtf8(env, thisVar, args[0]);
194         case UTF16LE:
195             return FromStringUtf16LE(env, thisVar, args[0]);
196         case BASE64:
197         case BASE64URL:
198             return FromStringBase64(env, thisVar, args[0], size, eType);
199         case HEX:
200             return FromStringHex(env, thisVar, args[0]);
201         default:
202             break;
203     }
204 
205     napi_value result = nullptr;
206     NAPI_CALL(env, napi_get_undefined(env, &result));
207     return result;
208 }
209 
GetArray(napi_env env,napi_value arr)210 static vector<uint8_t> GetArray(napi_env env, napi_value arr)
211 {
212     uint32_t length = 0;
213     napi_get_array_length(env, arr, &length);
214     napi_value napiNumber = nullptr;
215     vector<uint8_t> vec;
216     for (size_t i = 0; i < length; i++) {
217         napi_get_element(env, arr, i, &napiNumber);
218         uint32_t num = 0;
219         napi_get_value_uint32(env, napiNumber, &num);
220         // 255 : the max number of one byte unsigned value
221         num = num > 255 ? 0 : num;
222         vec.push_back(num);
223     }
224     return vec;
225 }
226 
freeBolbMemory(Blob * & blob)227 static void freeBolbMemory(Blob *&blob)
228 {
229     if (blob != nullptr) {
230         delete blob;
231         blob = nullptr;
232     }
233 }
234 
BlobConstructor(napi_env env,napi_callback_info info)235 static napi_value BlobConstructor(napi_env env, napi_callback_info info)
236 {
237     napi_value thisVar = nullptr;
238     Blob *blob = new (std::nothrow) Blob();
239     if (blob == nullptr) {
240         return nullptr;
241     }
242     size_t argc = 3; // the argument's count is 3
243     napi_value argv[3] = { nullptr }; // the argument's count is 3
244     if (napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr) != napi_ok) {
245         freeBolbMemory(blob);
246         return nullptr;
247     }
248     if (argc == 1) { // Array
249         vector<uint8_t> arr = GetArray(env, argv[0]);
250         blob->Init(arr.data(), arr.size());
251     } else { // Blob
252         Blob *blobIn = nullptr;
253         int32_t start = -1;
254         if (napi_get_value_int32(env, argv[1], &start) != napi_ok ||
255             napi_unwrap(env, argv[0], reinterpret_cast<void **>(&blobIn)) != napi_ok) {
256             freeBolbMemory(blob);
257             return nullptr;
258         }
259         if (argc == 2) { // 2 : the argument's count is 2
260             blob->Init(blobIn, start);
261         } else if (argc == 3) { // 3 : the argument's count is 3
262             int32_t end = -1;
263             if (napi_get_value_int32(env, argv[2], &end) != napi_ok) { // 2 : the third argument
264                 freeBolbMemory(blob);
265                 return nullptr;
266             }
267             blob->Init(blobIn, start, end);
268         } else {
269             freeBolbMemory(blob);
270             return nullptr;
271         }
272     }
273     if (napi_wrap(env, thisVar, blob,  FinalizeBlobCallback, nullptr, nullptr) != napi_ok) {
274         freeBolbMemory(blob);
275         return nullptr;
276     }
277     return thisVar;
278 }
279 
GetBufferWrapValue(napi_env env,napi_value thisVar,Buffer * buffer)280 static napi_value GetBufferWrapValue(napi_env env, napi_value thisVar, Buffer *buffer)
281 {
282     uint32_t length = buffer->GetNeedRelease() ? buffer->GetLength() : 0;
283     napi_status status = napi_wrap_with_size(env, thisVar, buffer, FinalizeBufferCallback, nullptr, nullptr, length);
284     if (status != napi_ok) {
285         HILOG_ERROR("Buffer:: can not wrap buffer");
286         if (buffer != nullptr) {
287             delete buffer;
288             buffer = nullptr;
289         }
290         return nullptr;
291     }
292     return thisVar;
293 }
294 
freeBufferMemory(Buffer * & buffer)295 static void freeBufferMemory(Buffer *&buffer)
296 {
297     if (buffer != nullptr) {
298         delete buffer;
299         buffer = nullptr;
300     }
301 }
302 
DealParaTypeBuffer(napi_env env,size_t argc,napi_value * argv,uint32_t length,Buffer * & buffer)303 static Buffer* DealParaTypeBuffer(napi_env env, size_t argc, napi_value* argv, uint32_t length, Buffer*& buffer)
304 {
305     Buffer *valueBuffer = nullptr;
306     if (napi_unwrap(env, argv[1], reinterpret_cast<void **>(&valueBuffer)) != napi_ok) {
307         return nullptr;
308     }
309     if (argc == 2) { // the count of argument is 2
310         buffer->Init(valueBuffer);
311     } else if (argc == 4) { // the count of argument is 4
312         uint32_t poolOffset = 0;
313         if (napi_get_value_uint32(env, argv[2], &poolOffset) != napi_ok || // 2 : the third argument
314             napi_get_value_uint32(env, argv[3], &length) != napi_ok) { // 3 : the forth argument
315             return nullptr;
316         }
317         buffer->Init(valueBuffer, poolOffset, length);
318     } else {
319         return nullptr;
320     }
321     return buffer;
322 }
323 
InitAnyArrayBuffer(napi_env env,napi_value * argv,Buffer * & buffer)324 static bool InitAnyArrayBuffer(napi_env env, napi_value* argv, Buffer *&buffer)
325 {
326     void *data = nullptr;
327     size_t bufferSize = 0;
328     uint32_t byteOffset = 0;
329     uint32_t length = 0;
330     bool isShared = false;
331     if (napi_get_value_uint32(env, argv[2], &byteOffset) != napi_ok || // 2 : the third argument
332         napi_get_value_uint32(env, argv[3], &length) != napi_ok) { // 3 : the fourth argument
333         freeBufferMemory(buffer);
334         return false;
335     }
336     if (napi_is_shared_array_buffer(env, argv[1], &isShared) != napi_ok) {
337         freeBufferMemory(buffer);
338         return false;
339     }
340     if (isShared) {
341         if (napi_get_shared_array_buffer_info(env, argv[1], &data, &bufferSize) != napi_ok) {
342             freeBufferMemory(buffer);
343             return false;
344         }
345         buffer->Init(reinterpret_cast<uint8_t*>(data), byteOffset, length);
346         return true;
347     }
348     if (napi_get_arraybuffer_info(env, argv[1], &data, &bufferSize) != napi_ok) {
349         freeBufferMemory(buffer);
350         return false;
351     }
352     buffer->Init(reinterpret_cast<uint8_t*>(data), byteOffset, length);
353     return true;
354 }
355 
BufferConstructorInner(napi_env env,size_t argc,napi_value * argv,ParaType paraType)356 static Buffer* BufferConstructorInner(napi_env env, size_t argc, napi_value* argv, ParaType paraType)
357 {
358     Buffer *buffer = new (std::nothrow) Buffer();
359     if (buffer == nullptr) {
360         HILOG_ERROR("BufferStructor:: buffer is nullptr");
361         return nullptr;
362     }
363     uint32_t length = 0;
364     if (paraType == ParaType::NUMBER) {
365         if (napi_get_value_uint32(env, argv[1], &length) != napi_ok) {
366             freeBufferMemory(buffer);
367             return nullptr;
368         }
369         buffer->Init(length);
370     } else if (paraType == ParaType::NUMBERS) {
371         vector<uint8_t> arr = GetArray(env, argv[1]);
372         buffer->Init(arr.size());
373         buffer->SetArray(arr);
374     } else if (paraType == ParaType::BUFFER) {
375         auto rstBuffer = DealParaTypeBuffer(env, argc, argv, length, buffer);
376         if (rstBuffer == nullptr) {
377             freeBufferMemory(buffer);
378             return nullptr;
379         }
380     } else if (paraType == ParaType::UINT8ARRAY) {
381         napi_typedarray_type type = napi_int8_array;
382         size_t offset = 0;
383         size_t aryLen = 0;
384         void *resultData = nullptr;
385         napi_value resultBuffer = nullptr;
386         if (napi_get_typedarray_info(env, argv[1], &type, &aryLen, &resultData, &resultBuffer, &offset) != napi_ok) {
387             freeBufferMemory(buffer);
388             return nullptr;
389         }
390         buffer->Init(reinterpret_cast<uint8_t *>(resultData) - offset, offset, aryLen);
391     } else if (paraType == ParaType::ARRAYBUFFER) {
392         if (!InitAnyArrayBuffer(env, argv, buffer)) {
393             return nullptr;
394         }
395     } else {
396         freeBufferMemory(buffer);
397         napi_throw_error(env, nullptr, "parameter type is error");
398         return nullptr;
399     }
400     return buffer;
401 }
402 
BufferConstructor(napi_env env,napi_callback_info info)403 static napi_value BufferConstructor(napi_env env, napi_callback_info info)
404 {
405     napi_value thisVar = nullptr;
406     size_t argc = 4; // the count of argument is 4
407     napi_value argv[4] = { nullptr };  // // the count of argument is 4
408     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
409 
410     int32_t pType = -1;
411     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &pType));
412     ParaType paraType = static_cast<ParaType>(pType);
413     if (paraType == ParaType::STRING) {
414         return nullptr;
415     }
416     Buffer *buffer = BufferConstructorInner(env, argc, argv, paraType);
417     if (buffer == nullptr) {
418         return nullptr;
419     }
420 
421     return GetBufferWrapValue(env, thisVar, buffer);
422 }
423 
GetValueOffsetAndBuf(napi_env env,napi_callback_info info,int32_t * pValue,uint32_t * pOffset)424 Buffer *GetValueOffsetAndBuf(napi_env env, napi_callback_info info, int32_t *pValue, uint32_t *pOffset)
425 {
426     napi_value thisVar = nullptr;
427     size_t argc = 2;
428     napi_value args[2] = { nullptr };
429     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
430     NAPI_ASSERT(env, argc > 1, "Wrong number of arguments.");
431 
432     Buffer *buf = nullptr;
433     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
434     NAPI_CALL(env, napi_get_value_int32(env, args[0], pValue));
435     NAPI_CALL(env, napi_get_value_uint32(env, args[1], pOffset));
436     return buf;
437 }
438 
GetOffsetAndBuf(napi_env env,napi_callback_info info,uint32_t * pOffset)439 Buffer *GetOffsetAndBuf(napi_env env, napi_callback_info info, uint32_t *pOffset)
440 {
441     napi_value thisVar = nullptr;
442     size_t argc = 1;
443     napi_value args[1] = { nullptr };
444     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
445     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
446 
447     Buffer *buf = nullptr;
448     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
449     NAPI_CALL(env, napi_get_value_uint32(env, args[0], pOffset));
450     return buf;
451 }
452 
WriteInt32BE(napi_env env,napi_callback_info info)453 static napi_value WriteInt32BE(napi_env env, napi_callback_info info)
454 {
455     int32_t value = 0;
456     uint32_t offset = 0;
457     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
458     if (buf != nullptr) {
459         buf->WriteInt32BE(value, offset);
460     }
461     napi_value result = nullptr;
462     NAPI_CALL(env, napi_get_undefined(env, &result));
463     return result;
464 }
465 
ReadInt32BE(napi_env env,napi_callback_info info)466 static napi_value ReadInt32BE(napi_env env, napi_callback_info info)
467 {
468     uint32_t offset = 0;
469     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
470     int32_t res = 0;
471     if (buf != nullptr) {
472         res = buf->ReadInt32BE(offset);
473     }
474     napi_value result = nullptr;
475     napi_create_int32(env, res, &result);
476     return result;
477 }
478 
SetArray(napi_env env,napi_callback_info info)479 static napi_value SetArray(napi_env env, napi_callback_info info)
480 {
481     napi_value thisVar = nullptr;
482     size_t argc = 1;
483     napi_value args[1] = { nullptr };
484     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
485     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
486 
487     bool isArray = false;
488     NAPI_CALL(env, napi_is_array(env, args[0], &isArray));
489     if (isArray) {
490         Buffer *buf = nullptr;
491         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
492         vector<uint8_t> arr = GetArray(env, args[0]);
493         buf->SetArray(arr);
494     }
495     napi_value result = nullptr;
496     NAPI_CALL(env, napi_get_undefined(env, &result));
497     return result;
498 }
499 
GetLength(napi_env env,napi_callback_info info)500 static napi_value GetLength(napi_env env, napi_callback_info info)
501 {
502     napi_value thisVar = nullptr;
503     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
504     Buffer *buf = nullptr;
505     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
506     uint32_t res = buf->GetLength();
507     napi_value result = nullptr;
508     napi_create_uint32(env, res, &result);
509     return result;
510 }
511 
GetByteOffset(napi_env env,napi_callback_info info)512 static napi_value GetByteOffset(napi_env env, napi_callback_info info)
513 {
514     napi_value thisVar = nullptr;
515     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
516     Buffer *buf = nullptr;
517     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
518     uint32_t res = buf->GetByteOffset();
519     napi_value result = nullptr;
520     napi_create_uint32(env, res, &result);
521     return result;
522 }
523 
WriteString(napi_env env,napi_callback_info info)524 static napi_value WriteString(napi_env env, napi_callback_info info)
525 {
526     napi_value thisVar = nullptr;
527     size_t argc = 4;
528     napi_value args[4] = { nullptr };
529     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
530     // 4 : 4 arguments is right
531     NAPI_ASSERT(env, argc == 4, "Wrong number of arguments.");
532 
533     // 3 : the forth argument
534     string encoding = GetStringASCII(env, args[3]);
535     EncodingType encodingType = Buffer::GetEncodingType(encoding);
536     string value = GetString(env, encodingType, args[0]);
537 
538     uint32_t offset = 0;
539     uint32_t length = 0;
540     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
541     // 2 : the third argument
542     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &length));
543 
544     Buffer *buf = nullptr;
545     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
546     length = (value.length() < length) ? value.length() : length;
547     unsigned int lengthWrote = buf->WriteString(value, offset, length, encoding);
548 
549     napi_value result = nullptr;
550     napi_create_uint32(env, lengthWrote, &result);
551     return result;
552 }
553 
FillString(napi_env env,napi_callback_info info)554 static napi_value FillString(napi_env env, napi_callback_info info)
555 {
556     napi_value thisVar = nullptr;
557     size_t argc = 4;
558     napi_value args[4] = { nullptr };
559     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
560     NAPI_ASSERT(env, argc > 3, "Wrong number of arguments."); // 3:The number of parameters is 3
561 
562     string encoding = GetStringASCII(env, args[3]);
563     EncodingType encodingType = Buffer::GetEncodingType(encoding);
564     string value = GetString(env, encodingType, args[0]);
565 
566     uint32_t offset = 0;
567     uint32_t end = 0;
568     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
569     // 2 : the third argument
570     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end));
571 
572     Buffer *buf = nullptr;
573     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
574     buf->FillString(value, offset, end, encoding);
575 
576     napi_value result = nullptr;
577     NAPI_CALL(env, napi_get_undefined(env, &result));
578     return result;
579 }
580 
FillNumbers(napi_env env,napi_callback_info info)581 static napi_value FillNumbers(napi_env env, napi_callback_info info)
582 {
583     napi_value thisVar = nullptr;
584     size_t argc = 3;
585     napi_value args[3] = { nullptr };
586     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
587     // 2 : the third argument
588     NAPI_ASSERT(env, argc > 2, "Wrong number of arguments.");
589 
590     uint32_t offset = 0;
591     uint32_t end = 0;
592     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
593     // 2 : the third argument
594     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end));
595 
596     Buffer *buf = nullptr;
597     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
598     vector<uint8_t> arr = GetArray(env, args[0]);
599     buf->FillNumber(arr, offset, end);
600 
601     napi_value result = nullptr;
602     NAPI_CALL(env, napi_get_undefined(env, &result));
603     return result;
604 }
605 
FillBuffer(napi_env env,napi_callback_info info)606 static napi_value FillBuffer(napi_env env, napi_callback_info info)
607 {
608     napi_value thisVar = nullptr;
609     size_t argc = 3;
610     napi_value args[3] = { nullptr };
611     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
612     // 2 : the third argument
613     NAPI_ASSERT(env, argc > 2, "Wrong number of arguments.");
614 
615     uint32_t offset = 0;
616     uint32_t end = 0;
617     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
618     // 2 : the third argument
619     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end));
620 
621     Buffer *buffer = nullptr;
622     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&buffer)));
623     Buffer *ego = nullptr;
624     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&ego)));
625     ego->FillBuffer(buffer, offset, end);
626 
627     napi_value result = nullptr;
628     NAPI_CALL(env, napi_get_undefined(env, &result));
629     return result;
630 }
631 
Utf8ByteLength(napi_env env,napi_callback_info info)632 static napi_value Utf8ByteLength(napi_env env, napi_callback_info info)
633 {
634     napi_value thisVar = nullptr;
635     size_t argc = 1;
636     napi_value args[1] = { nullptr };
637     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
638     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
639     size_t byteLen = 0;
640     NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], nullptr, 0, &byteLen));
641     napi_value result = nullptr;
642     napi_create_uint32(env, byteLen, &result);
643     return result;
644 }
645 
GetBufferData(napi_env env,napi_callback_info info)646 static napi_value GetBufferData(napi_env env, napi_callback_info info)
647 {
648     napi_value result = nullptr;
649     napi_value thisVar = nullptr;
650     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
651     Buffer *buf = nullptr;
652     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
653     uint32_t length = buf->GetLength();
654     uint8_t* data = new (std::nothrow) uint8_t[length];
655     if (data == nullptr) {
656         HILOG_ERROR("buffer:: data is nullptr");
657         return result;
658     }
659     buf->ReadBytes(data, 0, length);
660     NAPI_CALL(env, napi_create_array(env, &result));
661     size_t key = 0;
662     napi_value value = nullptr;
663     for (uint32_t i = 0, len = length; i < len; i++) {
664         napi_create_uint32(env, data[i], &value);
665         napi_set_element(env, result, key, value);
666         key++;
667     }
668     delete[] data;
669     data = nullptr;
670     return result;
671 }
672 
GetArrayBuffer(napi_env env,napi_callback_info info)673 static napi_value GetArrayBuffer(napi_env env, napi_callback_info info)
674 {
675     napi_value thisVar = nullptr;
676     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
677     Buffer *buf = nullptr;
678     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
679     uint32_t length = buf->GetLength();
680     void *data = nullptr;
681     napi_value arrayBuffer = nullptr;
682     NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer));
683     buf->ReadBytesForArrayBuffer(data, length);
684     return arrayBuffer;
685 }
686 
Get(napi_env env,napi_callback_info info)687 static napi_value Get(napi_env env, napi_callback_info info)
688 {
689     napi_value thisVar = nullptr;
690     size_t argc = 1;
691     napi_value args[1] = { nullptr };
692     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
693     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
694     uint32_t index = 0;
695     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &index));
696     Buffer *buf = nullptr;
697     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
698     int32_t value = buf->Get(index);
699     napi_value result = nullptr;
700     napi_create_int32(env, value, &result);
701     return result;
702 }
703 
Set(napi_env env,napi_callback_info info)704 static napi_value Set(napi_env env, napi_callback_info info)
705 {
706     napi_value thisVar = nullptr;
707     size_t argc = 2;
708     napi_value args[2] = { nullptr };
709     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
710     NAPI_ASSERT(env, argc > 1, "Wrong number of arguments.");
711 
712     Buffer *buf = nullptr;
713     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
714 
715     uint32_t index = 0;
716     int32_t value = 0;
717     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &index));
718     NAPI_CALL(env, napi_get_value_int32(env, args[1], &value));
719     buf->Set(index, value);
720     napi_value result = nullptr;
721     NAPI_CALL(env, napi_get_undefined(env, &result));
722     return result;
723 }
724 
WriteInt32LE(napi_env env,napi_callback_info info)725 static napi_value WriteInt32LE(napi_env env, napi_callback_info info)
726 {
727     int32_t value = 0;
728     uint32_t offset = 0;
729     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
730     if (buf != nullptr) {
731         buf->WriteInt32LE(value, offset);
732     }
733     napi_value result = nullptr;
734     NAPI_CALL(env, napi_get_undefined(env, &result));
735     return result;
736 }
737 
ReadInt32LE(napi_env env,napi_callback_info info)738 static napi_value ReadInt32LE(napi_env env, napi_callback_info info)
739 {
740     uint32_t offset = 0;
741     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
742     int32_t res = 0;
743     if (buf != nullptr) {
744         res = buf->ReadInt32LE(offset);
745     }
746     napi_value result = nullptr;
747     napi_create_int32(env, res, &result);
748     return result;
749 }
750 
WriteUInt32BE(napi_env env,napi_callback_info info)751 static napi_value WriteUInt32BE(napi_env env, napi_callback_info info)
752 {
753     int32_t value = 0;
754     uint32_t offset = 0;
755     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
756     if (buf != nullptr) {
757         buf->WriteUInt32BE(value, offset);
758     }
759     napi_value result = nullptr;
760     NAPI_CALL(env, napi_get_undefined(env, &result));
761     return result;
762 }
763 
ReadUInt32BE(napi_env env,napi_callback_info info)764 static napi_value ReadUInt32BE(napi_env env, napi_callback_info info)
765 {
766     uint32_t offset = 0;
767     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
768     uint32_t res = 0;
769     if (buf != nullptr) {
770         res = buf->ReadUInt32BE(offset);
771     }
772     napi_value result = nullptr;
773     napi_create_uint32(env, res, &result);
774     return result;
775 }
776 
WriteUInt32LE(napi_env env,napi_callback_info info)777 static napi_value WriteUInt32LE(napi_env env, napi_callback_info info)
778 {
779     int32_t value = 0;
780     uint32_t offset = 0;
781     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
782     if (buf != nullptr) {
783         buf->WriteUInt32LE(value, offset);
784     }
785     napi_value result = nullptr;
786     NAPI_CALL(env, napi_get_undefined(env, &result));
787     return result;
788 }
789 
ReadUInt32LE(napi_env env,napi_callback_info info)790 static napi_value ReadUInt32LE(napi_env env, napi_callback_info info)
791 {
792     uint32_t offset = 0;
793     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
794     uint32_t res = 0;
795     if (buf != nullptr) {
796         res = buf->ReadUInt32LE(offset);
797     }
798     napi_value result = nullptr;
799     napi_create_uint32(env, res, &result);
800     return result;
801 }
802 
SubBuffer(napi_env env,napi_callback_info info)803 static napi_value SubBuffer(napi_env env, napi_callback_info info)
804 {
805     napi_value thisVar = nullptr;
806     size_t argc = 3;
807     napi_value args[3] = { nullptr };
808     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
809     NAPI_ASSERT(env, argc == 3, "Wrong number of arguments"); // 3:Number of parameters.
810 
811     Buffer *newBuf = nullptr;
812     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&newBuf)));
813     Buffer *targetBuf = nullptr;
814     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&targetBuf)));
815 
816     uint32_t start = 0;
817     uint32_t end = 0;
818     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &start));
819     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end)); // 2:Array Size.
820     newBuf->SubBuffer(targetBuf, start, end);
821     napi_value result = nullptr;
822     NAPI_CALL(env, napi_get_undefined(env, &result));
823     return result;
824 }
825 
Copy(napi_env env,napi_callback_info info)826 static napi_value Copy(napi_env env, napi_callback_info info)
827 {
828     napi_value thisVar = nullptr;
829     size_t argc = 4;
830     napi_value args[4] = { nullptr };
831     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
832     // 4 : 4 arguments is right
833     NAPI_ASSERT(env, argc == 4, "Wrong number of arguments");
834     uint32_t targetStart = 0;
835     uint32_t sourceStart = 0;
836     uint32_t sourceEnd = 0;
837     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &targetStart));
838     // 2 : the third argument
839     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &sourceStart));
840     // 3 : the forth argument
841     NAPI_CALL(env, napi_get_value_uint32(env, args[3], &sourceEnd));
842     Buffer *targetBuf = nullptr;
843     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&targetBuf)));
844     Buffer *sBuf = nullptr;
845     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&sBuf)));
846     uint32_t cLength = sBuf->Copy(targetBuf, targetStart, sourceStart, sourceEnd);
847     napi_value result = nullptr;
848     napi_create_int32(env, cLength, &result);
849     return result;
850 }
851 
Compare(napi_env env,napi_callback_info info)852 static napi_value Compare(napi_env env, napi_callback_info info)
853 {
854     napi_value result = nullptr;
855     napi_value thisVar = nullptr;
856     size_t argc = 4;
857     napi_value args[4] = { nullptr };
858     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
859     uint32_t targetStart = 0;
860     uint32_t sourceStart = 0;
861     uint32_t length = 0;
862     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &targetStart));
863     // 2 : the third argument
864     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &sourceStart));
865     // 3 : the forth argument
866     NAPI_CALL(env, napi_get_value_uint32(env, args[3], &length));
867     Buffer *targetBuf = nullptr;
868     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&targetBuf)));
869     if (targetBuf == nullptr) {
870         HILOG_FATAL("buffer:: targetBuf is NULL");
871     }
872     Buffer *sBuf = nullptr;
873     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&sBuf)));
874     if (sBuf == nullptr) {
875         HILOG_FATAL("buffer:: sBuf is NULL");
876         napi_create_int32(env, 0, &result);
877         return result;
878     }
879     int res = sBuf->Compare(targetBuf, targetStart, sourceStart, length);
880     napi_create_int32(env, res, &result);
881     return result;
882 }
883 
ToUtf8(napi_env env,napi_callback_info info)884 static napi_value ToUtf8(napi_env env, napi_callback_info info)
885 {
886     napi_value thisVar = nullptr;
887     napi_value result = nullptr;
888     size_t argc = 2;
889     napi_value args[2] = { nullptr };
890     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
891     uint32_t start = 0;
892     uint32_t end = 0;
893     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &start));
894     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &end));
895     Buffer *buf = nullptr;
896     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buf)));
897     uint32_t length = end - start;
898     std::string data = "";
899     data.reserve(length + 1);
900     data.resize(length);
901     buf->ReadBytes(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data.c_str())), start, length);
902     napi_create_string_utf8(env, data.c_str(), length, &result);
903     return result;
904 }
905 
ToBase64(napi_env env,napi_callback_info info)906 static napi_value ToBase64(napi_env env, napi_callback_info info)
907 {
908     napi_value thisVar = nullptr;
909     size_t argc = 2;
910     napi_value args[2] = { nullptr };
911     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
912     uint32_t start = 0;
913     uint32_t end = 0;
914     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &start));
915     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &end));
916     Buffer *buf = nullptr;
917     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buf)));
918     uint32_t length = end - start;
919     std::string str = buf->ToBase64(start, length);
920     napi_value result = nullptr;
921     napi_create_string_latin1(env, str.c_str(), str.length(), &result);
922     return result;
923 }
924 
ToBase64Url(napi_env env,napi_callback_info info)925 static napi_value ToBase64Url(napi_env env, napi_callback_info info)
926 {
927     napi_value thisVar = nullptr;
928     size_t argc = 2;
929     napi_value args[2] = { nullptr };
930     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
931     uint32_t start = 0;
932     uint32_t end = 0;
933     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &start));
934     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &end));
935     Buffer *buf = nullptr;
936     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buf)));
937     uint32_t length = end - start;
938     std::string str = buf->ToBase64Url(start, length);
939     napi_value result = nullptr;
940     napi_create_string_latin1(env, str.c_str(), str.length(), &result);
941     return result;
942 }
943 
GetValue(napi_env env,EncodingType & eType,std::string & str,napi_value & args)944 uint32_t GetValue(napi_env env, EncodingType &eType, std::string &str, napi_value &args)
945 {
946     std::u16string u16Str = u"";
947     uint32_t len = 0;
948     switch (eType) {
949         case ASCII:
950         case LATIN1:
951         case BINARY:
952             str = GetStringASCII(env, args);
953             break;
954         case UTF8:
955             str = GetStringUtf8(env, args);
956             break;
957         case UTF16LE: {
958             u16Str = GetStringUtf16LE(env, args);
959             str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(u16Str);
960             len = u16Str.length() * 2; // 2 : 2 means the length of wide char String is 2 times of char String
961             break;
962         }
963         case BASE64:
964         case BASE64URL:
965             str = GetStringBase64(env, args, eType);
966             break;
967         case HEX:
968             str = GetStringHex(env, args);
969             break;
970         default:
971             break;
972     }
973     return len;
974 }
975 
IndexOf(napi_env env,napi_callback_info info)976 static napi_value IndexOf(napi_env env, napi_callback_info info)
977 {
978     napi_value thisVar = nullptr;
979     size_t argc = 4; // 4:The number of parameters is 4
980     napi_value args[4] = { nullptr }; // 4:The number of parameters is 4
981     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
982     uint32_t offset = 0;
983     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
984 
985     // 2 : the third argument
986     string type = GetStringASCII(env, args[2]);
987     EncodingType eType = Buffer::GetEncodingType(type);
988     std::string str = "";
989     uint32_t len = 0;
990     len = GetValue(env, eType, str, args[0]);
991     Buffer *buf = nullptr;
992     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
993     bool isReverse = false;
994     // 3 : the forth argument
995     NAPI_CALL(env, napi_get_value_bool(env, args[3], &isReverse));
996     int index = -1;
997     int indexNumber = -1;
998     uint64_t resultIndex = 0;
999     if (isReverse) {
1000         len = (eType == UTF16LE) ? len : str.length();
1001         index = buf->LastIndexOf(str.c_str(), offset, len);
1002     } else {
1003         len = (eType == UTF16LE) ? len : str.length();
1004         indexNumber = buf->IndexOf(str.c_str(), offset, len, resultIndex);
1005         if (indexNumber == -1) {
1006             index = indexNumber;
1007         } else {
1008             napi_value result = nullptr;
1009             napi_create_int64(env, resultIndex, &result);
1010             return result;
1011         }
1012     }
1013     napi_value result = nullptr;
1014     napi_create_int32(env, index, &result);
1015     return result;
1016 }
1017 
Utf8StringToNumbers(napi_env env,napi_callback_info info)1018 static napi_value Utf8StringToNumbers(napi_env env, napi_callback_info info)
1019 {
1020     napi_value thisVar = nullptr;
1021     size_t argc = 1;
1022     napi_value args[1] = { nullptr };
1023     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
1024 
1025     std::string str = GetStringUtf8(env, args[0]);
1026     napi_value result = nullptr;
1027     NAPI_CALL(env, napi_create_array(env, &result));
1028     size_t key = 0;
1029     napi_value value = nullptr;
1030     for (uint32_t i = 0; i < str.length(); i++) {
1031         napi_create_uint32(env, uint32_t(str.at(i) & 0xFF), &value);
1032         napi_set_element(env, result, key, value);
1033         key++;
1034     }
1035     return result;
1036 }
1037 
1038 struct PromiseInfo {
1039     napi_env env = nullptr;
1040     napi_async_work worker = nullptr;
1041     napi_deferred deferred = nullptr;
1042     napi_ref blobDataRef = nullptr;
1043 };
1044 
CopiedBlobToString(napi_env env,napi_status status,void * data)1045 static void CopiedBlobToString(napi_env env, napi_status status, void *data)
1046 {
1047     auto promiseInfo = reinterpret_cast<PromiseInfo *>(data);
1048     napi_value string = nullptr;
1049     napi_get_reference_value(env, promiseInfo->blobDataRef, &string);
1050     napi_resolve_deferred(env, promiseInfo->deferred, string);
1051     napi_delete_reference(env, promiseInfo->blobDataRef);
1052     napi_delete_async_work(env, promiseInfo->worker);
1053     delete promiseInfo;
1054 }
1055 
CopiedBlobToArrayBuffer(napi_env env,napi_status status,void * data)1056 static void CopiedBlobToArrayBuffer(napi_env env, napi_status status, void *data)
1057 {
1058     auto promiseInfo = reinterpret_cast<PromiseInfo *>(data);
1059     napi_value arrayBuffer = nullptr;
1060     napi_get_reference_value(env, promiseInfo->blobDataRef, &arrayBuffer);
1061     napi_resolve_deferred(env, promiseInfo->deferred, arrayBuffer);
1062     napi_delete_reference(env, promiseInfo->blobDataRef);
1063     napi_delete_async_work(env, promiseInfo->worker);
1064     delete promiseInfo;
1065 }
1066 
ArrayBufferAsync(napi_env env,napi_callback_info info)1067 static napi_value ArrayBufferAsync(napi_env env, napi_callback_info info)
1068 {
1069     napi_value thisVar = nullptr;
1070     napi_value resourceName = nullptr;
1071     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
1072     Blob *blob = nullptr;
1073     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&blob)));
1074     size_t bufferSize = blob->GetLength();
1075     void *bufdata = nullptr;
1076     napi_value arrayBuffer = nullptr;
1077     napi_value bufferPromise = nullptr;
1078     PromiseInfo *promiseInfo = new (std::nothrow) PromiseInfo();
1079     if (promiseInfo == nullptr) {
1080         HILOG_ERROR("buffer:: promiseInfo is nullptr");
1081         return nullptr;
1082     }
1083     napi_create_arraybuffer(env, bufferSize, &bufdata, &arrayBuffer);
1084     blob->ReadBytes(reinterpret_cast<uint8_t *>(bufdata), bufferSize);
1085     napi_create_reference(env, arrayBuffer, 1, &promiseInfo->blobDataRef);
1086     napi_create_promise(env, &promiseInfo->deferred, &bufferPromise);
1087     napi_create_string_utf8(env, "CopyBlobToArrayBuffer", NAPI_AUTO_LENGTH, &resourceName);
1088     napi_create_async_work(env, nullptr, resourceName, [](napi_env env, void* data) {}, CopiedBlobToArrayBuffer,
1089                            reinterpret_cast<void *>(promiseInfo), &promiseInfo->worker);
1090     napi_queue_async_work_with_qos(env, promiseInfo->worker, napi_qos_user_initiated);
1091     return bufferPromise;
1092 }
1093 
TextAsync(napi_env env,napi_callback_info info)1094 static napi_value TextAsync(napi_env env, napi_callback_info info)
1095 {
1096     napi_value thisVar = nullptr;
1097     napi_value resourceName = nullptr;
1098     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
1099     Blob *blob = nullptr;
1100     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&blob)));
1101     napi_value string = nullptr;
1102     PromiseInfo *promiseInfo = new (std::nothrow) PromiseInfo();
1103     if (promiseInfo == nullptr) {
1104         HILOG_ERROR("buffer:: promiseInfo is nullptr");
1105         return nullptr;
1106     }
1107     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->GetRaw()), blob->GetLength(), &string);
1108     napi_create_reference(env, string, 1, &promiseInfo->blobDataRef);
1109     napi_value textPromise = nullptr;
1110     napi_create_promise(env, &promiseInfo->deferred, &textPromise);
1111     napi_create_string_utf8(env, "GetPromiseOfString", NAPI_AUTO_LENGTH, &resourceName);
1112     napi_create_async_work(env, nullptr, resourceName, [](napi_env env, void* data) {}, CopiedBlobToString,
1113                            reinterpret_cast<void *>(promiseInfo), &promiseInfo->worker);
1114     napi_queue_async_work_with_qos(env, promiseInfo->worker, napi_qos_user_initiated);
1115     return textPromise;
1116 }
1117 
GetBytes(napi_env env,napi_callback_info info)1118 static napi_value GetBytes(napi_env env, napi_callback_info info)
1119 {
1120     napi_value thisVar = nullptr;
1121     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
1122     Blob *blob = nullptr;
1123     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&blob)));
1124     napi_value result = nullptr;
1125     NAPI_CALL(env, napi_create_array(env, &result));
1126     size_t key = 0;
1127     napi_value value = nullptr;
1128     for (unsigned int i = 0; i < blob->GetLength(); i++) {
1129         napi_create_uint32(env, uint32_t(blob->GetByte(i) & 0xFF), &value);
1130         napi_set_element(env, result, key, value);
1131         key++;
1132     }
1133     return result;
1134 }
1135 
BufferInit(napi_env env,napi_value exports)1136 static napi_value BufferInit(napi_env env, napi_value exports)
1137 {
1138     string className = "Buffer";
1139     napi_value bufferClass = nullptr;
1140     napi_property_descriptor bufferDesc[] = {
1141         DECLARE_NAPI_FUNCTION("writeInt32BE", WriteInt32BE),
1142         DECLARE_NAPI_FUNCTION("readInt32BE", ReadInt32BE),
1143         DECLARE_NAPI_FUNCTION("writeInt32LE", WriteInt32LE),
1144         DECLARE_NAPI_FUNCTION("readInt32LE", ReadInt32LE),
1145         DECLARE_NAPI_FUNCTION("writeUInt32BE", WriteUInt32BE),
1146         DECLARE_NAPI_FUNCTION("readUInt32BE", ReadUInt32BE),
1147         DECLARE_NAPI_FUNCTION("writeUInt32LE", WriteUInt32LE),
1148         DECLARE_NAPI_FUNCTION("readUInt32LE", ReadUInt32LE),
1149         DECLARE_NAPI_FUNCTION("setArray", SetArray),
1150         DECLARE_NAPI_FUNCTION("getLength", GetLength),
1151         DECLARE_NAPI_FUNCTION("getByteOffset", GetByteOffset),
1152         DECLARE_NAPI_FUNCTION("writeString", WriteString),
1153         DECLARE_NAPI_FUNCTION("fromString", FromString),
1154         DECLARE_NAPI_FUNCTION("fillString", FillString),
1155         DECLARE_NAPI_FUNCTION("fillNumbers", FillNumbers),
1156         DECLARE_NAPI_FUNCTION("fillBuffer", FillBuffer),
1157         DECLARE_NAPI_FUNCTION("getBufferData", GetBufferData),
1158         DECLARE_NAPI_FUNCTION("getArrayBuffer", GetArrayBuffer),
1159         DECLARE_NAPI_FUNCTION("get", Get),
1160         DECLARE_NAPI_FUNCTION("set", Set),
1161         DECLARE_NAPI_FUNCTION("subBuffer", SubBuffer),
1162         DECLARE_NAPI_FUNCTION("copy", Copy),
1163         DECLARE_NAPI_FUNCTION("compare", Compare),
1164         DECLARE_NAPI_FUNCTION("toUtf8", ToUtf8),
1165         DECLARE_NAPI_FUNCTION("toBase64", ToBase64),
1166         DECLARE_NAPI_FUNCTION("toBase64Url", ToBase64Url),
1167         DECLARE_NAPI_FUNCTION("indexOf", IndexOf),
1168     };
1169     NAPI_CALL(env, napi_define_class(env, className.c_str(), className.length(), BufferConstructor,
1170                                      nullptr, sizeof(bufferDesc) / sizeof(bufferDesc[0]), bufferDesc, &bufferClass));
1171     napi_property_descriptor desc[] = {
1172         DECLARE_NAPI_PROPERTY("Buffer", bufferClass),
1173     };
1174     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1175     return exports;
1176 }
1177 
BlobInit(napi_env env,napi_value exports)1178 static napi_value BlobInit(napi_env env, napi_value exports)
1179 {
1180     string className = "Blob";
1181     napi_value blobClass = nullptr;
1182     napi_property_descriptor blobDesc[] = {
1183         DECLARE_NAPI_FUNCTION("arraybuffer", ArrayBufferAsync),
1184         DECLARE_NAPI_FUNCTION("text", TextAsync),
1185         DECLARE_NAPI_FUNCTION("getBytes", GetBytes),
1186     };
1187     NAPI_CALL(env, napi_define_class(env, className.c_str(), className.length(), BlobConstructor,
1188                                      nullptr, sizeof(blobDesc) / sizeof(blobDesc[0]), blobDesc, &blobClass));
1189     napi_property_descriptor desc[] = {
1190         DECLARE_NAPI_PROPERTY("Blob", blobClass),
1191     };
1192     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1193     return exports;
1194 }
1195 
Init(napi_env env,napi_value exports)1196 static napi_value Init(napi_env env, napi_value exports)
1197 {
1198     napi_property_descriptor desc[] = {
1199         DECLARE_NAPI_FUNCTION("utf8ByteLength", Utf8ByteLength),
1200         DECLARE_NAPI_FUNCTION("utf8StringToNumbers", Utf8StringToNumbers),
1201     };
1202     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1203     BufferInit(env, exports);
1204     BlobInit(env, exports);
1205     return exports;
1206 }
1207 
1208 extern "C"
NAPI_buffer_GetJSCode(const char ** buf,int * bufLen)1209 __attribute__((visibility("default"))) void NAPI_buffer_GetJSCode(const char **buf, int *bufLen)
1210 {
1211     if (buf != nullptr) {
1212         *buf = _binary_js_buffer_js_start;
1213     }
1214 
1215     if (bufLen != nullptr) {
1216         *bufLen = _binary_js_buffer_js_end - _binary_js_buffer_js_start;
1217     }
1218 }
1219 
1220 extern "C"
NAPI_buffer_GetABCCode(const char ** buf,int * buflen)1221 __attribute__((visibility("default"))) void NAPI_buffer_GetABCCode(const char** buf, int* buflen)
1222 {
1223     if (buf != nullptr) {
1224         *buf = _binary_buffer_abc_start;
1225     }
1226     if (buflen != nullptr) {
1227         *buflen = _binary_buffer_abc_end - _binary_buffer_abc_start;
1228     }
1229 }
1230 
1231 static napi_module_with_js bufferModule = {
1232     .nm_version = 1,
1233     .nm_flags = 0,
1234     .nm_filename = nullptr,
1235     .nm_register_func = Init,
1236     .nm_modname = "buffer",
1237     .nm_priv = reinterpret_cast<void *>(0),
1238     .nm_get_abc_code = NAPI_buffer_GetABCCode,
1239     .nm_get_js_code = NAPI_buffer_GetJSCode,
1240 };
1241 
BufferRegisterModule()1242 extern "C" __attribute__((constructor)) void BufferRegisterModule()
1243 {
1244     napi_module_with_js_register(&bufferModule);
1245 }
1246 } // namespace OHOS::Buffer
1247