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