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