• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_message_sequence.h"
17 
18 #include <cinttypes>
19 #include <cstring>
20 #include <unistd.h>
21 
22 #include "hilog/log.h"
23 #include "ipc_debug.h"
24 #include "log_tags.h"
25 #include "napi_ashmem.h"
26 #include "napi_remote_object.h"
27 #include "string_ex.h"
28 
29 namespace OHOS {
30 using namespace OHOS::HiviewDFX;
31 constexpr size_t MAX_CAPACITY_TO_WRITE = 200 * 1024;
32 constexpr size_t BYTE_SIZE_8 = 1;
33 constexpr size_t BYTE_SIZE_32 = 4;
34 constexpr size_t BYTE_SIZE_64 = 8;
35 
36 NapiError NAPI_MessageSequence::napiErr;
37 
38 static const size_t ARGV_INDEX_0 = 0;
39 static const size_t ARGV_INDEX_1 = 1;
40 
41 static const size_t ARGV_LENGTH_1 = 1;
42 static const size_t ARGV_LENGTH_2 = 2;
43 static const size_t REQUIRED_ARGS_COUNT_1 = 1;  // "requires 1 parameter"
44 
45 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_NAPI, "NAPI_MessageSequence" };
46 
47 #define MAX_BYTES_LENGTH 40960
48 
49 #define CHECK_WRITE_CAPACITY(env, lenToWrite, napiParcel)                                              \
50     do {                                                                                               \
51         size_t cap =  (napiParcel)->maxCapacityToWrite_ - (napiParcel)->nativeParcel_->GetWritePosition(); \
52         if (cap < (lenToWrite)) {                                                                      \
53             ZLOGI(LOG_LABEL, "No enough capacity to write");                                           \
54             napi_throw_range_error(env, nullptr, "No enough capacity to write");                       \
55         }                                                                                              \
56     } while (0)
57 
58 #define REWIND_IF_WRITE_CHECK_FAIL(env, lenToWrite, pos, napiParcel)                                  \
59     do {                                                                                              \
60         size_t cap = (napiParcel)->maxCapacityToWrite_ - (napiParcel)->nativeParcel_->GetWritePosition(); \
61         if (cap < (lenToWrite)) {                                                                     \
62             ZLOGI(LOG_LABEL, "No enough capacity to write");                                          \
63             (napiParcel)->nativeParcel_->RewindWrite(pos);                                              \
64             napi_throw_range_error(env, nullptr, "No enough capacity to write");                      \
65         }                                                                                             \
66     } while (0)
67 
68 #define CHECK_READ_LENGTH(env, arrayLength, typeSize, napiParcel)                                                    \
69     do {                                                                                                             \
70         size_t remainSize = (napiParcel)->nativeParcel_->GetDataSize() -                                             \
71             (napiParcel)->nativeParcel_->GetReadPosition();                                                          \
72         if (((arrayLength) < 0) || ((arrayLength) > remainSize) || (((arrayLength) * (typeSize)) > remainSize)) {    \
73             ZLOGI(LOG_LABEL, "No enough data to read");                                                              \
74             napi_throw_range_error(env, nullptr, "No enough data to read");                                          \
75         }                                                                                                            \
76     } while (0)
77 
NAPI_MessageSequence(napi_env env,napi_value thisVar,MessageParcel * parcel)78 NAPI_MessageSequence::NAPI_MessageSequence(napi_env env, napi_value thisVar, MessageParcel *parcel)
79 {
80     env_ = env;
81     maxCapacityToWrite_ = MAX_CAPACITY_TO_WRITE;
82     // do NOT reference js parcel here
83     if (parcel == nullptr) {
84         nativeParcel_ = std::make_shared<MessageParcel>();
85         owner = true;
86     } else {
87         nativeParcel_ = std::shared_ptr<MessageParcel>(parcel, release);
88         owner = false;
89     }
90 }
91 
~NAPI_MessageSequence()92 NAPI_MessageSequence::~NAPI_MessageSequence()
93 {
94     ZLOGD(LOG_LABEL, "NAPI_MessageSequence::Destructor");
95     nativeParcel_ = nullptr;
96     env_ = nullptr;
97 }
98 
release(MessageParcel * parcel)99 void NAPI_MessageSequence::release(MessageParcel *parcel)
100 {
101     ZLOGD(LOG_LABEL, "message parcel is created by others, do nothing");
102 }
103 
GetMessageParcel()104 std::shared_ptr<MessageParcel> NAPI_MessageSequence::GetMessageParcel()
105 {
106     return nativeParcel_;
107 }
108 
JS_writeByte(napi_env env,napi_callback_info info)109 napi_value NAPI_MessageSequence::JS_writeByte(napi_env env, napi_callback_info info)
110 {
111     size_t argc = 1;
112     napi_value argv[ARGV_LENGTH_1] = {0};
113     napi_value thisVar = nullptr;
114     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
115     if (argc != REQUIRED_ARGS_COUNT_1) {
116         ZLOGE(LOG_LABEL, "requires 1 parameter");
117         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
118     }
119 
120     napi_valuetype valueType = napi_null;
121     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
122     if (valueType != napi_number) {
123         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
124         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
125     }
126 
127     int32_t value = 0;
128     napi_get_value_int32(env, argv[ARGV_INDEX_0], &value);
129 
130     NAPI_MessageSequence *napiSequence = nullptr;
131     napi_unwrap(env, thisVar, (void **)&napiSequence);
132     if (napiSequence == nullptr) {
133         ZLOGE(LOG_LABEL, "napiSequence is null");
134         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
135     }
136     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
137     bool result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
138     if (!result) {
139         ZLOGE(LOG_LABEL, "write int8 failed");
140         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
141     }
142     napi_value napiValue = nullptr;
143     napi_get_undefined(env, &napiValue);
144     return napiValue;
145 }
146 
JS_writeShort(napi_env env,napi_callback_info info)147 napi_value NAPI_MessageSequence::JS_writeShort(napi_env env, napi_callback_info info)
148 {
149     size_t argc = 1;
150     napi_value argv[ARGV_LENGTH_1] = {0};
151     napi_value thisVar = nullptr;
152     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
153     if (argc != REQUIRED_ARGS_COUNT_1) {
154         ZLOGE(LOG_LABEL, "requires 1 parameter");
155         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
156     }
157 
158     napi_valuetype valueType = napi_null;
159     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
160     if (valueType != napi_number) {
161         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
162         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
163     }
164 
165     int32_t value = 0;
166     napi_get_value_int32(env, argv[ARGV_INDEX_0], &value);
167 
168     NAPI_MessageSequence *napiSequence = nullptr;
169     napi_unwrap(env, thisVar, (void **)&napiSequence);
170     if (napiSequence == nullptr) {
171         ZLOGE(LOG_LABEL, "napiSequence is null");
172         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
173     }
174     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
175     bool result = napiSequence->nativeParcel_->WriteInt16(static_cast<int16_t>(value));
176     if (!result) {
177         ZLOGE(LOG_LABEL, "write int16 failed");
178         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
179     }
180     napi_value napiValue = nullptr;
181     napi_get_undefined(env, &napiValue);
182     return napiValue;
183 }
184 
JS_writeInt(napi_env env,napi_callback_info info)185 napi_value NAPI_MessageSequence::JS_writeInt(napi_env env, napi_callback_info info)
186 {
187     size_t argc = 1;
188     napi_value argv[ARGV_LENGTH_1] = {0};
189     napi_value thisVar = nullptr;
190     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
191     if (argc != REQUIRED_ARGS_COUNT_1) {
192         ZLOGE(LOG_LABEL, "requires 1 parameter");
193         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
194     }
195 
196     napi_valuetype valueType = napi_null;
197     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
198     if (valueType != napi_number) {
199         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
200         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
201     }
202 
203     int32_t value = 0;
204     napi_get_value_int32(env, argv[ARGV_INDEX_0], &value);
205 
206     NAPI_MessageSequence *napiSequence = nullptr;
207     napi_unwrap(env, thisVar, (void **)&napiSequence);
208     if (napiSequence == nullptr) {
209         ZLOGE(LOG_LABEL, "napiSequence is null");
210         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
211     }
212     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
213     bool result = napiSequence->nativeParcel_->WriteInt32(value);
214     if (!result) {
215         ZLOGE(LOG_LABEL, "write int32 failed");
216         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
217     }
218     napi_value napiValue = nullptr;
219     napi_get_undefined(env, &napiValue);
220     return napiValue;
221 }
222 
JS_writeLong(napi_env env,napi_callback_info info)223 napi_value NAPI_MessageSequence::JS_writeLong(napi_env env, napi_callback_info info)
224 {
225     size_t argc = 1;
226     napi_value argv[ARGV_LENGTH_1] = {0};
227     napi_value thisVar = nullptr;
228     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
229     if (argc != REQUIRED_ARGS_COUNT_1) {
230         ZLOGE(LOG_LABEL, "requires 1 parameter");
231         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
232     }
233 
234     napi_valuetype valueType = napi_null;
235     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
236     if (valueType != napi_number) {
237         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
238         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
239     }
240 
241     int64_t value = 0;
242     napi_get_value_int64(env, argv[ARGV_INDEX_0], &value);
243 
244     NAPI_MessageSequence *napiSequence = nullptr;
245     napi_unwrap(env, thisVar, (void **)&napiSequence);
246     if (napiSequence == nullptr) {
247         ZLOGE(LOG_LABEL, "napiSequence is null");
248         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
249     }
250     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_64, napiSequence);
251     bool result = napiSequence->nativeParcel_->WriteInt64(value);
252     if (!result) {
253         ZLOGE(LOG_LABEL, "write int64 failed");
254         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
255     }
256     napi_value napiValue = nullptr;
257     napi_get_undefined(env, &napiValue);
258     return napiValue;
259 }
260 
JS_writeFloat(napi_env env,napi_callback_info info)261 napi_value NAPI_MessageSequence::JS_writeFloat(napi_env env, napi_callback_info info)
262 {
263     size_t argc = 1;
264     napi_value argv[ARGV_LENGTH_1] = {0};
265     napi_value thisVar = nullptr;
266     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
267     if (argc != REQUIRED_ARGS_COUNT_1) {
268         ZLOGE(LOG_LABEL, "requires 1 parameter");
269         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
270     }
271 
272     napi_valuetype valueType = napi_null;
273     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
274     if (valueType != napi_number) {
275         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
276         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
277     }
278 
279     double value = 0;
280     napi_get_value_double(env, argv[ARGV_INDEX_0], &value);
281 
282     NAPI_MessageSequence *napiSequence = nullptr;
283     napi_unwrap(env, thisVar, (void **)&napiSequence);
284     if (napiSequence == nullptr) {
285         ZLOGE(LOG_LABEL, "napiSequence is null");
286         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
287     }
288     CHECK_WRITE_CAPACITY(env, sizeof(double), napiSequence);
289     bool result = napiSequence->nativeParcel_->WriteDouble(value);
290     if (!result) {
291         ZLOGE(LOG_LABEL, "write double failed");
292         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
293     }
294     napi_value napiValue = nullptr;
295     napi_get_undefined(env, &napiValue);
296     return napiValue;
297 }
298 
JS_writeDouble(napi_env env,napi_callback_info info)299 napi_value NAPI_MessageSequence::JS_writeDouble(napi_env env, napi_callback_info info)
300 {
301     // This function implementation is the same as JS_writeFloat
302     return NAPI_MessageSequence::JS_writeFloat(env, info);
303 }
304 
JS_writeBoolean(napi_env env,napi_callback_info info)305 napi_value NAPI_MessageSequence::JS_writeBoolean(napi_env env, napi_callback_info info)
306 {
307     size_t argc = 1;
308     napi_value argv[ARGV_LENGTH_1] = {0};
309     napi_value thisVar = nullptr;
310     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
311     if (argc != REQUIRED_ARGS_COUNT_1) {
312         ZLOGE(LOG_LABEL, "requires 1 parameter");
313         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
314     }
315 
316     napi_valuetype valueType = napi_null;
317     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
318     if (valueType != napi_boolean) {
319         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
320         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
321     }
322 
323     bool value = false;
324     napi_get_value_bool(env, argv[ARGV_INDEX_0], &value);
325 
326     NAPI_MessageSequence *napiSequence = nullptr;
327     napi_unwrap(env, thisVar, (void **)&napiSequence);
328     if (napiSequence == nullptr) {
329         ZLOGE(LOG_LABEL, "napiSequence is null");
330         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
331     }
332     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
333     bool result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
334     if (!result) {
335         ZLOGE(LOG_LABEL, "write int8 failed");
336         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
337     }
338     napi_value napiValue = nullptr;
339     napi_get_undefined(env, &napiValue);
340     return napiValue;
341 }
342 
JS_writeChar(napi_env env,napi_callback_info info)343 napi_value NAPI_MessageSequence::JS_writeChar(napi_env env, napi_callback_info info)
344 {
345     size_t argc = 1;
346     napi_value argv[ARGV_LENGTH_1] = {0};
347     napi_value thisVar = nullptr;
348     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
349     if (argc != REQUIRED_ARGS_COUNT_1) {
350         ZLOGE(LOG_LABEL, "requires 1 parameter");
351         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
352     }
353 
354     napi_valuetype valueType = napi_null;
355     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
356     if (valueType != napi_number) {
357         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
358         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
359     }
360 
361     uint32_t value = 0;
362     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
363 
364     NAPI_MessageSequence *napiSequence = nullptr;
365     napi_unwrap(env, thisVar, (void **)&napiSequence);
366     if (napiSequence == nullptr) {
367         ZLOGE(LOG_LABEL, "napiSequence is null");
368         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
369     }
370     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
371     bool result = napiSequence->nativeParcel_->WriteUint8(static_cast<uint8_t>(value));
372     if (!result) {
373         ZLOGE(LOG_LABEL, "write uint8 failed");
374         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
375     }
376     napi_value napiValue = nullptr;
377     napi_get_undefined(env, &napiValue);
378     return napiValue;
379 }
380 
JS_checkWriteByteArrayArgs(napi_env env,size_t argc,napi_value * argv,uint32_t & arrayLength)381 napi_value NAPI_MessageSequence::JS_checkWriteByteArrayArgs(napi_env env,
382                                                             size_t argc,
383                                                             napi_value* argv,
384                                                             uint32_t &arrayLength)
385 {
386     if (argv == nullptr) {
387         ZLOGE(LOG_LABEL, "argv is nullptr");
388         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
389     }
390     if (argc != REQUIRED_ARGS_COUNT_1) {
391         ZLOGE(LOG_LABEL, "requires 1 parameter");
392         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
393     }
394     bool isArray = false;
395     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
396     if (!isArray) {
397         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
398         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
399     }
400     uint32_t maxBytesLen = MAX_BYTES_LENGTH;
401     napi_get_array_length(env, argv[ARGV_INDEX_0], &arrayLength);
402     if (arrayLength >= maxBytesLen) {
403         ZLOGE(LOG_LABEL, "write byte array length too large");
404         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
405     }
406     napi_value result = nullptr;
407     napi_get_undefined(env, &result);
408     return result;
409 }
410 
JS_writeByteArray(napi_env env,napi_callback_info info)411 napi_value NAPI_MessageSequence::JS_writeByteArray(napi_env env, napi_callback_info info)
412 {
413     size_t argc = 1;
414     napi_value argv[ARGV_LENGTH_1] = {0};
415     napi_value thisVar = nullptr;
416     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
417     uint32_t arrayLength = 0;
418     napi_value checkArgsResult = JS_checkWriteByteArrayArgs(env, argc, argv, arrayLength);
419     if (checkArgsResult == nullptr) {
420         ZLOGE(LOG_LABEL, "checkArgsResult is null");
421         return checkArgsResult;
422     }
423 
424     NAPI_MessageSequence *napiSequence = nullptr;
425     napi_unwrap(env, thisVar, (void **)&napiSequence);
426     if (napiSequence == nullptr) {
427         ZLOGE(LOG_LABEL, "napiSequence is null");
428         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
429     }
430 
431     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_8 * (arrayLength + 1), napiSequence);
432     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
433     napiSequence->nativeParcel_->WriteUint32(arrayLength);
434     bool result = false;
435     for (size_t i = 0; i < arrayLength; i++) {
436         bool hasElement = false;
437         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
438         if (!hasElement) {
439             ZLOGE(LOG_LABEL, "parameter check error");
440             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
441         }
442 
443         napi_value element = nullptr;
444         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
445 
446         int32_t value = 0;
447         napi_get_value_int32(env, element, &value);
448         result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
449         if (!result) {
450             napiSequence->nativeParcel_->RewindWrite(pos);
451             ZLOGE(LOG_LABEL, "write int8 failed");
452             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
453         }
454     }
455 
456     napi_value napiValue = nullptr;
457     napi_get_undefined(env, &napiValue);
458     return napiValue;
459 }
460 
JS_checkWriteArrayArgs(napi_env env,size_t argc,napi_value * argv,uint32_t & arrayLength)461 napi_value NAPI_MessageSequence::JS_checkWriteArrayArgs(napi_env env,
462                                                         size_t argc,
463                                                         napi_value* argv,
464                                                         uint32_t &arrayLength)
465 {
466     if (argv == nullptr) {
467         ZLOGE(LOG_LABEL, "argv is nullptr");
468         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
469     }
470     if (argc != REQUIRED_ARGS_COUNT_1) {
471         ZLOGE(LOG_LABEL, "requires 1 parameter");
472         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
473     }
474 
475     bool isArray = false;
476     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
477     if (!isArray) {
478         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
479         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
480     }
481     napi_get_array_length(env, argv[ARGV_INDEX_0], &arrayLength);
482 
483     napi_value napiValue = nullptr;
484     napi_get_undefined(env, &napiValue);
485     return napiValue;
486 }
487 
JS_writeShortArray(napi_env env,napi_callback_info info)488 napi_value NAPI_MessageSequence::JS_writeShortArray(napi_env env, napi_callback_info info)
489 {
490     size_t argc = 1;
491     napi_value argv[ARGV_LENGTH_1] = {0};
492     napi_value thisVar = nullptr;
493     void *data = nullptr;
494     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
495     uint32_t arrayLength = 0;
496     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
497     if (checkArgsResult == nullptr) {
498         ZLOGE(LOG_LABEL, "checkArgsResult is null");
499         return checkArgsResult;
500     }
501 
502     NAPI_MessageSequence *napiSequence = nullptr;
503     napi_unwrap(env, thisVar, (void **)&napiSequence);
504     if (napiSequence == nullptr) {
505         ZLOGE(LOG_LABEL, "napiSequence is null");
506         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
507     }
508 
509     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
510     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
511     napiSequence->nativeParcel_->WriteUint32(arrayLength);
512     bool result = false;
513     for (size_t i = 0; i < arrayLength; i++) {
514         bool hasElement = false;
515         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
516         if (!hasElement) {
517             ZLOGE(LOG_LABEL, "parameter check error");
518             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
519         }
520 
521         napi_value element = nullptr;
522         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
523 
524         int32_t value = 0;
525         napi_get_value_int32(env, element, &value);
526         result = napiSequence->nativeParcel_->WriteInt16(static_cast<int16_t>(value));
527         if (!result) {
528             napiSequence->nativeParcel_->RewindWrite(pos);
529             ZLOGE(LOG_LABEL, "write int16 failed");
530             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
531         }
532     }
533 
534     napi_value napiValue = nullptr;
535     napi_get_undefined(env, &napiValue);
536     return napiValue;
537 }
538 
JS_writeIntArray(napi_env env,napi_callback_info info)539 napi_value NAPI_MessageSequence::JS_writeIntArray(napi_env env, napi_callback_info info)
540 {
541     size_t argc = 1;
542     napi_value argv[ARGV_LENGTH_1] = {0};
543     napi_value thisVar = nullptr;
544     void *data = nullptr;
545     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
546     uint32_t arrayLength = 0;
547     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
548     if (checkArgsResult == nullptr) {
549         ZLOGE(LOG_LABEL, "checkArgsResult is null");
550         return checkArgsResult;
551     }
552 
553     NAPI_MessageSequence *napiSequence = nullptr;
554     napi_unwrap(env, thisVar, (void **)&napiSequence);
555     if (napiSequence == nullptr) {
556         ZLOGE(LOG_LABEL, "napiSequence is null");
557         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
558     }
559 
560     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
561     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
562     napiSequence->nativeParcel_->WriteUint32(arrayLength);
563     bool result = false;
564     for (size_t i = 0; i < arrayLength; i++) {
565         bool hasElement = false;
566         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
567         if (!hasElement) {
568             ZLOGE(LOG_LABEL, "parameter check error");
569             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
570         }
571         napi_value element = nullptr;
572         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
573         napi_valuetype valueType;
574         napi_typeof(env, element, &valueType);
575         if (valueType != napi_number) {
576             ZLOGE(LOG_LABEL, "type mismatch element");
577             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
578         }
579 
580         int32_t value = 0;
581         napi_get_value_int32(env, element, &value);
582         result = napiSequence->nativeParcel_->WriteInt32(value);
583         if (!result) {
584             napiSequence->nativeParcel_->RewindWrite(pos);
585             ZLOGE(LOG_LABEL, "write int32 failed");
586             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
587         }
588     }
589     napi_value napiValue = nullptr;
590     napi_get_undefined(env, &napiValue);
591     return napiValue;
592 }
593 
JS_writeLongArray(napi_env env,napi_callback_info info)594 napi_value NAPI_MessageSequence::JS_writeLongArray(napi_env env, napi_callback_info info)
595 {
596     size_t argc = 1;
597     napi_value argv[ARGV_LENGTH_1] = {0};
598     napi_value thisVar = nullptr;
599     void *data = nullptr;
600     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
601     uint32_t arrayLength = 0;
602     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
603     if (checkArgsResult == nullptr) {
604         ZLOGE(LOG_LABEL, "checkArgsResult is null");
605         return checkArgsResult;
606     }
607     ZLOGI(LOG_LABEL, "messageparcel WriteBuffer typedarrayLength:%{public}d", (int)(arrayLength));
608 
609     NAPI_MessageSequence *napiSequence = nullptr;
610     napi_unwrap(env, thisVar, (void **)&napiSequence);
611     if (napiSequence == nullptr) {
612         ZLOGE(LOG_LABEL, "napiSequence is null");
613         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
614     }
615 
616     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 + BYTE_SIZE_64 * arrayLength, napiSequence);
617     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
618     napiSequence->nativeParcel_->WriteUint32(arrayLength);
619     bool result = false;
620     for (size_t i = 0; i < arrayLength; i++) {
621         bool hasElement = false;
622         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
623         if (!hasElement) {
624             ZLOGE(LOG_LABEL, "parameter check error");
625             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
626         }
627 
628         napi_value element = nullptr;
629         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
630 
631         int64_t value = 0;
632         napi_get_value_int64(env, element, &value);
633 
634         result = napiSequence->nativeParcel_->WriteInt64(value);
635         if (!result) {
636             napiSequence->nativeParcel_->RewindWrite(pos);
637             ZLOGE(LOG_LABEL, "write int64 failed");
638             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
639         }
640     }
641 
642     napi_value napiValue = nullptr;
643     napi_get_undefined(env, &napiValue);
644     return napiValue;
645 }
646 
JS_writeFloatArray(napi_env env,napi_callback_info info)647 napi_value NAPI_MessageSequence::JS_writeFloatArray(napi_env env, napi_callback_info info)
648 {
649     size_t argc = 1;
650     napi_value argv[ARGV_LENGTH_1] = {0};
651     napi_value thisVar = nullptr;
652     void *data = nullptr;
653     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
654     uint32_t arrayLength = 0;
655     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
656     if (checkArgsResult == nullptr) {
657         ZLOGE(LOG_LABEL, "checkArgsResult is null");
658         return checkArgsResult;
659     }
660 
661     NAPI_MessageSequence *napiSequence = nullptr;
662     napi_unwrap(env, thisVar, (void **)&napiSequence);
663     if (napiSequence == nullptr) {
664         ZLOGE(LOG_LABEL, "napiSequence is null");
665         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
666     }
667 
668     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 + sizeof(double) * arrayLength, napiSequence);
669     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
670     napiSequence->nativeParcel_->WriteUint32(arrayLength);
671     bool result = false;
672     for (size_t i = 0; i < arrayLength; i++) {
673         bool hasElement = false;
674         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
675         if (!hasElement) {
676             ZLOGE(LOG_LABEL, "parameter check error");
677             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
678         }
679 
680         napi_value element = nullptr;
681         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
682 
683         double value = 0;
684         napi_get_value_double(env, element, &value);
685 
686         result = napiSequence->nativeParcel_->WriteDouble(value);
687         if (!result) {
688             napiSequence->nativeParcel_->RewindWrite(pos);
689             ZLOGE(LOG_LABEL, "write double failed");
690             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
691         }
692     }
693 
694     napi_value napiValue = nullptr;
695     napi_get_undefined(env, &napiValue);
696     return napiValue;
697 }
698 
JS_writeDoubleArray(napi_env env,napi_callback_info info)699 napi_value NAPI_MessageSequence::JS_writeDoubleArray(napi_env env, napi_callback_info info)
700 {
701     size_t argc = 1;
702     napi_value argv[ARGV_LENGTH_1] = {0};
703     napi_value thisVar = nullptr;
704     void *data = nullptr;
705     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
706     uint32_t arrayLength = 0;
707     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
708     if (checkArgsResult == nullptr) {
709         ZLOGE(LOG_LABEL, "checkArgsResult is null");
710         return checkArgsResult;
711     }
712 
713     NAPI_MessageSequence *napiSequence = nullptr;
714     napi_unwrap(env, thisVar, (void **)&napiSequence);
715     if (napiSequence == nullptr) {
716         ZLOGE(LOG_LABEL, "napiSequence is null");
717         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
718     }
719 
720     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 + sizeof(double) * arrayLength, napiSequence);
721     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
722     napiSequence->nativeParcel_->WriteUint32(arrayLength);
723     bool result = false;
724     for (size_t i = 0; i < arrayLength; i++) {
725         bool hasElement = false;
726         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
727         if (!hasElement) {
728             ZLOGE(LOG_LABEL, "parameter check error");
729             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
730         }
731 
732         napi_value element = nullptr;
733         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
734 
735         double value = 0;
736         napi_get_value_double(env, element, &value);
737 
738         result = napiSequence->nativeParcel_->WriteDouble(value);
739         if (!result) {
740             napiSequence->nativeParcel_->RewindWrite(pos);
741             ZLOGE(LOG_LABEL, "write double failed");
742             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
743         }
744     }
745 
746     napi_value napiValue = nullptr;
747     napi_get_undefined(env, &napiValue);
748     return napiValue;
749 }
750 
JS_writeBooleanArray(napi_env env,napi_callback_info info)751 napi_value NAPI_MessageSequence::JS_writeBooleanArray(napi_env env, napi_callback_info info)
752 {
753     size_t argc = 1;
754     napi_value argv[ARGV_LENGTH_1] = {0};
755     napi_value thisVar = nullptr;
756     void *data = nullptr;
757     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
758     uint32_t arrayLength = 0;
759     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
760     if (checkArgsResult == nullptr) {
761         ZLOGE(LOG_LABEL, "checkArgsResult is null");
762         return checkArgsResult;
763     }
764 
765     NAPI_MessageSequence *napiSequence = nullptr;
766     napi_unwrap(env, thisVar, (void **)&napiSequence);
767     if (napiSequence == nullptr) {
768         ZLOGE(LOG_LABEL, "napiSequence is null");
769         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
770     }
771 
772     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
773     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
774     napiSequence->nativeParcel_->WriteUint32(arrayLength);
775     bool result = false;
776     for (size_t i = 0; i < arrayLength; i++) {
777         bool hasElement = false;
778         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
779         if (!hasElement) {
780             ZLOGE(LOG_LABEL, "parameter check error");
781             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
782         }
783 
784         napi_value element = nullptr;
785         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
786 
787         bool value = false;
788         napi_get_value_bool(env, element, &value);
789 
790         result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
791         if (!result) {
792             napiSequence->nativeParcel_->RewindWrite(pos);
793             ZLOGE(LOG_LABEL, "write int8 failed");
794             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
795         }
796     }
797 
798     napi_value napiValue = nullptr;
799     napi_get_undefined(env, &napiValue);
800     return napiValue;
801 }
802 
JS_writeCharArray(napi_env env,napi_callback_info info)803 napi_value NAPI_MessageSequence::JS_writeCharArray(napi_env env, napi_callback_info info)
804 {
805     size_t argc = 1;
806     napi_value argv[ARGV_LENGTH_1] = {0};
807     napi_value thisVar = nullptr;
808     void *data = nullptr;
809     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
810     uint32_t arrayLength = 0;
811     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
812     if (checkArgsResult == nullptr) {
813         ZLOGE(LOG_LABEL, "checkArgsResult is null");
814         return checkArgsResult;
815     }
816 
817     NAPI_MessageSequence *napiSequence = nullptr;
818     napi_unwrap(env, thisVar, (void **)&napiSequence);
819     if (napiSequence == nullptr) {
820         ZLOGE(LOG_LABEL, "napiSequence is null");
821         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
822     }
823 
824     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
825     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
826     napiSequence->nativeParcel_->WriteUint32(arrayLength);
827     bool result = false;
828     for (size_t i = 0; i < arrayLength; i++) {
829         bool hasElement = false;
830         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
831         if (!hasElement) {
832             ZLOGE(LOG_LABEL, "parameter check error");
833             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
834         }
835 
836         napi_value element = nullptr;
837         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
838         uint32_t value = 0;
839         napi_get_value_uint32(env, element, &value);
840 
841         result = napiSequence->nativeParcel_->WriteUint8(static_cast<uint8_t>(value));
842         if (!result) {
843             napiSequence->nativeParcel_->RewindWrite(pos);
844             ZLOGE(LOG_LABEL, "write uint8 failed");
845             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
846         }
847     }
848 
849     napi_value napiValue = nullptr;
850     napi_get_undefined(env, &napiValue);
851     return napiValue;
852 }
853 
JS_writeString(napi_env env,napi_callback_info info)854 napi_value NAPI_MessageSequence::JS_writeString(napi_env env, napi_callback_info info)
855 {
856     size_t argc = 1;
857     napi_value argv[ARGV_LENGTH_1] = {0};
858     napi_value thisVar = nullptr;
859     void *data = nullptr;
860     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
861     if (argc != 1) {
862         ZLOGE(LOG_LABEL, "requires 1 parameters");
863         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
864     }
865     napi_valuetype valueType = napi_null;
866     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
867     if (valueType != napi_string) {
868         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
869         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
870     }
871     size_t bufferSize = 0;
872     size_t maxLen = MAX_BYTES_LENGTH;
873     napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
874     if (bufferSize >= maxLen) {
875         ZLOGE(LOG_LABEL, "string length too large");
876         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
877     }
878     char stringValue[bufferSize + 1];
879     size_t jsStringLength = 0;
880     napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
881     if (jsStringLength != bufferSize) {
882         ZLOGE(LOG_LABEL, "string length wrong");
883         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
884     }
885 
886     NAPI_MessageSequence *napiSequence = nullptr;
887     napi_unwrap(env, thisVar, (void **)&napiSequence);
888     if (napiSequence == nullptr) {
889         ZLOGE(LOG_LABEL, "napiSequence is null");
890         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
891     }
892 
893     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * bufferSize, napiSequence);
894     std::string parcelString = stringValue;
895     bool result = napiSequence->nativeParcel_->WriteString16(to_utf16(parcelString));
896     if (!result) {
897         ZLOGE(LOG_LABEL, "write string16 failed");
898         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
899     }
900     napi_value napiValue = nullptr;
901     napi_get_undefined(env, &napiValue);
902     return napiValue;
903 }
904 
JS_checkWriteStringArrayElement(napi_env env,napi_value * argv,size_t & index,size_t & bufferSize,napi_value & element)905 napi_value NAPI_MessageSequence::JS_checkWriteStringArrayElement(napi_env env,
906                                                                  napi_value* argv,
907                                                                  size_t &index,
908                                                                  size_t &bufferSize,
909                                                                  napi_value &element)
910 {
911     if (argv == nullptr) {
912         ZLOGE(LOG_LABEL, "argv is nullptr");
913         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
914     }
915     bool hasElement = false;
916     size_t maxSize = MAX_BYTES_LENGTH;
917     napi_has_element(env, argv[ARGV_INDEX_0], index, &hasElement);
918     if (!hasElement) {
919         ZLOGE(LOG_LABEL, "parameter check error");
920         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
921     }
922 
923     napi_get_element(env, argv[ARGV_INDEX_0], index, &element);
924     napi_valuetype valuetype;
925     napi_typeof(env, element, &valuetype);
926     if (valuetype != napi_string) {
927         ZLOGE(LOG_LABEL, "Parameter type error");
928         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
929     }
930 
931     napi_get_value_string_utf8(env, element, nullptr, 0, &bufferSize);
932     if (bufferSize >= maxSize) {
933         ZLOGE(LOG_LABEL, "string length too large");
934         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
935     }
936     napi_value napiValue = nullptr;
937     napi_get_undefined(env, &napiValue);
938     return napiValue;
939 }
940 
JS_writeStringArray(napi_env env,napi_callback_info info)941 napi_value NAPI_MessageSequence::JS_writeStringArray(napi_env env, napi_callback_info info)
942 {
943     size_t argc = 1;
944     napi_value argv[ARGV_LENGTH_1] = {0};
945     napi_value thisVar = nullptr;
946     void *data = nullptr;
947     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
948     uint32_t arrayLength = 0;
949     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
950     if (checkArgsResult == nullptr) {
951         ZLOGE(LOG_LABEL, "checkArgsResult is null");
952         return checkArgsResult;
953     }
954 
955     NAPI_MessageSequence *napiSequence = nullptr;
956     napi_unwrap(env, thisVar, (void **)&napiSequence);
957     if (napiSequence == nullptr) {
958         ZLOGE(LOG_LABEL, "napiSequence is null");
959         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
960     }
961 
962     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
963     napiSequence->nativeParcel_->WriteUint32(arrayLength);
964     bool result = false;
965     for (size_t i = 0; i < arrayLength; i++) {
966         size_t bufferSize = 0;
967         napi_value element = nullptr;
968         napi_value checkElementResult = JS_checkWriteStringArrayElement(env, argv, i, bufferSize, element);
969         if (checkElementResult == nullptr) {
970             return checkElementResult;
971         }
972         char stringValue[bufferSize + 1];
973         size_t jsStringLength = 0;
974         napi_get_value_string_utf8(env, element, stringValue, bufferSize + 1, &jsStringLength);
975         if (jsStringLength != bufferSize) {
976             ZLOGE(LOG_LABEL, "string length wrong");
977             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
978         }
979 
980         REWIND_IF_WRITE_CHECK_FAIL(env, BYTE_SIZE_32 * bufferSize, pos, napiSequence);
981         std::string parcelString = stringValue;
982         result = napiSequence->nativeParcel_->WriteString16(to_utf16(parcelString));
983         if (!result) {
984             napiSequence->nativeParcel_->RewindWrite(pos);
985             ZLOGE(LOG_LABEL, "write string16 failed");
986             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
987         }
988     }
989 
990     napi_value napiValue = nullptr;
991     napi_get_undefined(env, &napiValue);
992     return napiValue;
993 }
994 
JS_writeParcelable(napi_env env,napi_callback_info info)995 napi_value NAPI_MessageSequence::JS_writeParcelable(napi_env env, napi_callback_info info)
996 {
997     napi_value result = nullptr;
998     napi_get_undefined(env, &result);
999 
1000     size_t argc = 1;
1001     napi_value argv[ARGV_LENGTH_1] = {0};
1002     napi_value thisVar = nullptr;
1003     void *data = nullptr;
1004     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1005     if (argc != 1) {
1006         ZLOGE(LOG_LABEL, "requires 1 parameters");
1007         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1008     }
1009 
1010     NAPI_MessageSequence *napiSequence = nullptr;
1011     napi_unwrap(env, thisVar, (void **)&napiSequence);
1012     if (napiSequence == nullptr) {
1013         ZLOGE(LOG_LABEL, "napiSequence is null");
1014         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1015     }
1016 
1017     napi_valuetype valueType = napi_null;
1018     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1019     if (valueType == napi_null || valueType == napi_undefined) {
1020         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1021         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1022     }
1023     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1024     napiSequence->nativeParcel_->WriteInt32(1);
1025     napi_value propKey = nullptr;
1026     const char *propKeyStr = "marshalling";
1027     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
1028     napi_value prop = nullptr;
1029     napi_get_property(env, argv[ARGV_INDEX_0], propKey, &prop);
1030 
1031     napi_value funcArg[1] = { thisVar };
1032     napi_value callResult = nullptr;
1033     napi_call_function(env, argv[ARGV_INDEX_0], prop, 1, funcArg, &callResult);
1034     bool isPendingException = false;
1035     napi_is_exception_pending(env, &isPendingException);
1036     if (isPendingException) {
1037         napi_value lastException = nullptr;
1038         ZLOGE(LOG_LABEL, "call mashalling failed");
1039         napi_get_and_clear_last_exception(env, &lastException);
1040         napiSequence->nativeParcel_->RewindWrite(pos);
1041         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1042     }
1043     napi_typeof(env, callResult, &valueType);
1044     if (callResult != nullptr && valueType != napi_undefined) {
1045         return callResult;
1046     }
1047     ZLOGE(LOG_LABEL, "call mashalling failed");
1048     napiSequence->nativeParcel_->RewindWrite(pos);
1049     return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1050 }
1051 
JS_writeParcelableArrayCallJsFunc(napi_env env,napi_value & element,napi_value & thisVar)1052 napi_value NAPI_MessageSequence::JS_writeParcelableArrayCallJsFunc(napi_env env,
1053     napi_value &element, napi_value &thisVar)
1054 {
1055     napi_value propKey = nullptr;
1056     const char *propKeyStr = "marshalling";
1057     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
1058     napi_value prop = nullptr;
1059     napi_get_property(env, element, propKey, &prop);
1060 
1061     napi_value funcArg[1] = { thisVar };
1062     napi_value callResult = nullptr;
1063     napi_call_function(env, element, prop, 1, funcArg, &callResult);
1064     napi_valuetype valueType = napi_null;
1065     napi_typeof(env, callResult, &valueType);
1066     if (callResult == nullptr || valueType == napi_undefined) {
1067         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1068     }
1069 
1070     napi_value retValue = nullptr;
1071     napi_get_undefined(env, &retValue);
1072     return retValue;
1073 }
1074 
JS_writeParcelableArray(napi_env env,napi_callback_info info)1075 napi_value NAPI_MessageSequence::JS_writeParcelableArray(napi_env env, napi_callback_info info)
1076 {
1077     size_t argc = 1;
1078     napi_value argv[ARGV_LENGTH_1] = {0};
1079     napi_value thisVar = nullptr;
1080     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1081     uint32_t arrayLength = 0;
1082     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
1083     if (checkArgsResult == nullptr) {
1084         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1085         return checkArgsResult;
1086     }
1087 
1088     NAPI_MessageSequence *napiSequence = nullptr;
1089     napi_unwrap(env, thisVar, (void **)&napiSequence);
1090     if (napiSequence == nullptr) {
1091         ZLOGE(LOG_LABEL, "napiSequence is null");
1092         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1093     }
1094 
1095     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1096     bool result = napiSequence->nativeParcel_->WriteUint32(arrayLength);
1097     if (!result) {
1098         ZLOGE(LOG_LABEL, "write uint32 failed");
1099         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1100     }
1101     for (size_t i = 0; i < arrayLength; i++) {
1102         bool hasElement = false;
1103         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
1104         if (!hasElement) {
1105             ZLOGE(LOG_LABEL, "parameter check error");
1106             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1107         }
1108 
1109         napi_value element = nullptr;
1110         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
1111         napi_valuetype valueType = napi_null;
1112         napi_typeof(env, element, &valueType);
1113         if (valueType == napi_null || valueType == napi_undefined) {
1114             napiSequence->nativeParcel_->WriteInt32(0);
1115             continue;
1116         } else {
1117             napiSequence->nativeParcel_->WriteInt32(1);
1118         }
1119         napi_value callResult = JS_writeParcelableArrayCallJsFunc(env, element, thisVar);
1120         if (callResult == nullptr) {
1121             ZLOGE(LOG_LABEL, "call mashalling failed, element index:%{public}zu", i);
1122             napiSequence->nativeParcel_->RewindWrite(pos);
1123             return callResult;
1124         }
1125     }
1126     napi_value retValue = nullptr;
1127     napi_get_undefined(env, &retValue);
1128     return retValue;
1129 }
1130 
JS_writeRemoteObjectArray(napi_env env,napi_callback_info info)1131 napi_value NAPI_MessageSequence::JS_writeRemoteObjectArray(napi_env env, napi_callback_info info)
1132 {
1133     size_t argc = 1;
1134     napi_value argv[ARGV_LENGTH_1] = {0};
1135     napi_value thisVar = nullptr;
1136     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1137     uint32_t arrayLength = 0;
1138     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
1139     if (checkArgsResult == nullptr) {
1140         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1141         return checkArgsResult;
1142     }
1143 
1144     NAPI_MessageSequence *napiSequence = nullptr;
1145     napi_unwrap(env, thisVar, (void **)&napiSequence);
1146     if (napiSequence == nullptr) {
1147         ZLOGE(LOG_LABEL, "napiSequence is null");
1148         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1149     }
1150     napi_valuetype valueType = napi_null;
1151     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1152     if (valueType == napi_null || valueType == napi_undefined) {
1153         napiSequence->nativeParcel_->WriteInt32(-1);
1154         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1155         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1156     }
1157     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1158     bool result =  napiSequence->nativeParcel_->WriteInt32(arrayLength);
1159     for (size_t i = 0; i < arrayLength; i++) {
1160         bool hasElement = false;
1161         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
1162         if (!hasElement) {
1163             ZLOGE(LOG_LABEL, "parameter check error");
1164             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1165         }
1166         napi_value element = nullptr;
1167         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
1168         sptr<IRemoteObject> remoteObject = NAPI_ohos_rpc_getNativeRemoteObject(env, element);
1169         if (remoteObject == nullptr) {
1170             ZLOGE(LOG_LABEL, "parameter check error");
1171             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1172         }
1173         result = napiSequence->nativeParcel_->WriteRemoteObject(remoteObject);
1174         if (!result) {
1175             napiSequence->nativeParcel_->RewindWrite(pos);
1176             ZLOGE(LOG_LABEL, "write string16 failed");
1177             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1178         }
1179     }
1180     napi_value retValue = nullptr;
1181     napi_get_undefined(env, &retValue);
1182     return retValue;
1183 }
1184 
JS_readByte(napi_env env,napi_callback_info info)1185 napi_value NAPI_MessageSequence::JS_readByte(napi_env env, napi_callback_info info)
1186 {
1187     size_t argc = 0;
1188     napi_value thisVar = nullptr;
1189     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1190     NAPI_MessageSequence *napiSequence = nullptr;
1191     napi_unwrap(env, thisVar, (void **)&napiSequence);
1192     if (napiSequence == nullptr) {
1193         ZLOGE(LOG_LABEL, "napiSequence is null");
1194         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1195     }
1196 
1197     int8_t value = napiSequence->nativeParcel_->ReadInt8();
1198     napi_value napiValue = nullptr;
1199     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
1200     return napiValue;
1201 }
1202 
JS_readShort(napi_env env,napi_callback_info info)1203 napi_value NAPI_MessageSequence::JS_readShort(napi_env env, napi_callback_info info)
1204 {
1205     size_t argc = 0;
1206     napi_value thisVar = nullptr;
1207     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1208     NAPI_MessageSequence *napiSequence = nullptr;
1209     napi_unwrap(env, thisVar, (void **)&napiSequence);
1210     if (napiSequence == nullptr) {
1211         ZLOGE(LOG_LABEL, "napiSequence is null");
1212         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1213     }
1214 
1215     int16_t value = napiSequence->nativeParcel_->ReadInt16();
1216     napi_value napiValue = nullptr;
1217     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
1218     return napiValue;
1219 }
1220 
JS_readInt(napi_env env,napi_callback_info info)1221 napi_value NAPI_MessageSequence::JS_readInt(napi_env env, napi_callback_info info)
1222 {
1223     size_t argc = 0;
1224     napi_value thisVar = nullptr;
1225     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1226     NAPI_MessageSequence *napiSequence = nullptr;
1227     napi_unwrap(env, thisVar, (void **)&napiSequence);
1228     if (napiSequence == nullptr) {
1229         ZLOGE(LOG_LABEL, "napiSequence is null");
1230         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1231     }
1232 
1233     int32_t value = napiSequence->nativeParcel_->ReadInt32();
1234     napi_value napiValue = nullptr;
1235     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
1236     return napiValue;
1237 }
1238 
JS_readLong(napi_env env,napi_callback_info info)1239 napi_value NAPI_MessageSequence::JS_readLong(napi_env env, napi_callback_info info)
1240 {
1241     size_t argc = 0;
1242     napi_value thisVar = nullptr;
1243     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1244     NAPI_MessageSequence *napiSequence = nullptr;
1245     napi_unwrap(env, thisVar, (void **)&napiSequence);
1246     if (napiSequence == nullptr) {
1247         ZLOGE(LOG_LABEL, "napiSequence is null");
1248         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1249     }
1250 
1251     int64_t value = napiSequence->nativeParcel_->ReadInt64();
1252     napi_value napiValue = nullptr;
1253     NAPI_CALL(env, napi_create_int64(env, value, &napiValue));
1254     return napiValue;
1255 }
1256 
JS_readFloat(napi_env env,napi_callback_info info)1257 napi_value NAPI_MessageSequence::JS_readFloat(napi_env env, napi_callback_info info)
1258 {
1259     size_t argc = 0;
1260     napi_value thisVar = nullptr;
1261     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1262     NAPI_MessageSequence *napiSequence = nullptr;
1263     napi_unwrap(env, thisVar, (void **)&napiSequence);
1264     if (napiSequence == nullptr) {
1265         ZLOGE(LOG_LABEL, "napiSequence is null");
1266         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1267     }
1268 
1269     double value = napiSequence->nativeParcel_->ReadDouble();
1270     napi_value napiValue = nullptr;
1271     NAPI_CALL(env, napi_create_double(env, value, &napiValue));
1272     return napiValue;
1273 }
1274 
JS_readDouble(napi_env env,napi_callback_info info)1275 napi_value NAPI_MessageSequence::JS_readDouble(napi_env env, napi_callback_info info)
1276 {
1277     // This function implementation is the same as JS_readFloat
1278     return NAPI_MessageSequence::JS_readFloat(env, info);
1279 }
1280 
JS_readBoolean(napi_env env,napi_callback_info info)1281 napi_value NAPI_MessageSequence::JS_readBoolean(napi_env env, napi_callback_info info)
1282 {
1283     size_t argc = 0;
1284     napi_value thisVar = nullptr;
1285     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1286     NAPI_MessageSequence *napiSequence = nullptr;
1287     napi_unwrap(env, thisVar, (void **)&napiSequence);
1288     if (napiSequence == nullptr) {
1289         ZLOGE(LOG_LABEL, "napiSequence is null");
1290         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1291     }
1292 
1293     int8_t value = napiSequence->nativeParcel_->ReadInt8();
1294     napi_value napiValue = nullptr;
1295     NAPI_CALL(env, napi_get_boolean(env, value, &napiValue));
1296     return napiValue;
1297 }
1298 
JS_readChar(napi_env env,napi_callback_info info)1299 napi_value NAPI_MessageSequence::JS_readChar(napi_env env, napi_callback_info info)
1300 {
1301     size_t argc = 0;
1302     napi_value thisVar = nullptr;
1303     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1304     NAPI_MessageSequence *napiSequence = nullptr;
1305     napi_unwrap(env, thisVar, (void **)&napiSequence);
1306     if (napiSequence == nullptr) {
1307         ZLOGE(LOG_LABEL, "napiSequence is null");
1308         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1309     }
1310 
1311     uint8_t value = napiSequence->nativeParcel_->ReadUint8();
1312     napi_value result = nullptr;
1313     napi_create_uint32(env, static_cast<uint32_t>(value), &result);
1314     return result;
1315 }
1316 
JS_readString(napi_env env,napi_callback_info info)1317 napi_value NAPI_MessageSequence::JS_readString(napi_env env, napi_callback_info info)
1318 {
1319     size_t argc = 0;
1320     napi_value thisVar = nullptr;
1321     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1322     NAPI_MessageSequence *napiSequence = nullptr;
1323     napi_unwrap(env, thisVar, (void **)&napiSequence);
1324     if (napiSequence == nullptr) {
1325         ZLOGE(LOG_LABEL, "napiSequence is null");
1326         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1327     }
1328 
1329     std::u16string parcelString = napiSequence->nativeParcel_->ReadString16();
1330     std::string outString = Str16ToStr8(parcelString.c_str());
1331     napi_value napiValue = nullptr;
1332     napi_create_string_utf8(env, outString.c_str(), outString.length(), &napiValue);
1333     return napiValue;
1334 }
1335 
JS_getSize(napi_env env,napi_callback_info info)1336 napi_value NAPI_MessageSequence::JS_getSize(napi_env env, napi_callback_info info)
1337 {
1338     size_t argc = 0;
1339     napi_value thisVar = nullptr;
1340     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1341 
1342     NAPI_MessageSequence *napiSequence = nullptr;
1343     napi_unwrap(env, thisVar, (void **)&napiSequence);
1344     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1345 
1346     size_t value = napiSequence->nativeParcel_->GetDataSize();
1347     napi_value napiValue = nullptr;
1348     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
1349     return napiValue;
1350 }
1351 
JS_getCapacity(napi_env env,napi_callback_info info)1352 napi_value NAPI_MessageSequence::JS_getCapacity(napi_env env, napi_callback_info info)
1353 {
1354     size_t argc = 0;
1355     napi_value thisVar = nullptr;
1356     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1357 
1358     NAPI_MessageSequence *napiSequence = nullptr;
1359     napi_unwrap(env, thisVar, (void **)&napiSequence);
1360     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1361 
1362     size_t value = napiSequence->nativeParcel_->GetDataCapacity();
1363     napi_value napiValue = nullptr;
1364     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
1365     return napiValue;
1366 }
1367 
JS_setSize(napi_env env,napi_callback_info info)1368 napi_value NAPI_MessageSequence::JS_setSize(napi_env env, napi_callback_info info)
1369 {
1370     size_t argc = 1;
1371     napi_value argv[ARGV_LENGTH_1] = {0};
1372     napi_value thisVar = nullptr;
1373     void *data = nullptr;
1374     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1375     if (argc != REQUIRED_ARGS_COUNT_1) {
1376         ZLOGE(LOG_LABEL, "requires 1 parameter");
1377         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1378     }
1379 
1380     napi_valuetype valueType = napi_null;
1381     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1382     if (valueType != napi_number) {
1383         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1384         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1385     }
1386 
1387     uint32_t value = 0;
1388     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
1389 
1390     NAPI_MessageSequence *napiSequence = nullptr;
1391     napi_unwrap(env, thisVar, (void **)&napiSequence);
1392     if (napiSequence == nullptr) {
1393         ZLOGE(LOG_LABEL, "napiSequence is null");
1394         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1395     }
1396 
1397     bool result = napiSequence->nativeParcel_->SetDataSize(static_cast<size_t>(value));
1398     if (!result) {
1399         ZLOGE(LOG_LABEL, "set data size failed");
1400     }
1401     napi_value napiValue = nullptr;
1402     napi_get_undefined(env, &napiValue);
1403     return napiValue;
1404 }
1405 
JS_setCapacity(napi_env env,napi_callback_info info)1406 napi_value NAPI_MessageSequence::JS_setCapacity(napi_env env, napi_callback_info info)
1407 {
1408     size_t argc = 1;
1409     napi_value argv[ARGV_LENGTH_1] = {0};
1410     napi_value thisVar = nullptr;
1411     void *data = nullptr;
1412     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1413     if (argc != REQUIRED_ARGS_COUNT_1) {
1414         ZLOGE(LOG_LABEL, "requires 1 parameter");
1415         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1416     }
1417 
1418     napi_valuetype valueType = napi_null;
1419     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1420     if (valueType != napi_number) {
1421         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1422         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1423     }
1424 
1425     uint32_t value = 0;
1426     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
1427 
1428     NAPI_MessageSequence *napiSequence = nullptr;
1429     napi_unwrap(env, thisVar, (void **)&napiSequence);
1430     if (napiSequence == nullptr) {
1431         ZLOGE(LOG_LABEL, "napiSequence is null");
1432         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1433     }
1434 
1435     bool result = napiSequence->nativeParcel_->SetDataCapacity(static_cast<size_t>(value));
1436     if (result) {
1437         napiSequence->maxCapacityToWrite_ = value;
1438     } else {
1439         ZLOGE(LOG_LABEL, "set data capacity failed");
1440         return napiErr.ThrowError(env, errorDesc::PARCEL_MEMORY_ALLOC_ERROR);
1441     }
1442     napi_value napiValue = nullptr;
1443     napi_get_undefined(env, &napiValue);
1444     return napiValue;
1445 }
1446 
JS_getWritableBytes(napi_env env,napi_callback_info info)1447 napi_value NAPI_MessageSequence::JS_getWritableBytes(napi_env env, napi_callback_info info)
1448 {
1449     size_t argc = 0;
1450     napi_value thisVar = nullptr;
1451     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1452 
1453     NAPI_MessageSequence *napiSequence = nullptr;
1454     napi_unwrap(env, thisVar, (void **)&napiSequence);
1455     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1456 
1457     size_t value = napiSequence->nativeParcel_->GetWritableBytes();
1458     napi_value napiValue = nullptr;
1459     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
1460     return napiValue;
1461 }
1462 
JS_getReadableBytes(napi_env env,napi_callback_info info)1463 napi_value NAPI_MessageSequence::JS_getReadableBytes(napi_env env, napi_callback_info info)
1464 {
1465     size_t argc = 0;
1466     napi_value thisVar = nullptr;
1467     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1468 
1469     NAPI_MessageSequence *napiSequence = nullptr;
1470     napi_unwrap(env, thisVar, (void **)&napiSequence);
1471     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1472 
1473     size_t value = napiSequence->nativeParcel_->GetReadableBytes();
1474     napi_value napiValue = nullptr;
1475     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
1476     return napiValue;
1477 }
1478 
JS_getReadPosition(napi_env env,napi_callback_info info)1479 napi_value NAPI_MessageSequence::JS_getReadPosition(napi_env env, napi_callback_info info)
1480 {
1481     size_t argc = 0;
1482     napi_value thisVar = nullptr;
1483     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1484 
1485     NAPI_MessageSequence *napiSequence = nullptr;
1486     napi_unwrap(env, thisVar, (void **)&napiSequence);
1487     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1488 
1489     size_t value = napiSequence->nativeParcel_->GetReadPosition();
1490     napi_value napiValue = nullptr;
1491     NAPI_CALL(env, napi_create_uint32(env, value, &napiValue));
1492     return napiValue;
1493 }
1494 
JS_rewindRead(napi_env env,napi_callback_info info)1495 napi_value NAPI_MessageSequence::JS_rewindRead(napi_env env, napi_callback_info info)
1496 {
1497     size_t argc = 1;
1498     napi_value argv[ARGV_LENGTH_1] = {0};
1499     napi_value thisVar = nullptr;
1500     void *data = nullptr;
1501     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1502     if (argc != 1) {
1503         ZLOGE(LOG_LABEL, "requires 1 parameters");
1504         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1505     }
1506 
1507     napi_valuetype valueType = napi_null;
1508     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1509     if (valueType != napi_number) {
1510         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1511         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1512     }
1513 
1514     uint32_t pos = 0;
1515     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &pos);
1516 
1517     NAPI_MessageSequence *napiSequence = nullptr;
1518     napi_unwrap(env, thisVar, (void **)&napiSequence);
1519     if (napiSequence == nullptr) {
1520         ZLOGE(LOG_LABEL, "napiSequence is null");
1521         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1522     }
1523 
1524     bool result = napiSequence->nativeParcel_->RewindRead(static_cast<size_t>(pos));
1525     NAPI_ASSERT(env, result == true, "rewind read failed");
1526     napi_value napiValue = nullptr;
1527     napi_get_undefined(env, &napiValue);
1528     return napiValue;
1529 }
1530 
JS_getWritePosition(napi_env env,napi_callback_info info)1531 napi_value NAPI_MessageSequence::JS_getWritePosition(napi_env env, napi_callback_info info)
1532 {
1533     size_t argc = 0;
1534     napi_value thisVar = nullptr;
1535     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1536 
1537     NAPI_MessageSequence *napiSequence = nullptr;
1538     napi_unwrap(env, thisVar, (void **)&napiSequence);
1539     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1540 
1541     size_t value = napiSequence->nativeParcel_->GetWritePosition();
1542     napi_value napiValue = nullptr;
1543     NAPI_CALL(env, napi_create_uint32(env, value, &napiValue));
1544     return napiValue;
1545 }
1546 
JS_rewindWrite(napi_env env,napi_callback_info info)1547 napi_value NAPI_MessageSequence::JS_rewindWrite(napi_env env, napi_callback_info info)
1548 {
1549     size_t argc = 1;
1550     napi_value argv[ARGV_LENGTH_1] = {0};
1551     napi_value thisVar = nullptr;
1552     void *data = nullptr;
1553     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1554     if (argc != 1) {
1555         ZLOGE(LOG_LABEL, "requires 1 parameters");
1556         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1557     }
1558 
1559     napi_valuetype valueType = napi_null;
1560     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1561     if (valueType != napi_number) {
1562         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1563         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1564     }
1565 
1566     uint32_t pos = 0;
1567     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &pos);
1568 
1569     NAPI_MessageSequence *napiSequence = nullptr;
1570     napi_unwrap(env, thisVar, (void **)&napiSequence);
1571     if (napiSequence == nullptr) {
1572         ZLOGE(LOG_LABEL, "napiSequence is null");
1573         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1574     }
1575 
1576     bool result = napiSequence->nativeParcel_->RewindWrite(static_cast<size_t>(pos));
1577     NAPI_ASSERT(env, result == true, "rewind write failed");
1578     napi_value napiValue = nullptr;
1579     napi_get_undefined(env, &napiValue);
1580     return napiValue;
1581 }
1582 
JS_writeNoException(napi_env env,napi_callback_info info)1583 napi_value NAPI_MessageSequence::JS_writeNoException(napi_env env, napi_callback_info info)
1584 {
1585     napi_value thisVar = nullptr;
1586     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1587     NAPI_MessageSequence *napiSequence = nullptr;
1588     napi_unwrap(env, thisVar, (void **)&napiSequence);
1589     if (napiSequence == nullptr) {
1590         ZLOGE(LOG_LABEL, "napiSequence is null");
1591         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1592     }
1593     bool writeResult = napiSequence->nativeParcel_->WriteInt32(0);
1594     if (writeResult == false) {
1595         ZLOGE(LOG_LABEL, "write int32 failed");
1596         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1597     }
1598     napi_value result = nullptr;
1599     napi_get_undefined(env, &result);
1600     return result;
1601 }
1602 
JS_readException(napi_env env,napi_callback_info info)1603 napi_value NAPI_MessageSequence::JS_readException(napi_env env, napi_callback_info info)
1604 {
1605     napi_value result = nullptr;
1606     napi_get_undefined(env, &result);
1607     napi_value thisVar = nullptr;
1608     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1609     NAPI_MessageSequence *napiSequence = nullptr;
1610     napi_unwrap(env, thisVar, (void **)&napiSequence);
1611     if (napiSequence == nullptr) {
1612         ZLOGE(LOG_LABEL, "napiSequence is null");
1613         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1614     }
1615 
1616     int32_t code = napiSequence->nativeParcel_->ReadInt32();
1617     if (code == 0) {
1618         return result;
1619     }
1620     std::u16string str = napiSequence->nativeParcel_->ReadString16();
1621     napi_throw_error(env, nullptr, Str16ToStr8(str).c_str());
1622     return result;
1623 }
1624 
JS_checkReadArrayArgs(napi_env env,napi_callback_info info,size_t & argc,napi_value & thisVar,napi_value * argv)1625 napi_value NAPI_MessageSequence::JS_checkReadArrayArgs(napi_env env,
1626                                                        napi_callback_info info,
1627                                                        size_t &argc,
1628                                                        napi_value &thisVar,
1629                                                        napi_value* argv)
1630 {
1631     if (argv == nullptr) {
1632         ZLOGE(LOG_LABEL, "argv is nullptr");
1633         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1634     }
1635     if (argc != 1) {
1636         ZLOGE(LOG_LABEL, "requires 1 parameters");
1637         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1638     }
1639     void *data = nullptr;
1640     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1641 
1642     bool isArray = false;
1643     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1644     if (!isArray) {
1645         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1646         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1647     }
1648 
1649     napi_value napiValue = nullptr;
1650     napi_get_undefined(env, &napiValue);
1651     return napiValue;
1652 }
1653 
JS_readByteArray(napi_env env,napi_callback_info info)1654 napi_value NAPI_MessageSequence::JS_readByteArray(napi_env env, napi_callback_info info)
1655 {
1656     size_t argc = 0;
1657     napi_value thisVar = nullptr;
1658     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1659     NAPI_MessageSequence *napiSequence = nullptr;
1660     napi_unwrap(env, thisVar, (void **)&napiSequence);
1661     if (napiSequence == nullptr) {
1662         ZLOGE(LOG_LABEL, "napiSequence is null");
1663         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1664     }
1665     uint32_t maxBytesLen = MAX_BYTES_LENGTH;
1666     uint32_t arrayLength = napiSequence->nativeParcel_->ReadUint32();
1667     if (arrayLength >= maxBytesLen) {
1668         ZLOGE(LOG_LABEL, "byte array length too large");
1669         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1670     }
1671 
1672     if (argc > 0) {
1673         napi_value argv[ARGV_LENGTH_1] = {0};
1674         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1675         if (checkArgsResult == nullptr) {
1676             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1677             return checkArgsResult;
1678         }
1679 
1680         for (uint32_t i = 0; i < arrayLength; i++) {
1681             int8_t val = napiSequence->nativeParcel_->ReadInt8();
1682             napi_value num = nullptr;
1683             napi_create_int32(env, val, &num);
1684             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
1685         }
1686         napi_value napiValue = nullptr;
1687         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
1688         return napiValue;
1689     }
1690 
1691     if (arrayLength == 0) {
1692         napi_value result = nullptr;
1693         napi_create_array(env, &result);
1694         return result;
1695     }
1696     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiSequence);
1697     napi_value result = nullptr;
1698     napi_create_array_with_length(env, (size_t)arrayLength, &result);
1699     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1700         int8_t val = napiSequence->nativeParcel_->ReadInt8();
1701         napi_value num = nullptr;
1702         napi_create_int32(env, val, &num);
1703         napi_set_element(env, result, i, num);
1704     }
1705     return result;
1706 }
1707 
JS_readShortArray(napi_env env,napi_callback_info info)1708 napi_value NAPI_MessageSequence::JS_readShortArray(napi_env env, napi_callback_info info)
1709 {
1710     size_t argc = 0;
1711     napi_value thisVar = nullptr;
1712     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1713 
1714     NAPI_MessageSequence *napiSequence = nullptr;
1715     napi_unwrap(env, thisVar, (void **)&napiSequence);
1716     if (napiSequence == nullptr) {
1717         ZLOGE(LOG_LABEL, "napiSequence is null");
1718         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1719     }
1720 
1721     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
1722     if (argc > 0) {
1723         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1724         napi_value argv[ARGV_LENGTH_1] = {0};
1725         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1726         if (checkArgsResult == nullptr) {
1727             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1728             return checkArgsResult;
1729         }
1730 
1731         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1732             int16_t val = napiSequence->nativeParcel_->ReadInt16();
1733             napi_value num = nullptr;
1734             napi_create_int32(env, val, &num);
1735             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
1736         }
1737         napi_value napiValue = nullptr;
1738         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
1739         return napiValue;
1740     }
1741 
1742     if (arrayLength <= 0) {
1743         napi_value result = nullptr;
1744         napi_create_array(env, &result);
1745         return result;
1746     }
1747     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1748     napi_value result = nullptr;
1749     napi_create_array_with_length(env, (size_t)arrayLength, &result);
1750 
1751     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1752         int16_t val = napiSequence->nativeParcel_->ReadInt16();
1753         napi_value num = nullptr;
1754         napi_create_int32(env, val, &num);
1755         napi_set_element(env, result, i, num);
1756     }
1757     return result;
1758 }
1759 
JS_readIntArray(napi_env env,napi_callback_info info)1760 napi_value NAPI_MessageSequence::JS_readIntArray(napi_env env, napi_callback_info info)
1761 {
1762     size_t argc = 0;
1763     napi_value thisVar = nullptr;
1764     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1765 
1766     NAPI_MessageSequence *napiSequence = nullptr;
1767     napi_unwrap(env, thisVar, (void **)&napiSequence);
1768     if (napiSequence == nullptr) {
1769         ZLOGE(LOG_LABEL, "napiSequence is null");
1770         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1771     }
1772 
1773     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
1774     if (argc > 0) {
1775         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1776         napi_value argv[ARGV_LENGTH_1] = {0};
1777         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1778         if (checkArgsResult == nullptr) {
1779             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1780             return checkArgsResult;
1781         }
1782 
1783         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1784             int32_t val = napiSequence->nativeParcel_->ReadInt32();
1785             napi_value num = nullptr;
1786             napi_create_int32(env, val, &num);
1787             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
1788         }
1789         napi_value napiValue = nullptr;
1790         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
1791         return napiValue;
1792     }
1793 
1794     if (arrayLength <= 0) {
1795         napi_value result = nullptr;
1796         napi_create_array(env, &result);
1797         return result;
1798     }
1799     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1800     napi_value result = nullptr;
1801     napi_create_array_with_length(env, (size_t)arrayLength, &result);
1802 
1803     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1804         int32_t val = napiSequence->nativeParcel_->ReadInt32();
1805         napi_value num = nullptr;
1806         napi_create_int32(env, val, &num);
1807         napi_set_element(env, result, i, num);
1808     }
1809     return result;
1810 }
1811 
JS_readLongArray(napi_env env,napi_callback_info info)1812 napi_value NAPI_MessageSequence::JS_readLongArray(napi_env env, napi_callback_info info)
1813 {
1814     size_t argc = 0;
1815     napi_value thisVar = nullptr;
1816     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1817 
1818     NAPI_MessageSequence *napiSequence = nullptr;
1819     napi_unwrap(env, thisVar, (void **)&napiSequence);
1820     if (napiSequence == nullptr) {
1821         ZLOGE(LOG_LABEL, "napiSequence is null");
1822         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1823     }
1824 
1825     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
1826     if (argc > 0) {
1827         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1828         napi_value argv[ARGV_LENGTH_1] = {0};
1829         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1830         if (checkArgsResult == nullptr) {
1831             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1832             return checkArgsResult;
1833         }
1834 
1835         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1836             int64_t val = napiSequence->nativeParcel_->ReadInt64();
1837             napi_value num = nullptr;
1838             napi_create_int64(env, val, &num);
1839             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
1840         }
1841         napi_value napiValue = nullptr;
1842         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
1843         return napiValue;
1844     }
1845 
1846     if (arrayLength <= 0) {
1847         napi_value result = nullptr;
1848         napi_create_array(env, &result);
1849         return result;
1850     }
1851     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_64, napiSequence);
1852     napi_value result = nullptr;
1853     napi_create_array_with_length(env, (size_t)arrayLength, &result);
1854 
1855     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1856         int64_t val = napiSequence->nativeParcel_->ReadInt64();
1857         napi_value num = nullptr;
1858         napi_create_int64(env, val, &num);
1859         napi_set_element(env, result, i, num);
1860     }
1861     return result;
1862 }
1863 
JS_readFloatArray(napi_env env,napi_callback_info info)1864 napi_value NAPI_MessageSequence::JS_readFloatArray(napi_env env, napi_callback_info info)
1865 {
1866     size_t argc = 0;
1867     napi_value thisVar = nullptr;
1868     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1869 
1870     NAPI_MessageSequence *napiSequence = nullptr;
1871     napi_unwrap(env, thisVar, (void **)&napiSequence);
1872     if (napiSequence == nullptr) {
1873         ZLOGE(LOG_LABEL, "napiSequence is null");
1874         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1875     }
1876 
1877     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
1878     if (argc > 0) {
1879         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1880         napi_value argv[ARGV_LENGTH_1] = {0};
1881         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1882         if (checkArgsResult == nullptr) {
1883             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1884             return checkArgsResult;
1885         }
1886 
1887         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1888             double val = napiSequence->nativeParcel_->ReadDouble();
1889             napi_value num = nullptr;
1890             napi_create_double(env, val, &num);
1891             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
1892         }
1893         napi_value napiValue = nullptr;
1894         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
1895         return napiValue;
1896     }
1897 
1898     if (arrayLength <= 0) {
1899         napi_value result = nullptr;
1900         napi_create_array(env, &result);
1901         return result;
1902     }
1903     CHECK_READ_LENGTH(env, (size_t)arrayLength, sizeof(double), napiSequence);
1904     napi_value result = nullptr;
1905     napi_create_array_with_length(env, (size_t)arrayLength, &result);
1906 
1907     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1908         double val = napiSequence->nativeParcel_->ReadDouble();
1909         napi_value num = nullptr;
1910         napi_create_double(env, val, &num);
1911         napi_set_element(env, result, i, num);
1912     }
1913     return result;
1914 }
1915 
JS_readDoubleArray(napi_env env,napi_callback_info info)1916 napi_value NAPI_MessageSequence::JS_readDoubleArray(napi_env env, napi_callback_info info)
1917 {
1918     // This function implementation is the same as JS_readFloatArray
1919     return NAPI_MessageSequence::JS_readFloatArray(env, info);
1920 }
1921 
JS_readBooleanArray(napi_env env,napi_callback_info info)1922 napi_value NAPI_MessageSequence::JS_readBooleanArray(napi_env env, napi_callback_info info)
1923 {
1924     size_t argc = 0;
1925     napi_value thisVar = nullptr;
1926     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1927 
1928     NAPI_MessageSequence *napiSequence = nullptr;
1929     napi_unwrap(env, thisVar, (void **)&napiSequence);
1930     if (napiSequence == nullptr) {
1931         ZLOGE(LOG_LABEL, "napiSequence is null");
1932         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1933     }
1934 
1935     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
1936     if (argc > 0) {
1937         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1938         napi_value argv[ARGV_LENGTH_1] = {0};
1939         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1940         if (checkArgsResult == nullptr) {
1941             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1942             return checkArgsResult;
1943         }
1944 
1945         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1946             int8_t val = napiSequence->nativeParcel_->ReadInt8();
1947             napi_value boolean = nullptr;
1948             napi_get_boolean(env, val, &boolean);
1949             napi_set_element(env, argv[ARGV_INDEX_0], i, boolean);
1950         }
1951         napi_value napiValue = nullptr;
1952         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
1953         return napiValue;
1954     }
1955 
1956     if (arrayLength <= 0) {
1957         napi_value result = nullptr;
1958         napi_create_array(env, &result);
1959         return result;
1960     }
1961 
1962     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1963     napi_value result = nullptr;
1964     napi_create_array_with_length(env, (size_t)arrayLength, &result);
1965 
1966     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1967         int8_t val = napiSequence->nativeParcel_->ReadInt8();
1968         napi_value boolean = nullptr;
1969         napi_get_boolean(env, val, &boolean);
1970         napi_set_element(env, result, i, boolean);
1971     }
1972     return result;
1973 }
1974 
JS_readCharArray(napi_env env,napi_callback_info info)1975 napi_value NAPI_MessageSequence::JS_readCharArray(napi_env env, napi_callback_info info)
1976 {
1977     size_t argc = 0;
1978     napi_value thisVar = nullptr;
1979     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1980 
1981     NAPI_MessageSequence *napiSequence = nullptr;
1982     napi_unwrap(env, thisVar, (void **)&napiSequence);
1983     if (napiSequence == nullptr) {
1984         ZLOGE(LOG_LABEL, "napiSequence is null");
1985         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1986     }
1987 
1988     uint32_t arrayLength = napiSequence->nativeParcel_->ReadUint32();
1989     if (argc > 0) {
1990         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
1991         napi_value argv[ARGV_LENGTH_1] = {0};
1992         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
1993         if (checkArgsResult == nullptr) {
1994             ZLOGE(LOG_LABEL, "checkArgsResult is null");
1995             return checkArgsResult;
1996         }
1997 
1998         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
1999             uint8_t val = napiSequence->nativeParcel_->ReadUint8();
2000             napi_value num = nullptr;
2001             napi_create_uint32(env, static_cast<uint32_t>(val), &num);
2002             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
2003         }
2004         napi_value napiValue = nullptr;
2005         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
2006         return napiValue;
2007     }
2008 
2009     if (arrayLength == 0) {
2010         napi_value result = nullptr;
2011         napi_create_array(env, &result);
2012         return result;
2013     }
2014     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
2015     napi_value result = nullptr;
2016     napi_create_array_with_length(env, (size_t)arrayLength, &result);
2017 
2018     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
2019         uint8_t val = napiSequence->nativeParcel_->ReadUint8();
2020         napi_value num = nullptr;
2021         napi_create_uint32(env, static_cast<uint32_t>(val), &num);
2022         napi_set_element(env, result, i, num);
2023     }
2024     return result;
2025 }
2026 
JS_readStringArray(napi_env env,napi_callback_info info)2027 napi_value NAPI_MessageSequence::JS_readStringArray(napi_env env, napi_callback_info info)
2028 {
2029     size_t argc = 0;
2030     napi_value thisVar = nullptr;
2031     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2032 
2033     NAPI_MessageSequence *napiSequence = nullptr;
2034     napi_unwrap(env, thisVar, (void **)&napiSequence);
2035     if (napiSequence == nullptr) {
2036         ZLOGE(LOG_LABEL, "napiSequence is null");
2037         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2038     }
2039 
2040     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
2041     if (argc > 0) {
2042         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
2043         napi_value argv[ARGV_LENGTH_1] = {0};
2044         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
2045         if (checkArgsResult == nullptr) {
2046             ZLOGE(LOG_LABEL, "checkArgsResult is null");
2047             return checkArgsResult;
2048         }
2049 
2050         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
2051             if (napiSequence->nativeParcel_->GetReadableBytes() <= 0) {
2052                 break;
2053             }
2054             std::u16string parcelString = napiSequence->nativeParcel_->ReadString16();
2055             std::string outString = Str16ToStr8(parcelString.c_str());
2056             napi_value val = nullptr;
2057             napi_create_string_utf8(env, outString.c_str(), outString.length(), &val);
2058             napi_set_element(env, argv[ARGV_INDEX_0], i, val);
2059         }
2060         napi_value napiValue = nullptr;
2061         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
2062         return napiValue;
2063     }
2064 
2065     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
2066     napi_value result = nullptr;
2067     napi_create_array(env, &result);
2068     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
2069         if (napiSequence->nativeParcel_->GetReadableBytes() <= 0) {
2070             break;
2071         }
2072         std::u16string parcelString = napiSequence->nativeParcel_->ReadString16();
2073         std::string outString = Str16ToStr8(parcelString.c_str());
2074         napi_value val = nullptr;
2075         napi_create_string_utf8(env, outString.c_str(), outString.length(), &val);
2076         napi_set_element(env, result, i, val);
2077     }
2078     return result;
2079 }
2080 
JS_readParcelableArrayCallJsFunc(napi_env env,napi_value & element,napi_value & thisVar)2081 napi_value NAPI_MessageSequence::JS_readParcelableArrayCallJsFunc(napi_env env,
2082     napi_value &element, napi_value &thisVar)
2083 {
2084     napi_value propKey = nullptr;
2085     const char *propKeyStr = "unmarshalling";
2086     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
2087     napi_value prop = nullptr;
2088     napi_get_property(env, element, propKey, &prop);
2089 
2090     napi_value funcArg[1] = { thisVar };
2091     napi_value callResult = nullptr;
2092     napi_call_function(env, element, prop, 1, funcArg, &callResult);
2093     if (callResult == nullptr) {
2094         return napiErr.ThrowError(env, errorDesc::CALL_JS_METHOD_ERROR);
2095     }
2096 
2097     napi_value retValue = nullptr;
2098     napi_get_undefined(env, &retValue);
2099     return retValue;
2100 }
2101 
JS_readParcelableArray(napi_env env,napi_callback_info info)2102 napi_value NAPI_MessageSequence::JS_readParcelableArray(napi_env env, napi_callback_info info)
2103 {
2104     size_t argc = 1;
2105     napi_value thisVar = nullptr;
2106     napi_value argv[ARGV_LENGTH_1] = {0};
2107     napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
2108     if (checkArgsResult == nullptr) {
2109         ZLOGE(LOG_LABEL, "checkArgsResult is null");
2110         return checkArgsResult;
2111     }
2112 
2113     NAPI_MessageSequence *napiSequence = nullptr;
2114     napi_unwrap(env, thisVar, (void **)&napiSequence);
2115     if (napiSequence == nullptr) {
2116         ZLOGE(LOG_LABEL, "napiSequence is null");
2117         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2118     }
2119 
2120     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
2121     // checking here is not accurate, but we can defend some extreme attacking case.
2122     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiSequence);
2123 
2124     uint32_t length = 0;
2125     napi_get_array_length(env, argv[ARGV_INDEX_0], &length);
2126     if (static_cast<int32_t>(length) != arrayLength) {
2127         ZLOGE(LOG_LABEL, "Bad length while reading Sequenceable array");
2128         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2129     }
2130 
2131     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
2132         int32_t len = napiSequence->nativeParcel_->ReadInt32();
2133         if (len > 0) {
2134             bool hasElement = false;
2135             napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
2136             if (!hasElement) {
2137                 ZLOGE(LOG_LABEL, "parameter check error");
2138                 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2139             }
2140             napi_value element = nullptr;
2141             napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
2142             napi_value callJsFuncResult = JS_readParcelableArrayCallJsFunc(env, element, thisVar);
2143             if (callJsFuncResult == nullptr) {
2144                 ZLOGE(LOG_LABEL, "call unmarshalling failed, element index:%{public}d", i);
2145                 return callJsFuncResult;
2146             }
2147         }
2148     }
2149     napi_value result = nullptr;
2150     napi_get_undefined(env, &result);
2151     return result;
2152 }
2153 
JS_readRemoteObjectArray(napi_env env,napi_callback_info info)2154 napi_value NAPI_MessageSequence::JS_readRemoteObjectArray(napi_env env, napi_callback_info info)
2155 {
2156     napi_value result = nullptr;
2157     napi_get_undefined(env, &result);
2158 
2159     size_t argc = 0;
2160     napi_value argv[ARGV_LENGTH_1] = {0};
2161     napi_value thisVar = nullptr;
2162     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2163 
2164     NAPI_MessageSequence *napiSequence = nullptr;
2165     napi_unwrap(env, thisVar, (void **)&napiSequence);
2166     if (napiSequence == nullptr) {
2167         ZLOGE(LOG_LABEL, "napiSequence is null");
2168         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2169     }
2170 
2171     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
2172     if (argc > 0) { // uses passed in array
2173         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
2174         if (checkArgsResult == nullptr) {
2175             ZLOGE(LOG_LABEL, "checkArgsResult is null");
2176             return checkArgsResult;
2177         }
2178         uint32_t length = 0;
2179         napi_get_array_length(env, argv[ARGV_INDEX_0], &length);
2180         if (static_cast<int32_t>(length) != arrayLength) {
2181             ZLOGE(LOG_LABEL, "Bad length while reading RemoteObject array");
2182             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2183         }
2184         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
2185             sptr<IRemoteObject> value = napiSequence->nativeParcel_->ReadRemoteObject();
2186             napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
2187             napi_set_element(env, argv[ARGV_INDEX_0], i, napiValue);
2188         }
2189         return result;
2190     }
2191 
2192     if (arrayLength <= 0) {
2193         napi_get_null(env, &result);
2194         return result;
2195     }
2196     napi_create_array(env, &result);
2197     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
2198         sptr<IRemoteObject> value = napiSequence->nativeParcel_->ReadRemoteObject();
2199         napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
2200         napi_set_element(env, result, i, napiValue);
2201     }
2202     return result;
2203 }
2204 
JS_readParcelable(napi_env env,napi_callback_info info)2205 napi_value NAPI_MessageSequence::JS_readParcelable(napi_env env, napi_callback_info info)
2206 {
2207     size_t argc = 1;
2208     napi_value argv[ARGV_LENGTH_1] = {0};
2209     napi_value thisVar = nullptr;
2210     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2211     if (argc != 1) {
2212         ZLOGE(LOG_LABEL, "requires 1 parameters");
2213         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2214     }
2215 
2216     NAPI_MessageSequence *napiSequence = nullptr;
2217     napi_unwrap(env, thisVar, (void **)&napiSequence);
2218     if (napiSequence == nullptr) {
2219         ZLOGE(LOG_LABEL, "napiSequence is null");
2220         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2221     }
2222 
2223     int32_t len = napiSequence->nativeParcel_->ReadInt32();
2224     if (len > 0) {
2225         napi_value propKey = nullptr;
2226         const char *propKeyStr = "unmarshalling";
2227         napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
2228         napi_value prop = nullptr;
2229         napi_get_property(env, argv[ARGV_INDEX_0], propKey, &prop);
2230 
2231         napi_value funcArg[1] = {thisVar};
2232         napi_value callResult = nullptr;
2233         napi_call_function(env, argv[ARGV_INDEX_0], prop, 1, funcArg, &callResult);
2234         if (callResult != nullptr) {
2235             return callResult;
2236         }
2237         ZLOGI(LOG_LABEL, "call unmarshalling failed");
2238     }
2239 
2240     return napiErr.ThrowError(env, errorDesc::CALL_JS_METHOD_ERROR);
2241 }
2242 
JS_create(napi_env env,napi_callback_info info)2243 napi_value NAPI_MessageSequence::JS_create(napi_env env, napi_callback_info info)
2244 {
2245     // new native sequence object
2246     napi_value global = nullptr;
2247     napi_status status = napi_get_global(env, &global);
2248     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
2249     napi_value constructor = nullptr;
2250     status = napi_get_named_property(env, global, "IPCSequenceConstructor_", &constructor);
2251     NAPI_ASSERT(env, status == napi_ok, "get message sequence constructor failed");
2252     napi_value jsMessageSequence;
2253     status = napi_new_instance(env, constructor, 0, nullptr, &jsMessageSequence);
2254     NAPI_ASSERT(env, status == napi_ok, "failed to  construct js MessageSequence");
2255     return jsMessageSequence;
2256 }
2257 
JS_reclaim(napi_env env,napi_callback_info info)2258 napi_value NAPI_MessageSequence::JS_reclaim(napi_env env, napi_callback_info info)
2259 {
2260     size_t argc = 0;
2261     napi_value thisVar = nullptr;
2262     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2263 
2264     NAPI_MessageSequence *napiSequence = nullptr;
2265     napi_remove_wrap(env, thisVar, (void **)&napiSequence);
2266     NAPI_ASSERT(env, napiSequence != nullptr, "napiSequence is null");
2267     delete napiSequence;
2268 
2269     napi_value result = nullptr;
2270     napi_get_undefined(env, &result);
2271     return result;
2272 }
2273 
JS_writeRemoteObject(napi_env env,napi_callback_info info)2274 napi_value NAPI_MessageSequence::JS_writeRemoteObject(napi_env env, napi_callback_info info)
2275 {
2276     size_t argc = 1;
2277     napi_value argv[ARGV_LENGTH_1] = {0};
2278     napi_value thisVar = nullptr;
2279     void *data = nullptr;
2280     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2281     if (argc != REQUIRED_ARGS_COUNT_1) {
2282         ZLOGE(LOG_LABEL, "requires 1 parameter");
2283         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2284     }
2285     napi_valuetype valueType = napi_null;
2286     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2287     if (valueType != napi_object) {
2288         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
2289         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2290     }
2291     sptr<IRemoteObject> remoteObject = NAPI_ohos_rpc_getNativeRemoteObject(env, argv[ARGV_INDEX_0]);
2292     if (remoteObject == nullptr) {
2293         ZLOGE(LOG_LABEL, "remote object is nullptr");
2294         return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
2295     }
2296     NAPI_MessageSequence *napiSequence = nullptr;
2297     napi_unwrap(env, thisVar, (void **)&napiSequence);
2298     if (napiSequence == nullptr) {
2299         ZLOGE(LOG_LABEL, "napiSequence is null");
2300         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2301     }
2302     bool writeResult = napiSequence->nativeParcel_->WriteRemoteObject(remoteObject);
2303     if (writeResult == false) {
2304         ZLOGE(LOG_LABEL, "write remote object failed");
2305         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2306     }
2307     napi_value result = nullptr;
2308     napi_get_undefined(env, &result);
2309     return result;
2310 }
2311 
JS_readRemoteObject(napi_env env,napi_callback_info info)2312 napi_value NAPI_MessageSequence::JS_readRemoteObject(napi_env env, napi_callback_info info)
2313 {
2314     size_t argc = 0;
2315     napi_value thisVar = nullptr;
2316     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2317 
2318     NAPI_MessageSequence *napiSequence = nullptr;
2319     napi_unwrap(env, thisVar, (void **)&napiSequence);
2320     if (napiSequence == nullptr) {
2321         ZLOGE(LOG_LABEL, "napiSequence is null");
2322         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2323     }
2324 
2325     sptr<IRemoteObject> value = napiSequence->nativeParcel_->ReadRemoteObject();
2326     napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
2327     if (napiValue == nullptr) {
2328         ZLOGE(LOG_LABEL, "remote object is null");
2329         return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
2330     }
2331     return napiValue;
2332 }
2333 
JS_writeInterfaceToken(napi_env env,napi_callback_info info)2334 napi_value NAPI_MessageSequence::JS_writeInterfaceToken(napi_env env, napi_callback_info info)
2335 {
2336     size_t argc = 1;
2337     napi_value argv[ARGV_LENGTH_1] = {0};
2338     napi_value thisVar = nullptr;
2339     void *data = nullptr;
2340     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2341     if (argc != REQUIRED_ARGS_COUNT_1) {
2342         ZLOGE(LOG_LABEL, "requires 1 parameter");
2343         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2344     }
2345     napi_valuetype valueType = napi_null;
2346     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2347     if (valueType != napi_string) {
2348         ZLOGE(LOG_LABEL, "type mismatch for parameter");
2349         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2350     }
2351     size_t bufferSize = 0;
2352     size_t maxSize = MAX_BYTES_LENGTH;
2353     napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
2354     if (bufferSize >= maxSize) {
2355         ZLOGE(LOG_LABEL, "string length too large");
2356         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2357     }
2358     char stringValue[bufferSize + 1];
2359     size_t jsStringLength = 0;
2360     napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
2361     if (jsStringLength != bufferSize) {
2362         ZLOGE(LOG_LABEL, "string length wrong");
2363         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2364     }
2365 
2366     NAPI_MessageSequence *napiSequence = nullptr;
2367     napi_unwrap(env, thisVar, (void **)&napiSequence);
2368     if (napiSequence == nullptr) {
2369         ZLOGE(LOG_LABEL, "napiSequence is null");
2370         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2371     }
2372 
2373     std::string parcelString = stringValue;
2374     bool writeResult = napiSequence->nativeParcel_->WriteInterfaceToken(to_utf16(parcelString));
2375     if (writeResult == false) {
2376         ZLOGE(LOG_LABEL, "write interface token failed");
2377         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2378     }
2379     napi_value result = nullptr;
2380     napi_get_undefined(env, &result);
2381     return result;
2382 }
2383 
JS_readInterfaceToken(napi_env env,napi_callback_info info)2384 napi_value NAPI_MessageSequence::JS_readInterfaceToken(napi_env env, napi_callback_info info)
2385 {
2386     size_t argc = 0;
2387     napi_value thisVar = nullptr;
2388     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2389 
2390     NAPI_MessageSequence *napiSequence = nullptr;
2391     napi_unwrap(env, thisVar, (void **)&napiSequence);
2392     if (napiSequence == nullptr) {
2393         ZLOGE(LOG_LABEL, "napiSequence is null");
2394         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2395     }
2396 
2397     std::u16string parcelString = napiSequence->nativeParcel_->ReadInterfaceToken();
2398     std::string outString = Str16ToStr8(parcelString.c_str());
2399     napi_value napiValue = nullptr;
2400     napi_create_string_utf8(env, outString.c_str(), outString.length(), &napiValue);
2401     return napiValue;
2402 }
2403 
JS_CloseFileDescriptor(napi_env env,napi_callback_info info)2404 napi_value NAPI_MessageSequence::JS_CloseFileDescriptor(napi_env env, napi_callback_info info)
2405 {
2406     size_t argc = 1;
2407     napi_value argv[ARGV_LENGTH_1] = {0};
2408     napi_value thisVar = nullptr;
2409     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2410     if (argc != 1) {
2411         ZLOGE(LOG_LABEL, "requires 1 parameters");
2412         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2413     }
2414     napi_valuetype valueType = napi_null;
2415     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2416     if (valueType != napi_number) {
2417         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
2418         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2419     }
2420     int32_t fd = -1;
2421     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
2422     close(fd);
2423     napi_value result = nullptr;
2424     napi_get_undefined(env, &result);
2425     return result;
2426 }
2427 
JS_DupFileDescriptor(napi_env env,napi_callback_info info)2428 napi_value NAPI_MessageSequence::JS_DupFileDescriptor(napi_env env, napi_callback_info info)
2429 {
2430     size_t argc = 1;
2431     napi_value argv[ARGV_LENGTH_1] = {0};
2432     napi_value thisVar = nullptr;
2433     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2434     if (argc != 1) {
2435         ZLOGE(LOG_LABEL, "requires 1 parameters");
2436         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2437     }
2438     napi_valuetype valueType = napi_null;
2439     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2440     if (valueType != napi_number) {
2441         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
2442         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2443     }
2444     int32_t fd = -1;
2445     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
2446     int32_t dupResult = dup(fd);
2447     if (dupResult < 0) {
2448         ZLOGE(LOG_LABEL, "os dup function failed");
2449         return napiErr.ThrowError(env, errorDesc::OS_DUP_ERROR);
2450     }
2451     napi_value napiValue;
2452     napi_create_int32(env, dupResult, &napiValue);
2453     return napiValue;
2454 }
2455 
JS_ContainFileDescriptors(napi_env env,napi_callback_info info)2456 napi_value NAPI_MessageSequence::JS_ContainFileDescriptors(napi_env env, napi_callback_info info)
2457 {
2458     size_t argc = 0;
2459     napi_value thisVar = nullptr;
2460     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2461     NAPI_MessageSequence *napiSequence = nullptr;
2462     napi_unwrap(env, thisVar, (void **)&napiSequence);
2463     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
2464     bool result = napiSequence->nativeParcel_->ContainFileDescriptors();
2465     napi_value napiValue = nullptr;
2466     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
2467     return napiValue;
2468 }
2469 
JS_WriteFileDescriptor(napi_env env,napi_callback_info info)2470 napi_value NAPI_MessageSequence::JS_WriteFileDescriptor(napi_env env, napi_callback_info info)
2471 {
2472     size_t argc = 1;
2473     napi_value argv[ARGV_LENGTH_1] = {0};
2474     napi_value thisVar = nullptr;
2475     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2476     if (argc != 1) {
2477         ZLOGE(LOG_LABEL, "requires 1 parameters");
2478         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2479     }
2480     napi_valuetype valueType = napi_null;
2481     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2482     if (valueType != napi_number) {
2483         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
2484         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2485     }
2486     int32_t fd = -1;
2487     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
2488     NAPI_MessageSequence *napiSequence = nullptr;
2489     napi_unwrap(env, thisVar, (void **)&napiSequence);
2490     if (napiSequence == nullptr) {
2491         ZLOGE(LOG_LABEL, "napiSequence is null");
2492         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2493     }
2494     bool result = napiSequence->nativeParcel_->WriteFileDescriptor(fd);
2495     if (!result) {
2496         ZLOGE(LOG_LABEL, "write file descriptor failed");
2497         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2498     }
2499     napi_value napiValue = nullptr;
2500     napi_get_undefined(env, &napiValue);
2501     return napiValue;
2502 }
2503 
JS_ReadFileDescriptor(napi_env env,napi_callback_info info)2504 napi_value NAPI_MessageSequence::JS_ReadFileDescriptor(napi_env env, napi_callback_info info)
2505 {
2506     size_t argc = 0;
2507     napi_value thisVar = nullptr;
2508     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2509     NAPI_MessageSequence *napiSequence = nullptr;
2510     napi_unwrap(env, thisVar, (void **)&napiSequence);
2511     if (napiSequence == nullptr) {
2512         ZLOGE(LOG_LABEL, "napiSequence is null");
2513         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2514     }
2515     int32_t result = napiSequence->nativeParcel_->ReadFileDescriptor();
2516     if (result == -1) {
2517         ZLOGE(LOG_LABEL, "read file descriptor failed");
2518         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2519     }
2520     napi_value napiValue;
2521     napi_create_int32(env, result, &napiValue);
2522     return napiValue;
2523 }
2524 
JS_WriteAshmem(napi_env env,napi_callback_info info)2525 napi_value NAPI_MessageSequence::JS_WriteAshmem(napi_env env, napi_callback_info info)
2526 {
2527     size_t argc = 1;
2528     napi_value argv[ARGV_LENGTH_1] = {0};
2529     napi_value thisVar = nullptr;
2530     void *data = nullptr;
2531     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
2532     if (argc != 1) {
2533         ZLOGE(LOG_LABEL, "requires 1 parameters");
2534         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2535     }
2536     // check type is Ashmem
2537     napi_value global = nullptr;
2538     napi_value napiValue = nullptr;
2539     napi_get_undefined(env, &napiValue);
2540     napi_status status = napi_get_global(env, &global);
2541     if (status != napi_ok) {
2542         ZLOGE(LOG_LABEL, "get napi global failed");
2543         return napiValue;
2544     }
2545     napi_value constructor = nullptr;
2546     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
2547     if (status != napi_ok) {
2548         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
2549         return napiValue;
2550     }
2551     bool isAshmem = false;
2552     napi_instanceof(env, argv[ARGV_INDEX_0], constructor, &isAshmem);
2553     if (!isAshmem) {
2554         ZLOGE(LOG_LABEL, "parameter is not instanceof Ashmem");
2555         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2556     }
2557     NAPIAshmem *napiAshmem = nullptr;
2558     napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&napiAshmem);
2559     if (napiAshmem == nullptr) {
2560         ZLOGE(LOG_LABEL, "napiAshmem is null");
2561         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2562     }
2563     sptr<Ashmem> nativeAshmem = napiAshmem->GetAshmem();
2564     NAPI_MessageSequence *napiSequence = nullptr;
2565     napi_unwrap(env, thisVar, (void **)&napiSequence);
2566     if (napiSequence == nullptr) {
2567         ZLOGE(LOG_LABEL, "napiSequence is null");
2568         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2569     }
2570     bool result = napiSequence->nativeParcel_->WriteAshmem(nativeAshmem);
2571     if (!result) {
2572         ZLOGE(LOG_LABEL, "write ashmem failed");
2573         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2574     }
2575     return napiValue;
2576 }
2577 
JS_ReadAshmem(napi_env env,napi_callback_info info)2578 napi_value NAPI_MessageSequence::JS_ReadAshmem(napi_env env, napi_callback_info info)
2579 {
2580     size_t argc = 0;
2581     napi_value thisVar = nullptr;
2582     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2583 
2584     NAPI_MessageSequence *napiSequence = nullptr;
2585     napi_unwrap(env, thisVar, (void **)&napiSequence);
2586     if (napiSequence == nullptr) {
2587         ZLOGE(LOG_LABEL, "napiSequence is null");
2588         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2589     }
2590     sptr<Ashmem> nativeAshmem = napiSequence->nativeParcel_->ReadAshmem();
2591     if (nativeAshmem == nullptr) {
2592         ZLOGE(LOG_LABEL, "nativeAshmem is null");
2593         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2594     }
2595     napi_value global = nullptr;
2596     napi_value napiValue = nullptr;
2597     napi_get_undefined(env, &napiValue);
2598     napi_status status = napi_get_global(env, &global);
2599     if (status != napi_ok) {
2600         ZLOGE(LOG_LABEL, "get napi global failed");
2601         return napiValue;
2602     }
2603     napi_value constructor = nullptr;
2604     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
2605     if (status != napi_ok) {
2606         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
2607         return napiValue;
2608     }
2609     napi_value jsAshmem;
2610     status = napi_new_instance(env, constructor, 0, nullptr, &jsAshmem);
2611     if (status != napi_ok) {
2612         ZLOGE(LOG_LABEL, "failed to  construct js Ashmem");
2613         return napiValue;
2614     }
2615     NAPIAshmem *napiAshmem = nullptr;
2616     napi_unwrap(env, jsAshmem, (void **)&napiAshmem);
2617     if (napiAshmem == nullptr) {
2618         ZLOGE(LOG_LABEL, "napiAshmem is null");
2619         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2620     }
2621     napiAshmem->SetAshmem(nativeAshmem);
2622     return jsAshmem;
2623 }
2624 
JS_checkWriteRawDataArgs(napi_env env,size_t argc,napi_value * argv)2625 napi_value NAPI_MessageSequence::JS_checkWriteRawDataArgs(napi_env env, size_t argc, napi_value* argv)
2626 {
2627     if (argv == nullptr) {
2628         ZLOGE(LOG_LABEL, "argv is nullptr");
2629         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2630     }
2631     size_t expectedArgc = 2;
2632     if (argc != expectedArgc) {
2633         ZLOGE(LOG_LABEL, "requires 2 parameters");
2634         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2635     }
2636     bool isArray = false;
2637     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
2638     if (!isArray) {
2639         bool isTypedArray = false;
2640         napi_is_typedarray(env, argv[ARGV_INDEX_0], &isTypedArray);
2641         if (!isTypedArray) {
2642             ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not array, not typedarray");
2643             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2644         }
2645     }
2646 
2647     napi_valuetype valueType = napi_null;
2648     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
2649     if (valueType != napi_number) {
2650         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
2651         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2652     }
2653 
2654     napi_value napiValue = nullptr;
2655     napi_get_undefined(env, &napiValue);
2656     return napiValue;
2657 }
2658 
JS_WriteRawDataForArray(napi_env env,napi_value jsArray,uint32_t size,NAPI_MessageSequence * napiSequence)2659 bool NAPI_MessageSequence::JS_WriteRawDataForArray(napi_env env, napi_value jsArray,
2660     uint32_t size, NAPI_MessageSequence *napiSequence)
2661 {
2662     std::vector<int32_t> array;
2663     uint32_t length = 0;
2664     napi_get_array_length(env, jsArray, &length);
2665     for (uint32_t i = 0; i < length; i++) {
2666         bool hasElement = false;
2667         napi_has_element(env, jsArray, i, &hasElement);
2668         if (!hasElement) {
2669             ZLOGE(LOG_LABEL, "parameter check error");
2670             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2671         }
2672 
2673         napi_value element = nullptr;
2674         napi_get_element(env, jsArray, i, &element);
2675 
2676         int32_t value = 0;
2677         napi_get_value_int32(env, element, &value);
2678         array.push_back(value);
2679     }
2680     if (length < size) {
2681         uint32_t padSize = size - length;
2682         ZLOGW(LOG_LABEL, "array length:%{public}u less than parameter size:%{public}u"
2683             " need pad:%{public}u 0", length, size, padSize);
2684         for (uint32_t i = 0; i < padSize; i++) {
2685             array.push_back(0);
2686         }
2687     }
2688     return napiSequence->nativeParcel_->WriteRawData(array.data(), size * BYTE_SIZE_32);
2689 }
2690 
JS_WriteRawDataForTypedArray(napi_env env,napi_value jsTypedArray,size_t size,NAPI_MessageSequence * napiSequence)2691 bool NAPI_MessageSequence::JS_WriteRawDataForTypedArray(napi_env env, napi_value jsTypedArray,
2692     size_t size, NAPI_MessageSequence *napiSequence)
2693 {
2694     napi_typedarray_type type;
2695     char *data = nullptr;
2696     size_t arrayLength = 0;
2697     napi_value arrayBuffer;
2698     size_t byteOffset = 0;
2699     napi_status isGet = napi_get_typedarray_info(env, jsTypedArray, &type,
2700         &arrayLength, (void **)&data, &arrayBuffer, &byteOffset);
2701     if (isGet != napi_ok || type != napi_int32_array) {
2702         ZLOGE(LOG_LABEL, "typedarray get info failed or not napi_int32_array");
2703         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2704     }
2705     if (arrayLength < size) {
2706         ZLOGE(LOG_LABEL, "typedarray length:%{public}zu less than parameter size:%{public}zu",
2707             arrayLength, size);
2708         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2709     }
2710     return napiSequence->nativeParcel_->WriteRawData(data - byteOffset, BYTE_SIZE_32 * size);
2711 }
2712 
JS_WriteRawData(napi_env env,napi_callback_info info)2713 napi_value NAPI_MessageSequence::JS_WriteRawData(napi_env env, napi_callback_info info)
2714 {
2715     size_t argc = 2;
2716     napi_value argv[ARGV_LENGTH_2] = {0};
2717     napi_value thisVar = nullptr;
2718     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2719     napi_value checkArgsResult = JS_checkWriteRawDataArgs(env, argc, argv);
2720     if (checkArgsResult == nullptr) {
2721         ZLOGE(LOG_LABEL, "checkArgsResult is null");
2722         return checkArgsResult;
2723     }
2724 
2725     NAPI_MessageSequence *napiSequence = nullptr;
2726     napi_unwrap(env, thisVar, (void **)&napiSequence);
2727     if (napiSequence == nullptr) {
2728         ZLOGE(LOG_LABEL, "napiSequence is null");
2729         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2730     }
2731 
2732     int32_t size = 0;
2733     napi_status isGetOk = napi_get_value_int32(env, argv[ARGV_INDEX_1], &size);
2734     if (isGetOk != napi_ok || size <= 0) {
2735         ZLOGE(LOG_LABEL, "error for parameter 2 size is %{public}d, get failed", size);
2736         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2737     }
2738     bool result = false;
2739     bool isArray = false;
2740     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
2741     if (isArray) {
2742         result = JS_WriteRawDataForArray(env, argv[ARGV_INDEX_0], static_cast<uint32_t>(size), napiSequence);
2743     } else {
2744         result = JS_WriteRawDataForTypedArray(env, argv[ARGV_INDEX_0], static_cast<size_t>(size), napiSequence);
2745     }
2746 
2747     if (!result) {
2748         ZLOGE(LOG_LABEL, "write raw data failed");
2749         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2750     }
2751     napi_value napiValue = nullptr;
2752     napi_get_undefined(env, &napiValue);
2753     return napiValue;
2754 }
2755 
JS_ReadRawData(napi_env env,napi_callback_info info)2756 napi_value NAPI_MessageSequence::JS_ReadRawData(napi_env env, napi_callback_info info)
2757 {
2758     size_t argc = 1;
2759     napi_value argv[ARGV_LENGTH_1] = {0};
2760     napi_value thisVar = nullptr;
2761     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2762     if (argc != 1) {
2763         ZLOGE(LOG_LABEL, "requires 1 parameters");
2764         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2765     }
2766     napi_valuetype valueType = napi_null;
2767     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2768     if (valueType != napi_number) {
2769         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
2770         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2771     }
2772     int32_t arraySize = 0;
2773     napi_get_value_int32(env, argv[ARGV_INDEX_0], &arraySize);
2774     napi_value result = nullptr;
2775     if (arraySize <= 0) {
2776         ZLOGE(LOG_LABEL, "arraySize is %{public}d, error", arraySize);
2777         napi_create_array(env, &result);
2778         return result;
2779     }
2780     NAPI_MessageSequence *napiSequence = nullptr;
2781     napi_unwrap(env, thisVar, (void **)&napiSequence);
2782     if (napiSequence == nullptr) {
2783         ZLOGE(LOG_LABEL, "napiSequence is null");
2784         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2785     }
2786     const void *rawData = napiSequence->nativeParcel_->ReadRawData(arraySize * BYTE_SIZE_32);
2787     if (rawData == nullptr) {
2788         ZLOGE(LOG_LABEL, "rawData is null");
2789         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2790     }
2791     // [c++] rawData -> byteBuffer()[js]
2792     napi_value arrayBuffer = nullptr;
2793     void *arrayBufferPtr = nullptr;
2794     size_t bufferSize = static_cast<size_t>(arraySize) * BYTE_SIZE_32;
2795 
2796     napi_status isCreateBufferOk = napi_create_arraybuffer(env, bufferSize, &arrayBufferPtr, &arrayBuffer);
2797     if (isCreateBufferOk != napi_ok) {
2798         ZLOGE(LOG_LABEL, "JS_ReadRawData create arrayBuffer failed");
2799         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2800     }
2801 
2802     napi_status isCreateArrayOk =
2803         napi_create_typedarray(env, napi_int32_array, arraySize, arrayBuffer, 0, &result);
2804     if (isCreateArrayOk != napi_ok) {
2805         ZLOGE(LOG_LABEL, "JS_ReadRawData create Typedarray failed");
2806         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2807     }
2808 
2809     errno_t status = memcpy_s(arrayBufferPtr, bufferSize, rawData, bufferSize);
2810     NAPI_ASSERT(env, status == EOK, "JS_ReadRawData memcpy_s is failed");
2811     return result;
2812 }
2813 
JS_WriteRawDataBuffer(napi_env env,napi_callback_info info)2814 napi_value NAPI_MessageSequence::JS_WriteRawDataBuffer(napi_env env, napi_callback_info info)
2815 {
2816     size_t argc = ARGV_LENGTH_2;
2817     napi_value argv[ARGV_LENGTH_2] = {0};
2818     napi_value thisVar = nullptr;
2819     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2820     if (argc != ARGV_LENGTH_2) {
2821         ZLOGE(LOG_LABEL, "requires 2 parameters");
2822         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2823     }
2824 
2825     bool isArrayBuffer = false;
2826     napi_is_arraybuffer(env, argv[ARGV_INDEX_0], &isArrayBuffer);
2827     if (!isArrayBuffer) {
2828         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not ArrayBuffer");
2829         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2830     }
2831 
2832     napi_valuetype valueType = napi_null;
2833     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
2834     if (valueType != napi_number) {
2835         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
2836         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2837     }
2838 
2839     void *data = nullptr;
2840     size_t byteLength = 0;
2841     napi_status isGet = napi_get_arraybuffer_info(env, argv[ARGV_INDEX_0], (void **)&data, &byteLength);
2842     if (isGet != napi_ok) {
2843         ZLOGE(LOG_LABEL, "arraybuffery get info failed");
2844         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2845     }
2846 
2847     int64_t size = 0;
2848     napi_status isGetOk = napi_get_value_int64(env, argv[ARGV_INDEX_1], &size);
2849     if (isGetOk != napi_ok || size <= 0 || size > byteLength) {
2850         ZLOGE(LOG_LABEL, "error for parameter 2 size is %{public}" PRId64, size);
2851         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2852     }
2853 
2854     NAPI_MessageSequence *napiSequence = nullptr;
2855     napi_unwrap(env, thisVar, (void **)&napiSequence);
2856     if (napiSequence == nullptr) {
2857         ZLOGE(LOG_LABEL, "napiSequence is null");
2858         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2859     }
2860 
2861     if (!napiSequence->nativeParcel_->WriteRawData(data, size)) {
2862         ZLOGE(LOG_LABEL, "write raw data failed");
2863         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
2864     }
2865 
2866     napi_value napiValue = nullptr;
2867     napi_get_undefined(env, &napiValue);
2868     return napiValue;
2869 }
2870 
JS_ReadRawDataBuffer(napi_env env,napi_callback_info info)2871 napi_value NAPI_MessageSequence::JS_ReadRawDataBuffer(napi_env env, napi_callback_info info)
2872 {
2873     size_t argc = ARGV_LENGTH_1;
2874     napi_value argv[ARGV_LENGTH_1] = {0};
2875     napi_value thisVar = nullptr;
2876     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2877     if (argc != ARGV_LENGTH_1) {
2878         ZLOGE(LOG_LABEL, "requires 1 parameters");
2879         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2880     }
2881 
2882     napi_valuetype valueType = napi_null;
2883     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
2884     if (valueType != napi_number) {
2885         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
2886         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
2887     }
2888     int64_t arraySize = 0;
2889     napi_get_value_int64(env, argv[ARGV_INDEX_0], &arraySize);
2890     napi_value result = nullptr;
2891     if (arraySize <= 0) {
2892         ZLOGE(LOG_LABEL, "arraySize is %{public}" PRId64 ", error", arraySize);
2893         napi_create_array(env, &result);
2894         return result;
2895     }
2896     NAPI_MessageSequence *napiSequence = nullptr;
2897     napi_unwrap(env, thisVar, (void **)&napiSequence);
2898     if (napiSequence == nullptr) {
2899         ZLOGE(LOG_LABEL, "napiSequence is null");
2900         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2901     }
2902     const void *rawData = napiSequence->nativeParcel_->ReadRawData(arraySize);
2903     if (rawData == nullptr) {
2904         ZLOGE(LOG_LABEL, "rawData is null");
2905         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2906     }
2907 
2908     napi_value arrayBuffer = nullptr;
2909     void *arrayBufferPtr = nullptr;
2910     size_t bufferSize = static_cast<size_t>(arraySize);
2911     napi_status isCreateBufferOk = napi_create_arraybuffer(env, bufferSize, &arrayBufferPtr, &arrayBuffer);
2912     if (isCreateBufferOk != napi_ok) {
2913         ZLOGE(LOG_LABEL, "JS_ReadRawData create arrayBuffer failed");
2914         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
2915     }
2916 
2917     errno_t status = memcpy_s(arrayBufferPtr, bufferSize, rawData, bufferSize);
2918     NAPI_ASSERT(env, status == EOK, "JS_ReadRawDataBuffer memcpy_s fail");
2919     return arrayBuffer;
2920 }
2921 
JS_GetRawDataCapacity(napi_env env,napi_callback_info info)2922 napi_value NAPI_MessageSequence::JS_GetRawDataCapacity(napi_env env, napi_callback_info info)
2923 {
2924     size_t argc = 0;
2925     napi_value thisVar = nullptr;
2926     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
2927     NAPI_MessageSequence *napiSequence = nullptr;
2928     napi_unwrap(env, thisVar, (void **)&napiSequence);
2929     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
2930     uint32_t result = napiSequence->nativeParcel_->GetRawDataCapacity();
2931     napi_value napiValue;
2932     napi_create_uint32(env, result, &napiValue);
2933     return napiValue;
2934 }
2935 
Export(napi_env env,napi_value exports)2936 napi_value NAPI_MessageSequence::Export(napi_env env, napi_value exports)
2937 {
2938     const std::string className = "MessageSequence";
2939     napi_property_descriptor properties[] = {
2940         DECLARE_NAPI_STATIC_FUNCTION("create", NAPI_MessageSequence::JS_create),
2941         DECLARE_NAPI_FUNCTION("reclaim", NAPI_MessageSequence::JS_reclaim),
2942         DECLARE_NAPI_FUNCTION("writeRemoteObject", NAPI_MessageSequence::JS_writeRemoteObject),
2943         DECLARE_NAPI_FUNCTION("readRemoteObject", NAPI_MessageSequence::JS_readRemoteObject),
2944         DECLARE_NAPI_FUNCTION("writeInterfaceToken", NAPI_MessageSequence::JS_writeInterfaceToken),
2945         DECLARE_NAPI_FUNCTION("readInterfaceToken", NAPI_MessageSequence::JS_readInterfaceToken),
2946         DECLARE_NAPI_FUNCTION("getSize", NAPI_MessageSequence::JS_getSize),
2947         DECLARE_NAPI_FUNCTION("getCapacity", NAPI_MessageSequence::JS_getCapacity),
2948         DECLARE_NAPI_FUNCTION("setSize", NAPI_MessageSequence::JS_setSize),
2949         DECLARE_NAPI_FUNCTION("setCapacity", NAPI_MessageSequence::JS_setCapacity),
2950         DECLARE_NAPI_FUNCTION("getWritableBytes", NAPI_MessageSequence::JS_getWritableBytes),
2951         DECLARE_NAPI_FUNCTION("getReadableBytes", NAPI_MessageSequence::JS_getReadableBytes),
2952         DECLARE_NAPI_FUNCTION("getReadPosition", NAPI_MessageSequence::JS_getReadPosition),
2953         DECLARE_NAPI_FUNCTION("getWritePosition", NAPI_MessageSequence::JS_getWritePosition),
2954         DECLARE_NAPI_FUNCTION("rewindRead", NAPI_MessageSequence::JS_rewindRead),
2955         DECLARE_NAPI_FUNCTION("rewindWrite", NAPI_MessageSequence::JS_rewindWrite),
2956         DECLARE_NAPI_FUNCTION("writeNoException", NAPI_MessageSequence::JS_writeNoException),
2957         DECLARE_NAPI_FUNCTION("readException", NAPI_MessageSequence::JS_readException),
2958         DECLARE_NAPI_FUNCTION("writeByte", NAPI_MessageSequence::JS_writeByte),
2959         DECLARE_NAPI_FUNCTION("writeShort", NAPI_MessageSequence::JS_writeShort),
2960         DECLARE_NAPI_FUNCTION("writeInt", NAPI_MessageSequence::JS_writeInt),
2961         DECLARE_NAPI_FUNCTION("writeLong", NAPI_MessageSequence::JS_writeLong),
2962         DECLARE_NAPI_FUNCTION("writeFloat", NAPI_MessageSequence::JS_writeFloat),
2963         DECLARE_NAPI_FUNCTION("writeDouble", NAPI_MessageSequence::JS_writeDouble),
2964         DECLARE_NAPI_FUNCTION("writeBoolean", NAPI_MessageSequence::JS_writeBoolean),
2965         DECLARE_NAPI_FUNCTION("writeChar", NAPI_MessageSequence::JS_writeChar),
2966         DECLARE_NAPI_FUNCTION("writeString", NAPI_MessageSequence::JS_writeString),
2967         DECLARE_NAPI_FUNCTION("writeParcelable", NAPI_MessageSequence::JS_writeParcelable),
2968         DECLARE_NAPI_FUNCTION("writeByteArray", NAPI_MessageSequence::JS_writeByteArray),
2969         DECLARE_NAPI_FUNCTION("writeShortArray", NAPI_MessageSequence::JS_writeShortArray),
2970         DECLARE_NAPI_FUNCTION("writeIntArray", NAPI_MessageSequence::JS_writeIntArray),
2971         DECLARE_NAPI_FUNCTION("writeLongArray", NAPI_MessageSequence::JS_writeLongArray),
2972         DECLARE_NAPI_FUNCTION("writeFloatArray", NAPI_MessageSequence::JS_writeFloatArray),
2973         DECLARE_NAPI_FUNCTION("writeDoubleArray", NAPI_MessageSequence::JS_writeDoubleArray),
2974         DECLARE_NAPI_FUNCTION("writeBooleanArray", NAPI_MessageSequence::JS_writeBooleanArray),
2975         DECLARE_NAPI_FUNCTION("writeCharArray", NAPI_MessageSequence::JS_writeCharArray),
2976         DECLARE_NAPI_FUNCTION("writeStringArray", NAPI_MessageSequence::JS_writeStringArray),
2977         DECLARE_NAPI_FUNCTION("writeParcelableArray", NAPI_MessageSequence::JS_writeParcelableArray),
2978         DECLARE_NAPI_FUNCTION("writeRemoteObjectArray", NAPI_MessageSequence::JS_writeRemoteObjectArray),
2979         DECLARE_NAPI_FUNCTION("readByte", NAPI_MessageSequence::JS_readByte),
2980         DECLARE_NAPI_FUNCTION("readShort", NAPI_MessageSequence::JS_readShort),
2981         DECLARE_NAPI_FUNCTION("readInt", NAPI_MessageSequence::JS_readInt),
2982         DECLARE_NAPI_FUNCTION("readLong", NAPI_MessageSequence::JS_readLong),
2983         DECLARE_NAPI_FUNCTION("readFloat", NAPI_MessageSequence::JS_readFloat),
2984         DECLARE_NAPI_FUNCTION("readDouble", NAPI_MessageSequence::JS_readDouble),
2985         DECLARE_NAPI_FUNCTION("readBoolean", NAPI_MessageSequence::JS_readBoolean),
2986         DECLARE_NAPI_FUNCTION("readChar", NAPI_MessageSequence::JS_readChar),
2987         DECLARE_NAPI_FUNCTION("readString", NAPI_MessageSequence::JS_readString),
2988         DECLARE_NAPI_FUNCTION("readParcelable", NAPI_MessageSequence::JS_readParcelable),
2989         DECLARE_NAPI_FUNCTION("readByteArray", NAPI_MessageSequence::JS_readByteArray),
2990         DECLARE_NAPI_FUNCTION("readShortArray", NAPI_MessageSequence::JS_readShortArray),
2991         DECLARE_NAPI_FUNCTION("readIntArray", NAPI_MessageSequence::JS_readIntArray),
2992         DECLARE_NAPI_FUNCTION("readLongArray", NAPI_MessageSequence::JS_readLongArray),
2993         DECLARE_NAPI_FUNCTION("readFloatArray", NAPI_MessageSequence::JS_readFloatArray),
2994         DECLARE_NAPI_FUNCTION("readDoubleArray", NAPI_MessageSequence::JS_readDoubleArray),
2995         DECLARE_NAPI_FUNCTION("readBooleanArray", NAPI_MessageSequence::JS_readBooleanArray),
2996         DECLARE_NAPI_FUNCTION("readCharArray", NAPI_MessageSequence::JS_readCharArray),
2997         DECLARE_NAPI_FUNCTION("readStringArray", NAPI_MessageSequence::JS_readStringArray),
2998         DECLARE_NAPI_FUNCTION("readParcelableArray", NAPI_MessageSequence::JS_readParcelableArray),
2999         DECLARE_NAPI_FUNCTION("readRemoteObjectArray", NAPI_MessageSequence::JS_readRemoteObjectArray),
3000         DECLARE_NAPI_STATIC_FUNCTION("closeFileDescriptor", NAPI_MessageSequence::JS_CloseFileDescriptor),
3001         DECLARE_NAPI_STATIC_FUNCTION("dupFileDescriptor", NAPI_MessageSequence::JS_DupFileDescriptor),
3002         DECLARE_NAPI_FUNCTION("writeFileDescriptor", NAPI_MessageSequence::JS_WriteFileDescriptor),
3003         DECLARE_NAPI_FUNCTION("readFileDescriptor", NAPI_MessageSequence::JS_ReadFileDescriptor),
3004         DECLARE_NAPI_FUNCTION("containFileDescriptors", NAPI_MessageSequence::JS_ContainFileDescriptors),
3005         DECLARE_NAPI_FUNCTION("writeAshmem", NAPI_MessageSequence::JS_WriteAshmem),
3006         DECLARE_NAPI_FUNCTION("readAshmem", NAPI_MessageSequence::JS_ReadAshmem),
3007         DECLARE_NAPI_FUNCTION("getRawDataCapacity", NAPI_MessageSequence::JS_GetRawDataCapacity),
3008         DECLARE_NAPI_FUNCTION("writeRawData", NAPI_MessageSequence::JS_WriteRawData),
3009         DECLARE_NAPI_FUNCTION("readRawData", NAPI_MessageSequence::JS_ReadRawData),
3010         DECLARE_NAPI_FUNCTION("writeRawDataBuffer", NAPI_MessageSequence::JS_WriteRawDataBuffer),
3011         DECLARE_NAPI_FUNCTION("readRawDataBuffer", NAPI_MessageSequence::JS_ReadRawDataBuffer),
3012     };
3013     napi_value constructor = nullptr;
3014     napi_define_class(env, className.c_str(), className.length(), JS_constructor, nullptr,
3015         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
3016     NAPI_ASSERT(env, constructor != nullptr, "define js class MessageSequence failed");
3017     napi_status status = napi_set_named_property(env, exports, "MessageSequence", constructor);
3018     NAPI_ASSERT(env, status == napi_ok, "set property MessageSequence failed");
3019     napi_value global = nullptr;
3020     status = napi_get_global(env, &global);
3021     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
3022     status = napi_set_named_property(env, global, "IPCSequenceConstructor_", constructor);
3023     NAPI_ASSERT(env, status == napi_ok, "set message sequence constructor failed");
3024     return exports;
3025 }
3026 
JS_constructor(napi_env env,napi_callback_info info)3027 napi_value NAPI_MessageSequence::JS_constructor(napi_env env, napi_callback_info info)
3028 {
3029     napi_value thisVar = nullptr;
3030     size_t argc = 1;
3031     napi_value argv[ARGV_LENGTH_1] = {0};
3032     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
3033     NAPI_ASSERT(env, status == napi_ok, "napi get callback info failed");
3034     MessageParcel *parcel = nullptr;
3035     if (argc > 0) {
3036         napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&parcel);
3037         NAPI_ASSERT(env, parcel != nullptr, "parcel is null");
3038     }
3039     // new native parcel object
3040     auto messageSequence = new NAPI_MessageSequence(env, thisVar, parcel);
3041     // connect native object to js thisVar
3042     status = napi_wrap(
3043         env, thisVar, messageSequence,
3044         [](napi_env env, void *data, void *hint) {
3045             NAPI_MessageSequence *messageSequence = reinterpret_cast<NAPI_MessageSequence *>(data);
3046             if (!messageSequence->owner) {
3047                 delete messageSequence;
3048             }
3049         },
3050         nullptr, nullptr);
3051     NAPI_ASSERT(env, status == napi_ok, "napi wrap message parcel failed");
3052     return thisVar;
3053 }
3054 } // namespace OHOS
3055