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