• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     napi_status status = napi_wrap(env, thisVar, buffer, FinalizeBufferCallback, nullptr, nullptr);
283     if (status != napi_ok) {
284         HILOG_ERROR("Buffer:: can not wrap buffer");
285         if (buffer != nullptr) {
286             delete buffer;
287             buffer = nullptr;
288         }
289         return nullptr;
290     }
291     return thisVar;
292 }
293 
freeBufferMemory(Buffer * & buffer)294 static void freeBufferMemory(Buffer *&buffer)
295 {
296     if (buffer != nullptr) {
297         delete buffer;
298         buffer = nullptr;
299     }
300 }
301 
DealParaTypeBuffer(napi_env env,size_t argc,napi_value * argv,uint32_t length,Buffer * & buffer)302 static Buffer* DealParaTypeBuffer(napi_env env, size_t argc, napi_value* argv, uint32_t length, Buffer*& buffer)
303 {
304     Buffer *valueBuffer = nullptr;
305     if (napi_unwrap(env, argv[1], reinterpret_cast<void **>(&valueBuffer)) != napi_ok) {
306         return nullptr;
307     }
308     if (argc == 2) { // the count of argument is 2
309         buffer->Init(valueBuffer);
310     } else if (argc == 4) { // the count of argument is 4
311         uint32_t poolOffset = 0;
312         if (napi_get_value_uint32(env, argv[2], &poolOffset) != napi_ok || // 2 : the third argument
313             napi_get_value_uint32(env, argv[3], &length) != napi_ok) { // 3 : the forth argument
314             return nullptr;
315         }
316         buffer->Init(valueBuffer, poolOffset, length);
317     } else {
318         return nullptr;
319     }
320     return buffer;
321 }
322 
InitAnyArrayBuffer(napi_env env,napi_value * argv,Buffer * & buffer)323 static bool InitAnyArrayBuffer(napi_env env, napi_value* argv, Buffer *&buffer)
324 {
325     void *data = nullptr;
326     size_t bufferSize = 0;
327     uint32_t byteOffset = 0;
328     uint32_t length = 0;
329     bool isShared = false;
330     if (napi_get_value_uint32(env, argv[2], &byteOffset) != napi_ok || // 2 : the third argument
331         napi_get_value_uint32(env, argv[3], &length) != napi_ok) { // 3 : the fourth argument
332         freeBufferMemory(buffer);
333         return false;
334     }
335     if (napi_is_shared_array_buffer(env, argv[1], &isShared) != napi_ok) {
336         freeBufferMemory(buffer);
337         return false;
338     }
339     if (isShared) {
340         if (napi_get_shared_array_buffer_info(env, argv[1], &data, &bufferSize) != napi_ok) {
341             freeBufferMemory(buffer);
342             return false;
343         }
344         buffer->Init(reinterpret_cast<uint8_t*>(data), byteOffset, length);
345         return true;
346     }
347     if (napi_get_arraybuffer_info(env, argv[1], &data, &bufferSize) != napi_ok) {
348         freeBufferMemory(buffer);
349         return false;
350     }
351     buffer->Init(reinterpret_cast<uint8_t*>(data), byteOffset, length);
352     return true;
353 }
354 
BufferConstructorInner(napi_env env,size_t argc,napi_value * argv,ParaType paraType)355 static Buffer* BufferConstructorInner(napi_env env, size_t argc, napi_value* argv, ParaType paraType)
356 {
357     Buffer *buffer = new (std::nothrow) Buffer();
358     if (buffer == nullptr) {
359         HILOG_ERROR("BufferStructor:: buffer is nullptr");
360         return nullptr;
361     }
362     uint32_t length = 0;
363     if (paraType == ParaType::NUMBER) {
364         if (napi_get_value_uint32(env, argv[1], &length) != napi_ok) {
365             freeBufferMemory(buffer);
366             return nullptr;
367         }
368         buffer->Init(length);
369     } else if (paraType == ParaType::NUMBERS) {
370         vector<uint8_t> arr = GetArray(env, argv[1]);
371         buffer->Init(arr.size());
372         buffer->SetArray(arr);
373     } else if (paraType == ParaType::BUFFER) {
374         auto rstBuffer = DealParaTypeBuffer(env, argc, argv, length, buffer);
375         if (rstBuffer == nullptr) {
376             freeBufferMemory(buffer);
377             return nullptr;
378         }
379     } else if (paraType == ParaType::UINT8ARRAY) {
380         napi_typedarray_type type = napi_int8_array;
381         size_t offset = 0;
382         size_t aryLen = 0;
383         void *resultData = nullptr;
384         napi_value resultBuffer = nullptr;
385         if (napi_get_typedarray_info(env, argv[1], &type, &aryLen, &resultData, &resultBuffer, &offset) != napi_ok) {
386             freeBufferMemory(buffer);
387             return nullptr;
388         }
389         buffer->Init(reinterpret_cast<uint8_t *>(resultData) - offset, offset, aryLen);
390     } else if (paraType == ParaType::ARRAYBUFFER) {
391         if (!InitAnyArrayBuffer(env, argv, buffer)) {
392             return nullptr;
393         }
394     } else {
395         freeBufferMemory(buffer);
396         napi_throw_error(env, nullptr, "parameter type is error");
397         return nullptr;
398     }
399     return buffer;
400 }
401 
BufferConstructor(napi_env env,napi_callback_info info)402 static napi_value BufferConstructor(napi_env env, napi_callback_info info)
403 {
404     napi_value thisVar = nullptr;
405     size_t argc = 4; // the count of argument is 4
406     napi_value argv[4] = { nullptr };  // // the count of argument is 4
407     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
408 
409     int32_t pType = -1;
410     NAPI_CALL(env, napi_get_value_int32(env, argv[0], &pType));
411     ParaType paraType = static_cast<ParaType>(pType);
412     if (paraType == ParaType::STRING) {
413         return nullptr;
414     }
415     Buffer *buffer = BufferConstructorInner(env, argc, argv, paraType);
416     if (buffer == nullptr) {
417         return nullptr;
418     }
419 
420     return GetBufferWrapValue(env, thisVar, buffer);
421 }
422 
GetValueOffsetAndBuf(napi_env env,napi_callback_info info,int32_t * pValue,uint32_t * pOffset)423 Buffer *GetValueOffsetAndBuf(napi_env env, napi_callback_info info, int32_t *pValue, uint32_t *pOffset)
424 {
425     napi_value thisVar = nullptr;
426     size_t argc = 2;
427     napi_value args[2] = { nullptr };
428     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
429     NAPI_ASSERT(env, argc > 1, "Wrong number of arguments.");
430 
431     Buffer *buf = nullptr;
432     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
433     NAPI_CALL(env, napi_get_value_int32(env, args[0], pValue));
434     NAPI_CALL(env, napi_get_value_uint32(env, args[1], pOffset));
435     return buf;
436 }
437 
GetOffsetAndBuf(napi_env env,napi_callback_info info,uint32_t * pOffset)438 Buffer *GetOffsetAndBuf(napi_env env, napi_callback_info info, uint32_t *pOffset)
439 {
440     napi_value thisVar = nullptr;
441     size_t argc = 1;
442     napi_value args[1] = { nullptr };
443     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
444     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
445 
446     Buffer *buf = nullptr;
447     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
448     NAPI_CALL(env, napi_get_value_uint32(env, args[0], pOffset));
449     return buf;
450 }
451 
WriteInt32BE(napi_env env,napi_callback_info info)452 static napi_value WriteInt32BE(napi_env env, napi_callback_info info)
453 {
454     int32_t value = 0;
455     uint32_t offset = 0;
456     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
457     if (buf != nullptr) {
458         buf->WriteInt32BE(value, offset);
459     }
460     napi_value result = nullptr;
461     NAPI_CALL(env, napi_get_undefined(env, &result));
462     return result;
463 }
464 
ReadInt32BE(napi_env env,napi_callback_info info)465 static napi_value ReadInt32BE(napi_env env, napi_callback_info info)
466 {
467     uint32_t offset = 0;
468     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
469     int32_t res = 0;
470     if (buf != nullptr) {
471         res = buf->ReadInt32BE(offset);
472     }
473     napi_value result = nullptr;
474     napi_create_int32(env, res, &result);
475     return result;
476 }
477 
SetArray(napi_env env,napi_callback_info info)478 static napi_value SetArray(napi_env env, napi_callback_info info)
479 {
480     napi_value thisVar = nullptr;
481     size_t argc = 1;
482     napi_value args[1] = { nullptr };
483     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
484     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
485 
486     bool isArray = false;
487     NAPI_CALL(env, napi_is_array(env, args[0], &isArray));
488     if (isArray) {
489         Buffer *buf = nullptr;
490         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
491         vector<uint8_t> arr = GetArray(env, args[0]);
492         buf->SetArray(arr);
493     }
494     napi_value result = nullptr;
495     NAPI_CALL(env, napi_get_undefined(env, &result));
496     return result;
497 }
498 
GetLength(napi_env env,napi_callback_info info)499 static napi_value GetLength(napi_env env, napi_callback_info info)
500 {
501     napi_value thisVar = nullptr;
502     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
503     Buffer *buf = nullptr;
504     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
505     uint32_t res = buf->GetLength();
506     napi_value result = nullptr;
507     napi_create_uint32(env, res, &result);
508     return result;
509 }
510 
GetByteOffset(napi_env env,napi_callback_info info)511 static napi_value GetByteOffset(napi_env env, napi_callback_info info)
512 {
513     napi_value thisVar = nullptr;
514     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
515     Buffer *buf = nullptr;
516     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
517     uint32_t res = buf->GetByteOffset();
518     napi_value result = nullptr;
519     napi_create_uint32(env, res, &result);
520     return result;
521 }
522 
WriteString(napi_env env,napi_callback_info info)523 static napi_value WriteString(napi_env env, napi_callback_info info)
524 {
525     napi_value thisVar = nullptr;
526     size_t argc = 4;
527     napi_value args[4] = { nullptr };
528     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
529     // 4 : 4 arguments is right
530     NAPI_ASSERT(env, argc == 4, "Wrong number of arguments.");
531 
532     // 3 : the forth argument
533     string encoding = GetStringASCII(env, args[3]);
534     EncodingType encodingType = Buffer::GetEncodingType(encoding);
535     string value = GetString(env, encodingType, args[0]);
536 
537     uint32_t offset = 0;
538     uint32_t length = 0;
539     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
540     // 2 : the third argument
541     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &length));
542 
543     Buffer *buf = nullptr;
544     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
545     length = (value.length() < length) ? value.length() : length;
546     unsigned int lengthWrote = buf->WriteString(value, offset, length, encoding);
547 
548     napi_value result = nullptr;
549     napi_create_uint32(env, lengthWrote, &result);
550     return result;
551 }
552 
FillString(napi_env env,napi_callback_info info)553 static napi_value FillString(napi_env env, napi_callback_info info)
554 {
555     napi_value thisVar = nullptr;
556     size_t argc = 4;
557     napi_value args[4] = { nullptr };
558     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
559     NAPI_ASSERT(env, argc > 3, "Wrong number of arguments."); // 3:The number of parameters is 3
560 
561     string encoding = GetStringASCII(env, args[3]);
562     EncodingType encodingType = Buffer::GetEncodingType(encoding);
563     string value = GetString(env, encodingType, args[0]);
564 
565     uint32_t offset = 0;
566     uint32_t end = 0;
567     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
568     // 2 : the third argument
569     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end));
570 
571     Buffer *buf = nullptr;
572     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
573     buf->FillString(value, offset, end, encoding);
574 
575     napi_value result = nullptr;
576     NAPI_CALL(env, napi_get_undefined(env, &result));
577     return result;
578 }
579 
FillNumbers(napi_env env,napi_callback_info info)580 static napi_value FillNumbers(napi_env env, napi_callback_info info)
581 {
582     napi_value thisVar = nullptr;
583     size_t argc = 3;
584     napi_value args[3] = { nullptr };
585     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
586     // 2 : the third argument
587     NAPI_ASSERT(env, argc > 2, "Wrong number of arguments.");
588 
589     uint32_t offset = 0;
590     uint32_t end = 0;
591     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
592     // 2 : the third argument
593     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end));
594 
595     Buffer *buf = nullptr;
596     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
597     vector<uint8_t> arr = GetArray(env, args[0]);
598     buf->FillNumber(arr, offset, end);
599 
600     napi_value result = nullptr;
601     NAPI_CALL(env, napi_get_undefined(env, &result));
602     return result;
603 }
604 
FillBuffer(napi_env env,napi_callback_info info)605 static napi_value FillBuffer(napi_env env, napi_callback_info info)
606 {
607     napi_value thisVar = nullptr;
608     size_t argc = 3;
609     napi_value args[3] = { nullptr };
610     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
611     // 2 : the third argument
612     NAPI_ASSERT(env, argc > 2, "Wrong number of arguments.");
613 
614     uint32_t offset = 0;
615     uint32_t end = 0;
616     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
617     // 2 : the third argument
618     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end));
619 
620     Buffer *buffer = nullptr;
621     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&buffer)));
622     Buffer *ego = nullptr;
623     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&ego)));
624     ego->FillBuffer(buffer, offset, end);
625 
626     napi_value result = nullptr;
627     NAPI_CALL(env, napi_get_undefined(env, &result));
628     return result;
629 }
630 
Utf8ByteLength(napi_env env,napi_callback_info info)631 static napi_value Utf8ByteLength(napi_env env, napi_callback_info info)
632 {
633     napi_value thisVar = nullptr;
634     size_t argc = 1;
635     napi_value args[1] = { nullptr };
636     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
637     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
638     size_t byteLen = 0;
639     NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], nullptr, 0, &byteLen));
640     napi_value result = nullptr;
641     napi_create_uint32(env, byteLen, &result);
642     return result;
643 }
644 
GetBufferData(napi_env env,napi_callback_info info)645 static napi_value GetBufferData(napi_env env, napi_callback_info info)
646 {
647     napi_value result = nullptr;
648     napi_value thisVar = nullptr;
649     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
650     Buffer *buf = nullptr;
651     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
652     uint32_t length = buf->GetLength();
653     uint8_t* data = new (std::nothrow) uint8_t[length];
654     if (data == nullptr) {
655         HILOG_ERROR("buffer:: data is nullptr");
656         return result;
657     }
658     buf->ReadBytes(data, 0, length);
659     NAPI_CALL(env, napi_create_array(env, &result));
660     size_t key = 0;
661     napi_value value = nullptr;
662     for (uint32_t i = 0, len = length; i < len; i++) {
663         napi_create_uint32(env, data[i], &value);
664         napi_set_element(env, result, key, value);
665         key++;
666     }
667     delete[] data;
668     data = nullptr;
669     return result;
670 }
671 
GetArrayBuffer(napi_env env,napi_callback_info info)672 static napi_value GetArrayBuffer(napi_env env, napi_callback_info info)
673 {
674     napi_value thisVar = nullptr;
675     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
676     Buffer *buf = nullptr;
677     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
678     uint32_t length = buf->GetLength();
679     void *data = nullptr;
680     napi_value arrayBuffer = nullptr;
681     NAPI_CALL(env, napi_create_arraybuffer(env, length, &data, &arrayBuffer));
682     buf->ReadBytesForArrayBuffer(data, length);
683     return arrayBuffer;
684 }
685 
Get(napi_env env,napi_callback_info info)686 static napi_value Get(napi_env env, napi_callback_info info)
687 {
688     napi_value thisVar = nullptr;
689     size_t argc = 1;
690     napi_value args[1] = { nullptr };
691     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
692     NAPI_ASSERT(env, argc > 0, "Wrong number of arguments.");
693     uint32_t index = 0;
694     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &index));
695     Buffer *buf = nullptr;
696     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
697     int32_t value = buf->Get(index);
698     napi_value result = nullptr;
699     napi_create_int32(env, value, &result);
700     return result;
701 }
702 
Set(napi_env env,napi_callback_info info)703 static napi_value Set(napi_env env, napi_callback_info info)
704 {
705     napi_value thisVar = nullptr;
706     size_t argc = 2;
707     napi_value args[2] = { nullptr };
708     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
709     NAPI_ASSERT(env, argc > 1, "Wrong number of arguments.");
710 
711     Buffer *buf = nullptr;
712     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
713 
714     uint32_t index = 0;
715     int32_t value = 0;
716     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &index));
717     NAPI_CALL(env, napi_get_value_int32(env, args[1], &value));
718     buf->Set(index, value);
719     napi_value result = nullptr;
720     NAPI_CALL(env, napi_get_undefined(env, &result));
721     return result;
722 }
723 
WriteInt32LE(napi_env env,napi_callback_info info)724 static napi_value WriteInt32LE(napi_env env, napi_callback_info info)
725 {
726     int32_t value = 0;
727     uint32_t offset = 0;
728     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
729     if (buf != nullptr) {
730         buf->WriteInt32LE(value, offset);
731     }
732     napi_value result = nullptr;
733     NAPI_CALL(env, napi_get_undefined(env, &result));
734     return result;
735 }
736 
ReadInt32LE(napi_env env,napi_callback_info info)737 static napi_value ReadInt32LE(napi_env env, napi_callback_info info)
738 {
739     uint32_t offset = 0;
740     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
741     int32_t res = 0;
742     if (buf != nullptr) {
743         res = buf->ReadInt32LE(offset);
744     }
745     napi_value result = nullptr;
746     napi_create_int32(env, res, &result);
747     return result;
748 }
749 
WriteUInt32BE(napi_env env,napi_callback_info info)750 static napi_value WriteUInt32BE(napi_env env, napi_callback_info info)
751 {
752     int32_t value = 0;
753     uint32_t offset = 0;
754     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
755     if (buf != nullptr) {
756         buf->WriteUInt32BE(value, offset);
757     }
758     napi_value result = nullptr;
759     NAPI_CALL(env, napi_get_undefined(env, &result));
760     return result;
761 }
762 
ReadUInt32BE(napi_env env,napi_callback_info info)763 static napi_value ReadUInt32BE(napi_env env, napi_callback_info info)
764 {
765     uint32_t offset = 0;
766     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
767     uint32_t res = 0;
768     if (buf != nullptr) {
769         res = buf->ReadUInt32BE(offset);
770     }
771     napi_value result = nullptr;
772     napi_create_uint32(env, res, &result);
773     return result;
774 }
775 
WriteUInt32LE(napi_env env,napi_callback_info info)776 static napi_value WriteUInt32LE(napi_env env, napi_callback_info info)
777 {
778     int32_t value = 0;
779     uint32_t offset = 0;
780     Buffer *buf = GetValueOffsetAndBuf(env, info, &value, &offset);
781     if (buf != nullptr) {
782         buf->WriteUInt32LE(value, offset);
783     }
784     napi_value result = nullptr;
785     NAPI_CALL(env, napi_get_undefined(env, &result));
786     return result;
787 }
788 
ReadUInt32LE(napi_env env,napi_callback_info info)789 static napi_value ReadUInt32LE(napi_env env, napi_callback_info info)
790 {
791     uint32_t offset = 0;
792     Buffer *buf = GetOffsetAndBuf(env, info, &offset);
793     uint32_t res = 0;
794     if (buf != nullptr) {
795         res = buf->ReadUInt32LE(offset);
796     }
797     napi_value result = nullptr;
798     napi_create_uint32(env, res, &result);
799     return result;
800 }
801 
SubBuffer(napi_env env,napi_callback_info info)802 static napi_value SubBuffer(napi_env env, napi_callback_info info)
803 {
804     napi_value thisVar = nullptr;
805     size_t argc = 3;
806     napi_value args[3] = { nullptr };
807     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
808     NAPI_ASSERT(env, argc == 3, "Wrong number of arguments"); // 3:Number of parameters.
809 
810     Buffer *newBuf = nullptr;
811     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&newBuf)));
812     Buffer *targetBuf = nullptr;
813     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&targetBuf)));
814 
815     uint32_t start = 0;
816     uint32_t end = 0;
817     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &start));
818     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &end)); // 2:Array Size.
819     newBuf->SubBuffer(targetBuf, start, end);
820     napi_value result = nullptr;
821     NAPI_CALL(env, napi_get_undefined(env, &result));
822     return result;
823 }
824 
Copy(napi_env env,napi_callback_info info)825 static napi_value Copy(napi_env env, napi_callback_info info)
826 {
827     napi_value thisVar = nullptr;
828     size_t argc = 4;
829     napi_value args[4] = { nullptr };
830     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
831     // 4 : 4 arguments is right
832     NAPI_ASSERT(env, argc == 4, "Wrong number of arguments");
833     uint32_t targetStart = 0;
834     uint32_t sourceStart = 0;
835     uint32_t sourceEnd = 0;
836     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &targetStart));
837     // 2 : the third argument
838     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &sourceStart));
839     // 3 : the forth argument
840     NAPI_CALL(env, napi_get_value_uint32(env, args[3], &sourceEnd));
841     Buffer *targetBuf = nullptr;
842     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&targetBuf)));
843     Buffer *sBuf = nullptr;
844     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&sBuf)));
845     uint32_t cLength = sBuf->Copy(targetBuf, targetStart, sourceStart, sourceEnd);
846     napi_value result = nullptr;
847     napi_create_int32(env, cLength, &result);
848     return result;
849 }
850 
Compare(napi_env env,napi_callback_info info)851 static napi_value Compare(napi_env env, napi_callback_info info)
852 {
853     napi_value result = nullptr;
854     napi_value thisVar = nullptr;
855     size_t argc = 4;
856     napi_value args[4] = { nullptr };
857     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
858     uint32_t targetStart = 0;
859     uint32_t sourceStart = 0;
860     uint32_t length = 0;
861     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &targetStart));
862     // 2 : the third argument
863     NAPI_CALL(env, napi_get_value_uint32(env, args[2], &sourceStart));
864     // 3 : the forth argument
865     NAPI_CALL(env, napi_get_value_uint32(env, args[3], &length));
866     Buffer *targetBuf = nullptr;
867     NAPI_CALL(env, napi_unwrap(env, args[0], reinterpret_cast<void **>(&targetBuf)));
868     if (targetBuf == nullptr) {
869         HILOG_FATAL("buffer:: targetBuf is NULL");
870     }
871     Buffer *sBuf = nullptr;
872     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&sBuf)));
873     if (sBuf == nullptr) {
874         HILOG_FATAL("buffer:: sBuf is NULL");
875         napi_create_int32(env, 0, &result);
876         return result;
877     }
878     int res = sBuf->Compare(targetBuf, targetStart, sourceStart, length);
879     napi_create_int32(env, res, &result);
880     return result;
881 }
882 
ToUtf8(napi_env env,napi_callback_info info)883 static napi_value ToUtf8(napi_env env, napi_callback_info info)
884 {
885     napi_value thisVar = nullptr;
886     napi_value result = nullptr;
887     size_t argc = 2;
888     napi_value args[2] = { nullptr };
889     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
890     uint32_t start = 0;
891     uint32_t end = 0;
892     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &start));
893     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &end));
894     Buffer *buf = nullptr;
895     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buf)));
896     uint32_t length = end - start;
897     std::string data = "";
898     data.reserve(length + 1);
899     data.resize(length);
900     buf->ReadBytes(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data.c_str())), start, length);
901     napi_create_string_utf8(env, data.c_str(), length, &result);
902     return result;
903 }
904 
ToBase64(napi_env env,napi_callback_info info)905 static napi_value ToBase64(napi_env env, napi_callback_info info)
906 {
907     napi_value thisVar = nullptr;
908     size_t argc = 2;
909     napi_value args[2] = { nullptr };
910     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
911     uint32_t start = 0;
912     uint32_t end = 0;
913     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &start));
914     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &end));
915     Buffer *buf = nullptr;
916     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buf)));
917     uint32_t length = end - start;
918     std::string str = buf->ToBase64(start, length);
919     napi_value result = nullptr;
920     napi_create_string_latin1(env, str.c_str(), str.length(), &result);
921     return result;
922 }
923 
ToBase64Url(napi_env env,napi_callback_info info)924 static napi_value ToBase64Url(napi_env env, napi_callback_info info)
925 {
926     napi_value thisVar = nullptr;
927     size_t argc = 2;
928     napi_value args[2] = { nullptr };
929     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
930     uint32_t start = 0;
931     uint32_t end = 0;
932     NAPI_CALL(env, napi_get_value_uint32(env, args[0], &start));
933     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &end));
934     Buffer *buf = nullptr;
935     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&buf)));
936     uint32_t length = end - start;
937     std::string str = buf->ToBase64Url(start, length);
938     napi_value result = nullptr;
939     napi_create_string_latin1(env, str.c_str(), str.length(), &result);
940     return result;
941 }
942 
GetValue(napi_env env,EncodingType & eType,std::string & str,napi_value & args)943 uint32_t GetValue(napi_env env, EncodingType &eType, std::string &str, napi_value &args)
944 {
945     std::u16string u16Str = u"";
946     uint32_t len = 0;
947     switch (eType) {
948         case ASCII:
949         case LATIN1:
950         case BINARY:
951             str = GetStringASCII(env, args);
952             break;
953         case UTF8:
954             str = GetStringUtf8(env, args);
955             break;
956         case UTF16LE: {
957             u16Str = GetStringUtf16LE(env, args);
958             str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(u16Str);
959             len = u16Str.length() * 2; // 2 : 2 means the length of wide char String is 2 times of char String
960             break;
961         }
962         case BASE64:
963         case BASE64URL:
964             str = GetStringBase64(env, args, eType);
965             break;
966         case HEX:
967             str = GetStringHex(env, args);
968             break;
969         default:
970             break;
971     }
972     return len;
973 }
974 
IndexOf(napi_env env,napi_callback_info info)975 static napi_value IndexOf(napi_env env, napi_callback_info info)
976 {
977     napi_value thisVar = nullptr;
978     size_t argc = 4; // 4:The number of parameters is 4
979     napi_value args[4] = { nullptr }; // 4:The number of parameters is 4
980     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
981     uint32_t offset = 0;
982     NAPI_CALL(env, napi_get_value_uint32(env, args[1], &offset));
983 
984     // 2 : the third argument
985     string type = GetStringASCII(env, args[2]);
986     EncodingType eType = Buffer::GetEncodingType(type);
987     std::string str = "";
988     uint32_t len = 0;
989     len = GetValue(env, eType, str, args[0]);
990     Buffer *buf = nullptr;
991     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&buf)));
992     bool isReverse = false;
993     // 3 : the forth argument
994     NAPI_CALL(env, napi_get_value_bool(env, args[3], &isReverse));
995     int index = -1;
996     int indexNumber = -1;
997     uint64_t resultIndex = 0;
998     if (isReverse) {
999         len = (eType == UTF16LE) ? len : str.length();
1000         index = buf->LastIndexOf(str.c_str(), offset, len);
1001     } else {
1002         len = (eType == UTF16LE) ? len : str.length();
1003         indexNumber = buf->IndexOf(str.c_str(), offset, len, resultIndex);
1004         if (indexNumber == -1) {
1005             index = indexNumber;
1006         } else {
1007             napi_value result = nullptr;
1008             napi_create_int64(env, resultIndex, &result);
1009             return result;
1010         }
1011     }
1012     napi_value result = nullptr;
1013     napi_create_int32(env, index, &result);
1014     return result;
1015 }
1016 
Utf8StringToNumbers(napi_env env,napi_callback_info info)1017 static napi_value Utf8StringToNumbers(napi_env env, napi_callback_info info)
1018 {
1019     napi_value thisVar = nullptr;
1020     size_t argc = 1;
1021     napi_value args[1] = { nullptr };
1022     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
1023 
1024     std::string str = GetStringUtf8(env, args[0]);
1025     napi_value result = nullptr;
1026     NAPI_CALL(env, napi_create_array(env, &result));
1027     size_t key = 0;
1028     napi_value value = nullptr;
1029     for (uint32_t i = 0; i < str.length(); i++) {
1030         napi_create_uint32(env, uint32_t(str.at(i) & 0xFF), &value);
1031         napi_set_element(env, result, key, value);
1032         key++;
1033     }
1034     return result;
1035 }
1036 
1037 struct PromiseInfo {
1038     napi_env env = nullptr;
1039     napi_async_work worker = nullptr;
1040     napi_deferred deferred = nullptr;
1041     napi_ref blobDataRef = nullptr;
1042 };
1043 
CopiedBlobToString(napi_env env,napi_status status,void * data)1044 static void CopiedBlobToString(napi_env env, napi_status status, void *data)
1045 {
1046     auto promiseInfo = reinterpret_cast<PromiseInfo *>(data);
1047     napi_value string = nullptr;
1048     napi_get_reference_value(env, promiseInfo->blobDataRef, &string);
1049     napi_resolve_deferred(env, promiseInfo->deferred, string);
1050     napi_delete_reference(env, promiseInfo->blobDataRef);
1051     napi_delete_async_work(env, promiseInfo->worker);
1052     delete promiseInfo;
1053 }
1054 
CopiedBlobToArrayBuffer(napi_env env,napi_status status,void * data)1055 static void CopiedBlobToArrayBuffer(napi_env env, napi_status status, void *data)
1056 {
1057     auto promiseInfo = reinterpret_cast<PromiseInfo *>(data);
1058     napi_value arrayBuffer = nullptr;
1059     napi_get_reference_value(env, promiseInfo->blobDataRef, &arrayBuffer);
1060     napi_resolve_deferred(env, promiseInfo->deferred, arrayBuffer);
1061     napi_delete_reference(env, promiseInfo->blobDataRef);
1062     napi_delete_async_work(env, promiseInfo->worker);
1063     delete promiseInfo;
1064 }
1065 
ArrayBufferAsync(napi_env env,napi_callback_info info)1066 static napi_value ArrayBufferAsync(napi_env env, napi_callback_info info)
1067 {
1068     napi_value thisVar = nullptr;
1069     napi_value resourceName = nullptr;
1070     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
1071     Blob *blob = nullptr;
1072     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&blob)));
1073     size_t bufferSize = blob->GetLength();
1074     void *bufdata = nullptr;
1075     napi_value arrayBuffer = nullptr;
1076     napi_value bufferPromise = nullptr;
1077     PromiseInfo *promiseInfo = new (std::nothrow) PromiseInfo();
1078     if (promiseInfo == nullptr) {
1079         HILOG_ERROR("buffer:: promiseInfo is nullptr");
1080         return nullptr;
1081     }
1082     napi_create_arraybuffer(env, bufferSize, &bufdata, &arrayBuffer);
1083     blob->ReadBytes(reinterpret_cast<uint8_t *>(bufdata), bufferSize);
1084     napi_create_reference(env, arrayBuffer, 1, &promiseInfo->blobDataRef);
1085     napi_create_promise(env, &promiseInfo->deferred, &bufferPromise);
1086     napi_create_string_utf8(env, "CopyBlobToArrayBuffer", NAPI_AUTO_LENGTH, &resourceName);
1087     napi_create_async_work(env, nullptr, resourceName, [](napi_env env, void* data) {}, CopiedBlobToArrayBuffer,
1088                            reinterpret_cast<void *>(promiseInfo), &promiseInfo->worker);
1089     napi_queue_async_work_with_qos(env, promiseInfo->worker, napi_qos_user_initiated);
1090     return bufferPromise;
1091 }
1092 
TextAsync(napi_env env,napi_callback_info info)1093 static napi_value TextAsync(napi_env env, napi_callback_info info)
1094 {
1095     napi_value thisVar = nullptr;
1096     napi_value resourceName = nullptr;
1097     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
1098     Blob *blob = nullptr;
1099     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&blob)));
1100     napi_value string = nullptr;
1101     PromiseInfo *promiseInfo = new (std::nothrow) PromiseInfo();
1102     if (promiseInfo == nullptr) {
1103         HILOG_ERROR("buffer:: promiseInfo is nullptr");
1104         return nullptr;
1105     }
1106     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->GetRaw()), blob->GetLength(), &string);
1107     napi_create_reference(env, string, 1, &promiseInfo->blobDataRef);
1108     napi_value textPromise = nullptr;
1109     napi_create_promise(env, &promiseInfo->deferred, &textPromise);
1110     napi_create_string_utf8(env, "GetPromiseOfString", NAPI_AUTO_LENGTH, &resourceName);
1111     napi_create_async_work(env, nullptr, resourceName, [](napi_env env, void* data) {}, CopiedBlobToString,
1112                            reinterpret_cast<void *>(promiseInfo), &promiseInfo->worker);
1113     napi_queue_async_work_with_qos(env, promiseInfo->worker, napi_qos_user_initiated);
1114     return textPromise;
1115 }
1116 
GetBytes(napi_env env,napi_callback_info info)1117 static napi_value GetBytes(napi_env env, napi_callback_info info)
1118 {
1119     napi_value thisVar = nullptr;
1120     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
1121     Blob *blob = nullptr;
1122     NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(&blob)));
1123     napi_value result = nullptr;
1124     NAPI_CALL(env, napi_create_array(env, &result));
1125     size_t key = 0;
1126     napi_value value = nullptr;
1127     for (unsigned int i = 0; i < blob->GetLength(); i++) {
1128         napi_create_uint32(env, uint32_t(blob->GetByte(i) & 0xFF), &value);
1129         napi_set_element(env, result, key, value);
1130         key++;
1131     }
1132     return result;
1133 }
1134 
BufferInit(napi_env env,napi_value exports)1135 static napi_value BufferInit(napi_env env, napi_value exports)
1136 {
1137     string className = "Buffer";
1138     napi_value bufferClass = nullptr;
1139     napi_property_descriptor bufferDesc[] = {
1140         DECLARE_NAPI_FUNCTION("writeInt32BE", WriteInt32BE),
1141         DECLARE_NAPI_FUNCTION("readInt32BE", ReadInt32BE),
1142         DECLARE_NAPI_FUNCTION("writeInt32LE", WriteInt32LE),
1143         DECLARE_NAPI_FUNCTION("readInt32LE", ReadInt32LE),
1144         DECLARE_NAPI_FUNCTION("writeUInt32BE", WriteUInt32BE),
1145         DECLARE_NAPI_FUNCTION("readUInt32BE", ReadUInt32BE),
1146         DECLARE_NAPI_FUNCTION("writeUInt32LE", WriteUInt32LE),
1147         DECLARE_NAPI_FUNCTION("readUInt32LE", ReadUInt32LE),
1148         DECLARE_NAPI_FUNCTION("setArray", SetArray),
1149         DECLARE_NAPI_FUNCTION("getLength", GetLength),
1150         DECLARE_NAPI_FUNCTION("getByteOffset", GetByteOffset),
1151         DECLARE_NAPI_FUNCTION("writeString", WriteString),
1152         DECLARE_NAPI_FUNCTION("fromString", FromString),
1153         DECLARE_NAPI_FUNCTION("fillString", FillString),
1154         DECLARE_NAPI_FUNCTION("fillNumbers", FillNumbers),
1155         DECLARE_NAPI_FUNCTION("fillBuffer", FillBuffer),
1156         DECLARE_NAPI_FUNCTION("getBufferData", GetBufferData),
1157         DECLARE_NAPI_FUNCTION("getArrayBuffer", GetArrayBuffer),
1158         DECLARE_NAPI_FUNCTION("get", Get),
1159         DECLARE_NAPI_FUNCTION("set", Set),
1160         DECLARE_NAPI_FUNCTION("subBuffer", SubBuffer),
1161         DECLARE_NAPI_FUNCTION("copy", Copy),
1162         DECLARE_NAPI_FUNCTION("compare", Compare),
1163         DECLARE_NAPI_FUNCTION("toUtf8", ToUtf8),
1164         DECLARE_NAPI_FUNCTION("toBase64", ToBase64),
1165         DECLARE_NAPI_FUNCTION("toBase64Url", ToBase64Url),
1166         DECLARE_NAPI_FUNCTION("indexOf", IndexOf),
1167     };
1168     NAPI_CALL(env, napi_define_class(env, className.c_str(), className.length(), BufferConstructor,
1169                                      nullptr, sizeof(bufferDesc) / sizeof(bufferDesc[0]), bufferDesc, &bufferClass));
1170     napi_property_descriptor desc[] = {
1171         DECLARE_NAPI_PROPERTY("Buffer", bufferClass),
1172     };
1173     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1174     return exports;
1175 }
1176 
BlobInit(napi_env env,napi_value exports)1177 static napi_value BlobInit(napi_env env, napi_value exports)
1178 {
1179     string className = "Blob";
1180     napi_value blobClass = nullptr;
1181     napi_property_descriptor blobDesc[] = {
1182         DECLARE_NAPI_FUNCTION("arraybuffer", ArrayBufferAsync),
1183         DECLARE_NAPI_FUNCTION("text", TextAsync),
1184         DECLARE_NAPI_FUNCTION("getBytes", GetBytes),
1185     };
1186     NAPI_CALL(env, napi_define_class(env, className.c_str(), className.length(), BlobConstructor,
1187                                      nullptr, sizeof(blobDesc) / sizeof(blobDesc[0]), blobDesc, &blobClass));
1188     napi_property_descriptor desc[] = {
1189         DECLARE_NAPI_PROPERTY("Blob", blobClass),
1190     };
1191     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1192     return exports;
1193 }
1194 
Init(napi_env env,napi_value exports)1195 static napi_value Init(napi_env env, napi_value exports)
1196 {
1197     napi_property_descriptor desc[] = {
1198         DECLARE_NAPI_FUNCTION("utf8ByteLength", Utf8ByteLength),
1199         DECLARE_NAPI_FUNCTION("utf8StringToNumbers", Utf8StringToNumbers),
1200     };
1201     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1202     BufferInit(env, exports);
1203     BlobInit(env, exports);
1204     return exports;
1205 }
1206 
1207 extern "C"
NAPI_buffer_GetJSCode(const char ** buf,int * bufLen)1208 __attribute__((visibility("default"))) void NAPI_buffer_GetJSCode(const char **buf, int *bufLen)
1209 {
1210     if (buf != nullptr) {
1211         *buf = _binary_js_buffer_js_start;
1212     }
1213 
1214     if (bufLen != nullptr) {
1215         *bufLen = _binary_js_buffer_js_end - _binary_js_buffer_js_start;
1216     }
1217 }
1218 
1219 extern "C"
NAPI_buffer_GetABCCode(const char ** buf,int * buflen)1220 __attribute__((visibility("default"))) void NAPI_buffer_GetABCCode(const char** buf, int* buflen)
1221 {
1222     if (buf != nullptr) {
1223         *buf = _binary_buffer_abc_start;
1224     }
1225     if (buflen != nullptr) {
1226         *buflen = _binary_buffer_abc_end - _binary_buffer_abc_start;
1227     }
1228 }
1229 
1230 static napi_module_with_js bufferModule = {
1231     .nm_version = 1,
1232     .nm_flags = 0,
1233     .nm_filename = nullptr,
1234     .nm_register_func = Init,
1235     .nm_modname = "buffer",
1236     .nm_priv = reinterpret_cast<void *>(0),
1237     .nm_get_abc_code = NAPI_buffer_GetABCCode,
1238     .nm_get_js_code = NAPI_buffer_GetJSCode,
1239 };
1240 
BufferRegisterModule()1241 extern "C" __attribute__((constructor)) void BufferRegisterModule()
1242 {
1243     napi_module_with_js_register(&bufferModule);
1244 }
1245 } // namespace OHOS::Buffer
1246