• 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 "napi_rpc_common.h"
28 #include "string_ex.h"
29 
30 namespace OHOS {
31 using namespace OHOS::HiviewDFX;
32 NapiError NAPI_MessageSequence::napiErr;
33 
34 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_NAPI, "NAPI_MessageSequenceWrite" };
35 
NAPI_MessageSequence(napi_env env,napi_value thisVar,MessageParcel * parcel)36 NAPI_MessageSequence::NAPI_MessageSequence(napi_env env, napi_value thisVar, MessageParcel *parcel)
37 {
38     env_ = env;
39     maxCapacityToWrite_ = MAX_CAPACITY_TO_WRITE;
40     // do NOT reference js parcel here
41     if (parcel == nullptr) {
42         nativeParcel_ = std::make_shared<MessageParcel>();
43         owner = true;
44     } else {
45         nativeParcel_ = std::shared_ptr<MessageParcel>(parcel, release);
46         owner = false;
47     }
48 }
49 
~NAPI_MessageSequence()50 NAPI_MessageSequence::~NAPI_MessageSequence()
51 {
52     ZLOGD(LOG_LABEL, "NAPI_MessageSequence::Destructor");
53     nativeParcel_ = nullptr;
54     env_ = nullptr;
55 }
56 
release(MessageParcel * parcel)57 void NAPI_MessageSequence::release(MessageParcel *parcel)
58 {
59     ZLOGD(LOG_LABEL, "message parcel is created by others, do nothing");
60 }
61 
GetMessageParcel()62 std::shared_ptr<MessageParcel> NAPI_MessageSequence::GetMessageParcel()
63 {
64     return nativeParcel_;
65 }
66 
CreateTypeCodeEnum(napi_env env)67 napi_value CreateTypeCodeEnum(napi_env env)
68 {
69     napi_value enumValues[ENUM_TYPECODE_COUNT] = {nullptr};
70     napi_value enumObject = nullptr;
71     napi_create_object(env, &enumObject);
72     for (size_t i = 0; i < ENUM_TYPECODE_COUNT; i++) {
73         napi_create_int32(env, i, &enumValues[i]);
74     }
75 
76     napi_property_descriptor enumDesc[] = {
77         DECLARE_NAPI_PROPERTY("INT8_ARRAY", enumValues[INT8_ARRAY]),
78         DECLARE_NAPI_PROPERTY("UINT8_ARRAY", enumValues[UINT8_ARRAY]),
79         DECLARE_NAPI_PROPERTY("INT16_ARRAY", enumValues[INT16_ARRAY]),
80         DECLARE_NAPI_PROPERTY("UINT16_ARRAY", enumValues[UINT16_ARRAY]),
81         DECLARE_NAPI_PROPERTY("INT32_ARRAY", enumValues[INT32_ARRAY]),
82         DECLARE_NAPI_PROPERTY("UINT32_ARRAY", enumValues[UINT32_ARRAY]),
83         DECLARE_NAPI_PROPERTY("FLOAT32_ARRAY", enumValues[FLOAT32_ARRAY]),
84         DECLARE_NAPI_PROPERTY("FLOAT64_ARRAY", enumValues[FLOAT64_ARRAY]),
85         DECLARE_NAPI_PROPERTY("BIGINT64_ARRAY", enumValues[BIGINT64_ARRAY]),
86         DECLARE_NAPI_PROPERTY("BIGUINT64_ARRAY", enumValues[BIGUINT64_ARRAY]),
87     };
88     napi_define_properties(env, enumObject, sizeof(enumDesc) / sizeof(enumDesc[0]), enumDesc);
89     return enumObject;
90 }
91 
JS_writeByte(napi_env env,napi_callback_info info)92 napi_value NAPI_MessageSequence::JS_writeByte(napi_env env, napi_callback_info info)
93 {
94     size_t argc = 1;
95     napi_value argv[ARGV_LENGTH_1] = {0};
96     napi_value thisVar = nullptr;
97     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
98     if (argc != REQUIRED_ARGS_COUNT_1) {
99         ZLOGE(LOG_LABEL, "requires 1 parameter");
100         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
101     }
102 
103     napi_valuetype valueType = napi_null;
104     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
105     if (valueType != napi_number) {
106         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
107         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
108     }
109 
110     int32_t value = 0;
111     napi_get_value_int32(env, argv[ARGV_INDEX_0], &value);
112 
113     NAPI_MessageSequence *napiSequence = nullptr;
114     napi_unwrap(env, thisVar, (void **)&napiSequence);
115     if (napiSequence == nullptr) {
116         ZLOGE(LOG_LABEL, "napiSequence is null");
117         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
118     }
119     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
120     bool result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
121     if (!result) {
122         ZLOGE(LOG_LABEL, "write int8 failed");
123         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
124     }
125     napi_value napiValue = nullptr;
126     napi_get_undefined(env, &napiValue);
127     return napiValue;
128 }
129 
JS_writeShort(napi_env env,napi_callback_info info)130 napi_value NAPI_MessageSequence::JS_writeShort(napi_env env, napi_callback_info info)
131 {
132     size_t argc = 1;
133     napi_value argv[ARGV_LENGTH_1] = {0};
134     napi_value thisVar = nullptr;
135     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
136     if (argc != REQUIRED_ARGS_COUNT_1) {
137         ZLOGE(LOG_LABEL, "requires 1 parameter");
138         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
139     }
140 
141     napi_valuetype valueType = napi_null;
142     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
143     if (valueType != napi_number) {
144         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
145         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
146     }
147 
148     int32_t value = 0;
149     napi_get_value_int32(env, argv[ARGV_INDEX_0], &value);
150 
151     NAPI_MessageSequence *napiSequence = nullptr;
152     napi_unwrap(env, thisVar, (void **)&napiSequence);
153     if (napiSequence == nullptr) {
154         ZLOGE(LOG_LABEL, "napiSequence is null");
155         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
156     }
157     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
158     bool result = napiSequence->nativeParcel_->WriteInt16(static_cast<int16_t>(value));
159     if (!result) {
160         ZLOGE(LOG_LABEL, "write int16 failed");
161         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
162     }
163     napi_value napiValue = nullptr;
164     napi_get_undefined(env, &napiValue);
165     return napiValue;
166 }
167 
JS_writeInt(napi_env env,napi_callback_info info)168 napi_value NAPI_MessageSequence::JS_writeInt(napi_env env, napi_callback_info info)
169 {
170     size_t argc = 1;
171     napi_value argv[ARGV_LENGTH_1] = {0};
172     napi_value thisVar = nullptr;
173     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
174     if (argc != REQUIRED_ARGS_COUNT_1) {
175         ZLOGE(LOG_LABEL, "requires 1 parameter");
176         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
177     }
178 
179     napi_valuetype valueType = napi_null;
180     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
181     if (valueType != napi_number) {
182         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
183         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
184     }
185 
186     int32_t value = 0;
187     napi_get_value_int32(env, argv[ARGV_INDEX_0], &value);
188 
189     NAPI_MessageSequence *napiSequence = nullptr;
190     napi_unwrap(env, thisVar, (void **)&napiSequence);
191     if (napiSequence == nullptr) {
192         ZLOGE(LOG_LABEL, "napiSequence is null");
193         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
194     }
195     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
196     bool result = napiSequence->nativeParcel_->WriteInt32(value);
197     if (!result) {
198         ZLOGE(LOG_LABEL, "write int32 failed");
199         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
200     }
201     napi_value napiValue = nullptr;
202     napi_get_undefined(env, &napiValue);
203     return napiValue;
204 }
205 
JS_writeLong(napi_env env,napi_callback_info info)206 napi_value NAPI_MessageSequence::JS_writeLong(napi_env env, napi_callback_info info)
207 {
208     size_t argc = 1;
209     napi_value argv[ARGV_LENGTH_1] = {0};
210     napi_value thisVar = nullptr;
211     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
212     if (argc != REQUIRED_ARGS_COUNT_1) {
213         ZLOGE(LOG_LABEL, "requires 1 parameter");
214         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
215     }
216 
217     napi_valuetype valueType = napi_null;
218     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
219     if (valueType != napi_number) {
220         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
221         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
222     }
223 
224     int64_t value = 0;
225     napi_get_value_int64(env, argv[ARGV_INDEX_0], &value);
226 
227     NAPI_MessageSequence *napiSequence = nullptr;
228     napi_unwrap(env, thisVar, (void **)&napiSequence);
229     if (napiSequence == nullptr) {
230         ZLOGE(LOG_LABEL, "napiSequence is null");
231         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
232     }
233     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_64, napiSequence);
234     bool result = napiSequence->nativeParcel_->WriteInt64(value);
235     if (!result) {
236         ZLOGE(LOG_LABEL, "write int64 failed");
237         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
238     }
239     napi_value napiValue = nullptr;
240     napi_get_undefined(env, &napiValue);
241     return napiValue;
242 }
243 
JS_writeFloat(napi_env env,napi_callback_info info)244 napi_value NAPI_MessageSequence::JS_writeFloat(napi_env env, napi_callback_info info)
245 {
246     size_t argc = 1;
247     napi_value argv[ARGV_LENGTH_1] = {0};
248     napi_value thisVar = nullptr;
249     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
250     if (argc != REQUIRED_ARGS_COUNT_1) {
251         ZLOGE(LOG_LABEL, "requires 1 parameter");
252         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
253     }
254 
255     napi_valuetype valueType = napi_null;
256     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
257     if (valueType != napi_number) {
258         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
259         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
260     }
261 
262     double value = 0;
263     napi_get_value_double(env, argv[ARGV_INDEX_0], &value);
264 
265     NAPI_MessageSequence *napiSequence = nullptr;
266     napi_unwrap(env, thisVar, (void **)&napiSequence);
267     if (napiSequence == nullptr) {
268         ZLOGE(LOG_LABEL, "napiSequence is null");
269         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
270     }
271     CHECK_WRITE_CAPACITY(env, sizeof(double), napiSequence);
272     bool result = napiSequence->nativeParcel_->WriteDouble(value);
273     if (!result) {
274         ZLOGE(LOG_LABEL, "write double failed");
275         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
276     }
277     napi_value napiValue = nullptr;
278     napi_get_undefined(env, &napiValue);
279     return napiValue;
280 }
281 
JS_writeDouble(napi_env env,napi_callback_info info)282 napi_value NAPI_MessageSequence::JS_writeDouble(napi_env env, napi_callback_info info)
283 {
284     // This function implementation is the same as JS_writeFloat
285     return NAPI_MessageSequence::JS_writeFloat(env, info);
286 }
287 
JS_writeBoolean(napi_env env,napi_callback_info info)288 napi_value NAPI_MessageSequence::JS_writeBoolean(napi_env env, napi_callback_info info)
289 {
290     size_t argc = 1;
291     napi_value argv[ARGV_LENGTH_1] = {0};
292     napi_value thisVar = nullptr;
293     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
294     if (argc != REQUIRED_ARGS_COUNT_1) {
295         ZLOGE(LOG_LABEL, "requires 1 parameter");
296         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
297     }
298 
299     napi_valuetype valueType = napi_null;
300     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
301     if (valueType != napi_boolean) {
302         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
303         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
304     }
305 
306     bool value = false;
307     napi_get_value_bool(env, argv[ARGV_INDEX_0], &value);
308 
309     NAPI_MessageSequence *napiSequence = nullptr;
310     napi_unwrap(env, thisVar, (void **)&napiSequence);
311     if (napiSequence == nullptr) {
312         ZLOGE(LOG_LABEL, "napiSequence is null");
313         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
314     }
315     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
316     bool result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
317     if (!result) {
318         ZLOGE(LOG_LABEL, "write int8 failed");
319         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
320     }
321     napi_value napiValue = nullptr;
322     napi_get_undefined(env, &napiValue);
323     return napiValue;
324 }
325 
JS_writeChar(napi_env env,napi_callback_info info)326 napi_value NAPI_MessageSequence::JS_writeChar(napi_env env, napi_callback_info info)
327 {
328     size_t argc = 1;
329     napi_value argv[ARGV_LENGTH_1] = {0};
330     napi_value thisVar = nullptr;
331     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
332     if (argc != REQUIRED_ARGS_COUNT_1) {
333         ZLOGE(LOG_LABEL, "requires 1 parameter");
334         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
335     }
336 
337     napi_valuetype valueType = napi_null;
338     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
339     if (valueType != napi_number) {
340         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
341         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
342     }
343 
344     uint32_t value = 0;
345     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
346 
347     NAPI_MessageSequence *napiSequence = nullptr;
348     napi_unwrap(env, thisVar, (void **)&napiSequence);
349     if (napiSequence == nullptr) {
350         ZLOGE(LOG_LABEL, "napiSequence is null");
351         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
352     }
353     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32, napiSequence);
354     bool result = napiSequence->nativeParcel_->WriteUint8(static_cast<uint8_t>(value));
355     if (!result) {
356         ZLOGE(LOG_LABEL, "write uint8 failed");
357         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
358     }
359     napi_value napiValue = nullptr;
360     napi_get_undefined(env, &napiValue);
361     return napiValue;
362 }
363 
JS_writeByteArray(napi_env env,napi_callback_info info)364 napi_value NAPI_MessageSequence::JS_writeByteArray(napi_env env, napi_callback_info info)
365 {
366     size_t argc = 1;
367     napi_value argv[ARGV_LENGTH_1] = {0};
368     napi_value thisVar = nullptr;
369     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
370     uint32_t arrayLength = 0;
371     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
372     if (checkArgsResult == nullptr) {
373         ZLOGE(LOG_LABEL, "checkArgsResult is null");
374         return checkArgsResult;
375     }
376 
377     NAPI_MessageSequence *napiSequence = nullptr;
378     napi_unwrap(env, thisVar, (void **)&napiSequence);
379     if (napiSequence == nullptr) {
380         ZLOGE(LOG_LABEL, "napiSequence is null");
381         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
382     }
383 
384     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_8 * (arrayLength + 1), napiSequence);
385     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
386     napiSequence->nativeParcel_->WriteUint32(arrayLength);
387     bool result = false;
388     for (size_t i = 0; i < arrayLength; i++) {
389         bool hasElement = false;
390         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
391         if (!hasElement) {
392             ZLOGE(LOG_LABEL, "parameter check error");
393             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
394         }
395 
396         napi_value element = nullptr;
397         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
398         napi_valuetype valueType;
399         napi_typeof(env, element, &valueType);
400         if (valueType != napi_number) {
401             ZLOGE(LOG_LABEL, "type mismatch. valueType %{public}d is not equal %{public}d", valueType, napi_number);
402             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
403         }
404 
405         int32_t value = 0;
406         napi_get_value_int32(env, element, &value);
407         result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
408         if (!result) {
409             napiSequence->nativeParcel_->RewindWrite(pos);
410             ZLOGE(LOG_LABEL, "write int8 failed");
411             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
412         }
413     }
414 
415     napi_value napiValue = nullptr;
416     napi_get_undefined(env, &napiValue);
417     return napiValue;
418 }
419 
JS_checkWriteArrayArgs(napi_env env,size_t argc,napi_value * argv,uint32_t & arrayLength)420 napi_value NAPI_MessageSequence::JS_checkWriteArrayArgs(napi_env env,
421                                                         size_t argc,
422                                                         napi_value* argv,
423                                                         uint32_t &arrayLength)
424 {
425     if (argv == nullptr) {
426         ZLOGE(LOG_LABEL, "argv is nullptr");
427         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
428     }
429     if (argc != REQUIRED_ARGS_COUNT_1) {
430         ZLOGE(LOG_LABEL, "requires 1 parameter");
431         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
432     }
433 
434     bool isArray = false;
435     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
436     if (!isArray) {
437         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
438         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
439     }
440     napi_get_array_length(env, argv[ARGV_INDEX_0], &arrayLength);
441 
442     napi_value napiValue = nullptr;
443     napi_get_undefined(env, &napiValue);
444     return napiValue;
445 }
446 
JS_writeShortArray(napi_env env,napi_callback_info info)447 napi_value NAPI_MessageSequence::JS_writeShortArray(napi_env env, napi_callback_info info)
448 {
449     size_t argc = 1;
450     napi_value argv[ARGV_LENGTH_1] = {0};
451     napi_value thisVar = nullptr;
452     void *data = nullptr;
453     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
454     uint32_t arrayLength = 0;
455     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
456     if (checkArgsResult == nullptr) {
457         ZLOGE(LOG_LABEL, "checkArgsResult is null");
458         return checkArgsResult;
459     }
460 
461     NAPI_MessageSequence *napiSequence = nullptr;
462     napi_unwrap(env, thisVar, (void **)&napiSequence);
463     if (napiSequence == nullptr) {
464         ZLOGE(LOG_LABEL, "napiSequence is null");
465         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
466     }
467 
468     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
469     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
470     napiSequence->nativeParcel_->WriteUint32(arrayLength);
471     bool result = false;
472     for (size_t i = 0; i < arrayLength; i++) {
473         bool hasElement = false;
474         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
475         if (!hasElement) {
476             ZLOGE(LOG_LABEL, "parameter check error");
477             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
478         }
479 
480         napi_value element = nullptr;
481         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
482         napi_valuetype valueType;
483         napi_typeof(env, element, &valueType);
484         if (valueType != napi_number) {
485             ZLOGE(LOG_LABEL, "type mismatch. valueType %{public}d is not equal %{public}d", valueType, napi_number);
486             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
487         }
488 
489         int32_t value = 0;
490         napi_get_value_int32(env, element, &value);
491         result = napiSequence->nativeParcel_->WriteInt16(static_cast<int16_t>(value));
492         if (!result) {
493             napiSequence->nativeParcel_->RewindWrite(pos);
494             ZLOGE(LOG_LABEL, "write int16 failed");
495             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
496         }
497     }
498 
499     napi_value napiValue = nullptr;
500     napi_get_undefined(env, &napiValue);
501     return napiValue;
502 }
503 
JS_writeIntArray(napi_env env,napi_callback_info info)504 napi_value NAPI_MessageSequence::JS_writeIntArray(napi_env env, napi_callback_info info)
505 {
506     size_t argc = 1;
507     napi_value argv[ARGV_LENGTH_1] = {0};
508     napi_value thisVar = nullptr;
509     void *data = nullptr;
510     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
511     uint32_t arrayLength = 0;
512     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
513     if (checkArgsResult == nullptr) {
514         ZLOGE(LOG_LABEL, "checkArgsResult is null");
515         return checkArgsResult;
516     }
517 
518     NAPI_MessageSequence *napiSequence = nullptr;
519     napi_unwrap(env, thisVar, (void **)&napiSequence);
520     if (napiSequence == nullptr) {
521         ZLOGE(LOG_LABEL, "napiSequence is null");
522         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
523     }
524 
525     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
526     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
527     napiSequence->nativeParcel_->WriteUint32(arrayLength);
528     bool result = false;
529     for (size_t i = 0; i < arrayLength; i++) {
530         bool hasElement = false;
531         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
532         if (!hasElement) {
533             ZLOGE(LOG_LABEL, "parameter check error");
534             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
535         }
536 
537         napi_value element = nullptr;
538         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
539         napi_valuetype valueType;
540         napi_typeof(env, element, &valueType);
541         if (valueType != napi_number) {
542             ZLOGE(LOG_LABEL, "type mismatch. valueType %{public}d is not equal %{public}d", valueType, napi_number);
543             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
544         }
545 
546         int32_t value = 0;
547         napi_get_value_int32(env, element, &value);
548         result = napiSequence->nativeParcel_->WriteInt32(value);
549         if (!result) {
550             napiSequence->nativeParcel_->RewindWrite(pos);
551             ZLOGE(LOG_LABEL, "write int32 failed");
552             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
553         }
554     }
555 
556     napi_value napiValue = nullptr;
557     napi_get_undefined(env, &napiValue);
558     return napiValue;
559 }
560 
JS_writeLongArray(napi_env env,napi_callback_info info)561 napi_value NAPI_MessageSequence::JS_writeLongArray(napi_env env, napi_callback_info info)
562 {
563     size_t argc = 1;
564     napi_value argv[ARGV_LENGTH_1] = {0};
565     napi_value thisVar = nullptr;
566     void *data = nullptr;
567     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
568     uint32_t arrayLength = 0;
569     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
570     if (checkArgsResult == nullptr) {
571         ZLOGE(LOG_LABEL, "checkArgsResult is null");
572         return checkArgsResult;
573     }
574 
575     NAPI_MessageSequence *napiSequence = nullptr;
576     napi_unwrap(env, thisVar, (void **)&napiSequence);
577     if (napiSequence == nullptr) {
578         ZLOGE(LOG_LABEL, "napiSequence is null");
579         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
580     }
581 
582     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 + BYTE_SIZE_64 * arrayLength, napiSequence);
583     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
584     napiSequence->nativeParcel_->WriteUint32(arrayLength);
585     bool result = false;
586     for (size_t i = 0; i < arrayLength; i++) {
587         bool hasElement = false;
588         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
589         if (!hasElement) {
590             ZLOGE(LOG_LABEL, "parameter check error");
591             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
592         }
593 
594         napi_value element = nullptr;
595         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
596         napi_valuetype valueType;
597         napi_typeof(env, element, &valueType);
598         if (valueType != napi_number) {
599             ZLOGE(LOG_LABEL, "type mismatch. valueType %{public}d is not equal %{public}d", valueType, napi_number);
600             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
601         }
602 
603         int64_t value = 0;
604         napi_get_value_int64(env, element, &value);
605         result = napiSequence->nativeParcel_->WriteInt64(value);
606         if (!result) {
607             napiSequence->nativeParcel_->RewindWrite(pos);
608             ZLOGE(LOG_LABEL, "write int64 failed");
609             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
610         }
611     }
612 
613     napi_value napiValue = nullptr;
614     napi_get_undefined(env, &napiValue);
615     return napiValue;
616 }
617 
JS_writeFloatArray(napi_env env,napi_callback_info info)618 napi_value NAPI_MessageSequence::JS_writeFloatArray(napi_env env, napi_callback_info info)
619 {
620     size_t argc = 1;
621     napi_value argv[ARGV_LENGTH_1] = {0};
622     napi_value thisVar = nullptr;
623     void *data = nullptr;
624     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
625     uint32_t arrayLength = 0;
626     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
627     if (checkArgsResult == nullptr) {
628         ZLOGE(LOG_LABEL, "checkArgsResult is null");
629         return checkArgsResult;
630     }
631 
632     NAPI_MessageSequence *napiSequence = nullptr;
633     napi_unwrap(env, thisVar, (void **)&napiSequence);
634     if (napiSequence == nullptr) {
635         ZLOGE(LOG_LABEL, "napiSequence is null");
636         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
637     }
638 
639     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 + sizeof(double) * arrayLength, napiSequence);
640     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
641     napiSequence->nativeParcel_->WriteUint32(arrayLength);
642     bool result = false;
643     for (size_t i = 0; i < arrayLength; i++) {
644         bool hasElement = false;
645         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
646         if (!hasElement) {
647             ZLOGE(LOG_LABEL, "parameter check error");
648             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
649         }
650 
651         napi_value element = nullptr;
652         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
653         napi_valuetype valueType;
654         napi_typeof(env, element, &valueType);
655         if (valueType != napi_number) {
656             ZLOGE(LOG_LABEL, "type mismatch. valueType %{public}d is not equal %{public}d", valueType, napi_number);
657             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
658         }
659 
660         double value = 0;
661         napi_get_value_double(env, element, &value);
662         result = napiSequence->nativeParcel_->WriteDouble(value);
663         if (!result) {
664             napiSequence->nativeParcel_->RewindWrite(pos);
665             ZLOGE(LOG_LABEL, "write double failed");
666             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
667         }
668     }
669 
670     napi_value napiValue = nullptr;
671     napi_get_undefined(env, &napiValue);
672     return napiValue;
673 }
674 
JS_writeDoubleArray(napi_env env,napi_callback_info info)675 napi_value NAPI_MessageSequence::JS_writeDoubleArray(napi_env env, napi_callback_info info)
676 {
677     size_t argc = 1;
678     napi_value argv[ARGV_LENGTH_1] = {0};
679     napi_value thisVar = nullptr;
680     void *data = nullptr;
681     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
682     uint32_t arrayLength = 0;
683     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
684     if (checkArgsResult == nullptr) {
685         ZLOGE(LOG_LABEL, "checkArgsResult is null");
686         return checkArgsResult;
687     }
688 
689     NAPI_MessageSequence *napiSequence = nullptr;
690     napi_unwrap(env, thisVar, (void **)&napiSequence);
691     if (napiSequence == nullptr) {
692         ZLOGE(LOG_LABEL, "napiSequence is null");
693         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
694     }
695 
696     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 + sizeof(double) * arrayLength, napiSequence);
697     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
698     napiSequence->nativeParcel_->WriteUint32(arrayLength);
699     bool result = false;
700     for (size_t i = 0; i < arrayLength; i++) {
701         bool hasElement = false;
702         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
703         if (!hasElement) {
704             ZLOGE(LOG_LABEL, "parameter check error");
705             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
706         }
707 
708         napi_value element = nullptr;
709         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
710         napi_valuetype valueType;
711         napi_typeof(env, element, &valueType);
712         if (valueType != napi_number) {
713             ZLOGE(LOG_LABEL, "type mismatch. valueType %{public}d is not equal %{public}d", valueType, napi_number);
714             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
715         }
716 
717         double value = 0;
718         napi_get_value_double(env, element, &value);
719         result = napiSequence->nativeParcel_->WriteDouble(value);
720         if (!result) {
721             napiSequence->nativeParcel_->RewindWrite(pos);
722             ZLOGE(LOG_LABEL, "write double failed");
723             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
724         }
725     }
726 
727     napi_value napiValue = nullptr;
728     napi_get_undefined(env, &napiValue);
729     return napiValue;
730 }
731 
JS_writeBooleanArray(napi_env env,napi_callback_info info)732 napi_value NAPI_MessageSequence::JS_writeBooleanArray(napi_env env, napi_callback_info info)
733 {
734     size_t argc = 1;
735     napi_value argv[ARGV_LENGTH_1] = {0};
736     napi_value thisVar = nullptr;
737     void *data = nullptr;
738     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
739     uint32_t arrayLength = 0;
740     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
741     if (checkArgsResult == nullptr) {
742         ZLOGE(LOG_LABEL, "checkArgsResult is null");
743         return checkArgsResult;
744     }
745 
746     NAPI_MessageSequence *napiSequence = nullptr;
747     napi_unwrap(env, thisVar, (void **)&napiSequence);
748     if (napiSequence == nullptr) {
749         ZLOGE(LOG_LABEL, "napiSequence is null");
750         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
751     }
752 
753     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
754     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
755     napiSequence->nativeParcel_->WriteUint32(arrayLength);
756     bool result = false;
757     for (size_t i = 0; i < arrayLength; i++) {
758         bool hasElement = false;
759         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
760         if (!hasElement) {
761             ZLOGE(LOG_LABEL, "parameter check error");
762             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
763         }
764 
765         napi_value element = nullptr;
766         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
767 
768         bool value = false;
769         napi_get_value_bool(env, element, &value);
770         result = napiSequence->nativeParcel_->WriteInt8(static_cast<int8_t>(value));
771         if (!result) {
772             napiSequence->nativeParcel_->RewindWrite(pos);
773             ZLOGE(LOG_LABEL, "write int8 failed");
774             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
775         }
776     }
777 
778     napi_value napiValue = nullptr;
779     napi_get_undefined(env, &napiValue);
780     return napiValue;
781 }
782 
JS_writeCharArray(napi_env env,napi_callback_info info)783 napi_value NAPI_MessageSequence::JS_writeCharArray(napi_env env, napi_callback_info info)
784 {
785     size_t argc = 1;
786     napi_value argv[ARGV_LENGTH_1] = {0};
787     napi_value thisVar = nullptr;
788     void *data = nullptr;
789     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
790     uint32_t arrayLength = 0;
791     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
792     if (checkArgsResult == nullptr) {
793         ZLOGE(LOG_LABEL, "checkArgsResult is null");
794         return checkArgsResult;
795     }
796 
797     NAPI_MessageSequence *napiSequence = nullptr;
798     napi_unwrap(env, thisVar, (void **)&napiSequence);
799     if (napiSequence == nullptr) {
800         ZLOGE(LOG_LABEL, "napiSequence is null");
801         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
802     }
803 
804     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * (arrayLength + 1), napiSequence);
805     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
806     napiSequence->nativeParcel_->WriteUint32(arrayLength);
807     bool result = false;
808     for (size_t i = 0; i < arrayLength; i++) {
809         bool hasElement = false;
810         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
811         if (!hasElement) {
812             ZLOGE(LOG_LABEL, "parameter check error");
813             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
814         }
815 
816         napi_value element = nullptr;
817         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
818 
819         uint32_t value = 0;
820         napi_get_value_uint32(env, element, &value);
821         result = napiSequence->nativeParcel_->WriteUint8(static_cast<uint8_t>(value));
822         if (!result) {
823             napiSequence->nativeParcel_->RewindWrite(pos);
824             ZLOGE(LOG_LABEL, "write uint8 failed");
825             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
826         }
827     }
828 
829     napi_value napiValue = nullptr;
830     napi_get_undefined(env, &napiValue);
831     return napiValue;
832 }
833 
JS_writeString(napi_env env,napi_callback_info info)834 napi_value NAPI_MessageSequence::JS_writeString(napi_env env, napi_callback_info info)
835 {
836     size_t argc = 1;
837     napi_value argv[ARGV_LENGTH_1] = {0};
838     napi_value thisVar = nullptr;
839     void *data = nullptr;
840     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
841     if (argc != 1) {
842         ZLOGE(LOG_LABEL, "requires 1 parameters");
843         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
844     }
845     napi_valuetype valueType = napi_null;
846     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
847     if (valueType != napi_string) {
848         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
849         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
850     }
851     size_t bufferSize = 0;
852     size_t maxLen = MAX_BYTES_LENGTH;
853     napi_get_value_string_utf16(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
854     if (bufferSize >= maxLen) {
855         ZLOGE(LOG_LABEL, "string length too large");
856         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
857     }
858     char16_t stringValue[bufferSize + 1];
859     size_t jsStringLength = 0;
860     napi_get_value_string_utf16(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
861     if (jsStringLength != bufferSize) {
862         ZLOGE(LOG_LABEL, "string length wrong");
863         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
864     }
865 
866     NAPI_MessageSequence *napiSequence = nullptr;
867     napi_unwrap(env, thisVar, (void **)&napiSequence);
868     if (napiSequence == nullptr) {
869         ZLOGE(LOG_LABEL, "napiSequence is null");
870         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
871     }
872 
873     CHECK_WRITE_CAPACITY(env, BYTE_SIZE_32 * bufferSize, napiSequence);
874     bool result = napiSequence->nativeParcel_->WriteString16(stringValue);
875     if (!result) {
876         ZLOGE(LOG_LABEL, "write string16 failed");
877         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
878     }
879     napi_value napiValue = nullptr;
880     napi_get_undefined(env, &napiValue);
881     return napiValue;
882 }
883 
JS_checkWriteStringArrayElement(napi_env env,napi_value * argv,size_t & index,size_t & bufferSize,napi_value & element)884 napi_value NAPI_MessageSequence::JS_checkWriteStringArrayElement(napi_env env,
885                                                                  napi_value* argv,
886                                                                  size_t &index,
887                                                                  size_t &bufferSize,
888                                                                  napi_value &element)
889 {
890     if (argv == nullptr) {
891         ZLOGE(LOG_LABEL, "argv is nullptr");
892         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
893     }
894     bool hasElement = false;
895     size_t maxSize = MAX_BYTES_LENGTH;
896     napi_has_element(env, argv[ARGV_INDEX_0], index, &hasElement);
897     if (!hasElement) {
898         ZLOGE(LOG_LABEL, "parameter check error");
899         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
900     }
901 
902     napi_get_element(env, argv[ARGV_INDEX_0], index, &element);
903     napi_valuetype valuetype;
904     napi_typeof(env, element, &valuetype);
905     if (valuetype != napi_string) {
906         ZLOGE(LOG_LABEL, "Parameter type error");
907         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
908     }
909 
910     napi_get_value_string_utf16(env, element, nullptr, 0, &bufferSize);
911     if (bufferSize >= maxSize) {
912         ZLOGE(LOG_LABEL, "string length too large");
913         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
914     }
915     napi_value napiValue = nullptr;
916     napi_get_undefined(env, &napiValue);
917     return napiValue;
918 }
919 
JS_writeStringArray(napi_env env,napi_callback_info info)920 napi_value NAPI_MessageSequence::JS_writeStringArray(napi_env env, napi_callback_info info)
921 {
922     size_t argc = 1;
923     napi_value argv[ARGV_LENGTH_1] = {0};
924     napi_value thisVar = nullptr;
925     void *data = nullptr;
926     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
927     uint32_t arrayLength = 0;
928     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
929     if (checkArgsResult == nullptr) {
930         ZLOGE(LOG_LABEL, "checkArgsResult is null");
931         return checkArgsResult;
932     }
933 
934     NAPI_MessageSequence *napiSequence = nullptr;
935     napi_unwrap(env, thisVar, (void **)&napiSequence);
936     if (napiSequence == nullptr) {
937         ZLOGE(LOG_LABEL, "napiSequence is null");
938         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
939     }
940 
941     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
942     napiSequence->nativeParcel_->WriteUint32(arrayLength);
943     bool result = false;
944     for (size_t i = 0; i < arrayLength; i++) {
945         size_t bufferSize = 0;
946         napi_value element = nullptr;
947         napi_value checkElementResult = JS_checkWriteStringArrayElement(env, argv, i, bufferSize, element);
948         if (checkElementResult == nullptr) {
949             return checkElementResult;
950         }
951         char16_t stringValue[bufferSize + 1];
952         size_t jsStringLength = 0;
953         napi_get_value_string_utf16(env, element, stringValue, bufferSize + 1, &jsStringLength);
954         if (jsStringLength != bufferSize) {
955             ZLOGE(LOG_LABEL, "string length wrong");
956             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
957         }
958 
959         REWIND_IF_WRITE_CHECK_FAIL(env, BYTE_SIZE_32 * bufferSize, pos, napiSequence);
960         result = napiSequence->nativeParcel_->WriteString16(stringValue);
961         if (!result) {
962             napiSequence->nativeParcel_->RewindWrite(pos);
963             ZLOGE(LOG_LABEL, "write string16 failed");
964             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
965         }
966     }
967 
968     napi_value napiValue = nullptr;
969     napi_get_undefined(env, &napiValue);
970     return napiValue;
971 }
972 
JS_writeParcelable(napi_env env,napi_callback_info info)973 napi_value NAPI_MessageSequence::JS_writeParcelable(napi_env env, napi_callback_info info)
974 {
975     napi_value result = nullptr;
976     napi_get_undefined(env, &result);
977 
978     size_t argc = 1;
979     napi_value argv[ARGV_LENGTH_1] = {0};
980     napi_value thisVar = nullptr;
981     void *data = nullptr;
982     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
983     if (argc != 1) {
984         ZLOGE(LOG_LABEL, "requires 1 parameters");
985         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
986     }
987 
988     NAPI_MessageSequence *napiSequence = nullptr;
989     napi_unwrap(env, thisVar, (void **)&napiSequence);
990     if (napiSequence == nullptr) {
991         ZLOGE(LOG_LABEL, "napiSequence is null");
992         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
993     }
994 
995     napi_valuetype valueType = napi_null;
996     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
997     if (valueType == napi_null || valueType == napi_undefined) {
998         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
999         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1000     }
1001     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1002     napiSequence->nativeParcel_->WriteInt32(1);
1003     napi_value propKey = nullptr;
1004     const char *propKeyStr = "marshalling";
1005     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
1006     napi_value prop = nullptr;
1007     napi_get_property(env, argv[ARGV_INDEX_0], propKey, &prop);
1008 
1009     napi_value funcArg[1] = { thisVar };
1010     napi_value callResult = nullptr;
1011     napi_call_function(env, argv[ARGV_INDEX_0], prop, 1, funcArg, &callResult);
1012     bool isPendingException = false;
1013     napi_is_exception_pending(env, &isPendingException);
1014     if (isPendingException) {
1015         napi_value lastException = nullptr;
1016         ZLOGE(LOG_LABEL, "call marshalling failed");
1017         napi_get_and_clear_last_exception(env, &lastException);
1018         napiSequence->nativeParcel_->RewindWrite(pos);
1019         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1020     }
1021     napi_typeof(env, callResult, &valueType);
1022     if (callResult != nullptr && valueType != napi_undefined) {
1023         return callResult;
1024     }
1025     ZLOGE(LOG_LABEL, "call marshalling failed");
1026     napiSequence->nativeParcel_->RewindWrite(pos);
1027     return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1028 }
1029 
JS_writeParcelableArrayCallJsFunc(napi_env env,napi_value & element,napi_value & thisVar)1030 napi_value NAPI_MessageSequence::JS_writeParcelableArrayCallJsFunc(napi_env env,
1031     napi_value &element, napi_value &thisVar)
1032 {
1033     napi_value propKey = nullptr;
1034     const char *propKeyStr = "marshalling";
1035     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
1036     napi_value prop = nullptr;
1037     napi_get_property(env, element, propKey, &prop);
1038 
1039     napi_value funcArg[1] = { thisVar };
1040     napi_value callResult = nullptr;
1041     napi_call_function(env, element, prop, 1, funcArg, &callResult);
1042     napi_valuetype valueType = napi_null;
1043     napi_typeof(env, callResult, &valueType);
1044     if (callResult == nullptr || valueType == napi_undefined) {
1045         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1046     }
1047 
1048     napi_value retValue = nullptr;
1049     napi_get_undefined(env, &retValue);
1050     return retValue;
1051 }
1052 
JS_writeParcelableArray(napi_env env,napi_callback_info info)1053 napi_value NAPI_MessageSequence::JS_writeParcelableArray(napi_env env, napi_callback_info info)
1054 {
1055     size_t argc = 1;
1056     napi_value argv[ARGV_LENGTH_1] = {0};
1057     napi_value thisVar = nullptr;
1058     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1059     uint32_t arrayLength = 0;
1060     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
1061     if (checkArgsResult == nullptr) {
1062         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1063         return checkArgsResult;
1064     }
1065 
1066     NAPI_MessageSequence *napiSequence = nullptr;
1067     napi_unwrap(env, thisVar, (void **)&napiSequence);
1068     if (napiSequence == nullptr) {
1069         ZLOGE(LOG_LABEL, "napiSequence is null");
1070         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1071     }
1072 
1073     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1074     if (!(napiSequence->nativeParcel_->WriteUint32(arrayLength))) {
1075         ZLOGE(LOG_LABEL, "write uint32 failed");
1076         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1077     }
1078     for (size_t i = 0; i < arrayLength; i++) {
1079         bool hasElement = false;
1080         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
1081         if (!hasElement) {
1082             ZLOGE(LOG_LABEL, "parameter check error");
1083             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1084         }
1085 
1086         napi_value element = nullptr;
1087         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
1088         napi_valuetype valueType = napi_null;
1089         napi_typeof(env, element, &valueType);
1090         if (valueType == napi_null || valueType == napi_undefined) {
1091             napiSequence->nativeParcel_->WriteInt32(0);
1092             continue;
1093         } else {
1094             napiSequence->nativeParcel_->WriteInt32(1);
1095         }
1096         napi_value callResult = JS_writeParcelableArrayCallJsFunc(env, element, thisVar);
1097         if (callResult == nullptr) {
1098             ZLOGE(LOG_LABEL, "call marshalling failed, element index:%{public}zu", i);
1099             napiSequence->nativeParcel_->RewindWrite(pos);
1100             return callResult;
1101         }
1102     }
1103     napi_value retValue = nullptr;
1104     napi_get_undefined(env, &retValue);
1105     return retValue;
1106 }
1107 
JS_writeRemoteObjectArray(napi_env env,napi_callback_info info)1108 napi_value NAPI_MessageSequence::JS_writeRemoteObjectArray(napi_env env, napi_callback_info info)
1109 {
1110     size_t argc = 1;
1111     napi_value argv[ARGV_LENGTH_1] = {0};
1112     napi_value thisVar = nullptr;
1113     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1114     uint32_t arrayLength = 0;
1115     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
1116     if (checkArgsResult == nullptr) {
1117         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1118         return checkArgsResult;
1119     }
1120 
1121     NAPI_MessageSequence *napiSequence = nullptr;
1122     napi_unwrap(env, thisVar, (void **)&napiSequence);
1123     if (napiSequence == nullptr) {
1124         ZLOGE(LOG_LABEL, "napiSequence is null");
1125         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1126     }
1127     napi_valuetype valueType = napi_null;
1128     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1129     if (valueType == napi_null || valueType == napi_undefined) {
1130         napiSequence->nativeParcel_->WriteInt32(-1);
1131         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1132         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1133     }
1134     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1135     bool result =  napiSequence->nativeParcel_->WriteInt32(arrayLength);
1136     for (size_t i = 0; i < arrayLength; i++) {
1137         bool hasElement = false;
1138         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
1139         if (!hasElement) {
1140             ZLOGE(LOG_LABEL, "parameter check error");
1141             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1142         }
1143         napi_value element = nullptr;
1144         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
1145         sptr<IRemoteObject> remoteObject = NAPI_ohos_rpc_getNativeRemoteObject(env, element);
1146         if (remoteObject == nullptr) {
1147             ZLOGE(LOG_LABEL, "parameter check error");
1148             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1149         }
1150         result = napiSequence->nativeParcel_->WriteRemoteObject(remoteObject);
1151         if (!result) {
1152             napiSequence->nativeParcel_->RewindWrite(pos);
1153             ZLOGE(LOG_LABEL, "write string16 failed");
1154             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1155         }
1156     }
1157     napi_value retValue = nullptr;
1158     napi_get_undefined(env, &retValue);
1159     return retValue;
1160 }
1161 
JS_setSize(napi_env env,napi_callback_info info)1162 napi_value NAPI_MessageSequence::JS_setSize(napi_env env, napi_callback_info info)
1163 {
1164     size_t argc = 1;
1165     napi_value argv[ARGV_LENGTH_1] = {0};
1166     napi_value thisVar = nullptr;
1167     void *data = nullptr;
1168     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1169     if (argc != REQUIRED_ARGS_COUNT_1) {
1170         ZLOGE(LOG_LABEL, "requires 1 parameter");
1171         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1172     }
1173 
1174     napi_valuetype valueType = napi_null;
1175     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1176     if (valueType != napi_number) {
1177         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1178         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1179     }
1180 
1181     uint32_t value = 0;
1182     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
1183 
1184     NAPI_MessageSequence *napiSequence = nullptr;
1185     napi_unwrap(env, thisVar, (void **)&napiSequence);
1186     if (napiSequence == nullptr) {
1187         ZLOGE(LOG_LABEL, "napiSequence is null");
1188         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1189     }
1190 
1191     bool result = napiSequence->nativeParcel_->SetDataSize(static_cast<size_t>(value));
1192     if (!result) {
1193         ZLOGE(LOG_LABEL, "set data size failed");
1194     }
1195     napi_value napiValue = nullptr;
1196     napi_get_undefined(env, &napiValue);
1197     return napiValue;
1198 }
1199 
JS_setCapacity(napi_env env,napi_callback_info info)1200 napi_value NAPI_MessageSequence::JS_setCapacity(napi_env env, napi_callback_info info)
1201 {
1202     size_t argc = 1;
1203     napi_value argv[ARGV_LENGTH_1] = {0};
1204     napi_value thisVar = nullptr;
1205     void *data = nullptr;
1206     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1207     if (argc != REQUIRED_ARGS_COUNT_1) {
1208         ZLOGE(LOG_LABEL, "requires 1 parameter");
1209         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1210     }
1211 
1212     napi_valuetype valueType = napi_null;
1213     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1214     if (valueType != napi_number) {
1215         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1216         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1217     }
1218 
1219     uint32_t value = 0;
1220     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
1221 
1222     NAPI_MessageSequence *napiSequence = nullptr;
1223     napi_unwrap(env, thisVar, (void **)&napiSequence);
1224     if (napiSequence == nullptr) {
1225         ZLOGE(LOG_LABEL, "napiSequence is null");
1226         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1227     }
1228 
1229     bool result = napiSequence->nativeParcel_->SetDataCapacity(static_cast<size_t>(value));
1230     if (result) {
1231         napiSequence->maxCapacityToWrite_ = value;
1232     } else {
1233         ZLOGE(LOG_LABEL, "set data capacity failed");
1234         return napiErr.ThrowError(env, errorDesc::PARCEL_MEMORY_ALLOC_ERROR);
1235     }
1236     napi_value napiValue = nullptr;
1237     napi_get_undefined(env, &napiValue);
1238     return napiValue;
1239 }
1240 
JS_getWritableBytes(napi_env env,napi_callback_info info)1241 napi_value NAPI_MessageSequence::JS_getWritableBytes(napi_env env, napi_callback_info info)
1242 {
1243     size_t argc = 0;
1244     napi_value thisVar = nullptr;
1245     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1246 
1247     NAPI_MessageSequence *napiSequence = nullptr;
1248     napi_unwrap(env, thisVar, (void **)&napiSequence);
1249     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1250 
1251     size_t value = napiSequence->nativeParcel_->GetWritableBytes();
1252     napi_value napiValue = nullptr;
1253     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
1254     return napiValue;
1255 }
1256 
JS_getWritePosition(napi_env env,napi_callback_info info)1257 napi_value NAPI_MessageSequence::JS_getWritePosition(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 
1263     NAPI_MessageSequence *napiSequence = nullptr;
1264     napi_unwrap(env, thisVar, (void **)&napiSequence);
1265     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1266 
1267     size_t value = napiSequence->nativeParcel_->GetWritePosition();
1268     napi_value napiValue = nullptr;
1269     NAPI_CALL(env, napi_create_uint32(env, value, &napiValue));
1270     return napiValue;
1271 }
1272 
JS_rewindWrite(napi_env env,napi_callback_info info)1273 napi_value NAPI_MessageSequence::JS_rewindWrite(napi_env env, napi_callback_info info)
1274 {
1275     size_t argc = 1;
1276     napi_value argv[ARGV_LENGTH_1] = {0};
1277     napi_value thisVar = nullptr;
1278     void *data = nullptr;
1279     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1280     if (argc != 1) {
1281         ZLOGE(LOG_LABEL, "requires 1 parameters");
1282         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1283     }
1284 
1285     napi_valuetype valueType = napi_null;
1286     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1287     if (valueType != napi_number) {
1288         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1289         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1290     }
1291 
1292     uint32_t pos = 0;
1293     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &pos);
1294 
1295     NAPI_MessageSequence *napiSequence = nullptr;
1296     napi_unwrap(env, thisVar, (void **)&napiSequence);
1297     if (napiSequence == nullptr) {
1298         ZLOGE(LOG_LABEL, "napiSequence is null");
1299         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1300     }
1301 
1302     bool result = napiSequence->nativeParcel_->RewindWrite(static_cast<size_t>(pos));
1303     NAPI_ASSERT(env, result == true, "rewind write failed");
1304     napi_value napiValue = nullptr;
1305     napi_get_undefined(env, &napiValue);
1306     return napiValue;
1307 }
1308 
JS_writeNoException(napi_env env,napi_callback_info info)1309 napi_value NAPI_MessageSequence::JS_writeNoException(napi_env env, napi_callback_info info)
1310 {
1311     napi_value thisVar = nullptr;
1312     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1313     NAPI_MessageSequence *napiSequence = nullptr;
1314     napi_unwrap(env, thisVar, (void **)&napiSequence);
1315     if (napiSequence == nullptr) {
1316         ZLOGE(LOG_LABEL, "napiSequence is null");
1317         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1318     }
1319     bool writeResult = napiSequence->nativeParcel_->WriteInt32(0);
1320     if (writeResult == false) {
1321         ZLOGE(LOG_LABEL, "write int32 failed");
1322         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1323     }
1324     napi_value result = nullptr;
1325     napi_get_undefined(env, &result);
1326     return result;
1327 }
1328 
JS_checkReadArrayArgs(napi_env env,napi_callback_info info,size_t & argc,napi_value & thisVar,napi_value * argv)1329 napi_value NAPI_MessageSequence::JS_checkReadArrayArgs(napi_env env,
1330                                                        napi_callback_info info,
1331                                                        size_t &argc,
1332                                                        napi_value &thisVar,
1333                                                        napi_value* argv)
1334 {
1335     if (argv == nullptr) {
1336         ZLOGE(LOG_LABEL, "argv is nullptr");
1337         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1338     }
1339     if (argc != 1) {
1340         ZLOGE(LOG_LABEL, "requires 1 parameters");
1341         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1342     }
1343     void *data = nullptr;
1344     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1345 
1346     bool isArray = false;
1347     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1348     if (!isArray) {
1349         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1350         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1351     }
1352 
1353     napi_value napiValue = nullptr;
1354     napi_get_undefined(env, &napiValue);
1355     return napiValue;
1356 }
1357 
JS_readParcelableArrayCallJsFunc(napi_env env,napi_value & element,napi_value & thisVar)1358 napi_value NAPI_MessageSequence::JS_readParcelableArrayCallJsFunc(napi_env env,
1359     napi_value &element, napi_value &thisVar)
1360 {
1361     napi_value propKey = nullptr;
1362     const char *propKeyStr = "unmarshalling";
1363     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
1364     napi_value prop = nullptr;
1365     napi_get_property(env, element, propKey, &prop);
1366 
1367     napi_value funcArg[1] = { thisVar };
1368     napi_value callResult = nullptr;
1369     napi_call_function(env, element, prop, 1, funcArg, &callResult);
1370     if (callResult == nullptr) {
1371         return napiErr.ThrowError(env, errorDesc::CALL_JS_METHOD_ERROR);
1372     }
1373 
1374     napi_value retValue = nullptr;
1375     napi_get_undefined(env, &retValue);
1376     return retValue;
1377 }
1378 
JS_create(napi_env env,napi_callback_info info)1379 napi_value NAPI_MessageSequence::JS_create(napi_env env, napi_callback_info info)
1380 {
1381     // new native sequence object
1382     napi_value global = nullptr;
1383     napi_status status = napi_get_global(env, &global);
1384     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
1385     napi_value constructor = nullptr;
1386     status = napi_get_named_property(env, global, "IPCSequenceConstructor_", &constructor);
1387     NAPI_ASSERT(env, status == napi_ok, "get message sequence constructor failed");
1388     napi_value jsMessageSequence;
1389     status = napi_new_instance(env, constructor, 0, nullptr, &jsMessageSequence);
1390     NAPI_ASSERT(env, status == napi_ok, "failed to  construct js MessageSequence");
1391     return jsMessageSequence;
1392 }
1393 
JS_reclaim(napi_env env,napi_callback_info info)1394 napi_value NAPI_MessageSequence::JS_reclaim(napi_env env, napi_callback_info info)
1395 {
1396     size_t argc = 0;
1397     napi_value thisVar = nullptr;
1398     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1399 
1400     NAPI_MessageSequence *napiSequence = nullptr;
1401     napi_remove_wrap(env, thisVar, (void **)&napiSequence);
1402     NAPI_ASSERT(env, napiSequence != nullptr, "napiSequence is null");
1403     delete napiSequence;
1404 
1405     napi_value result = nullptr;
1406     napi_get_undefined(env, &result);
1407     return result;
1408 }
1409 
JS_writeRemoteObject(napi_env env,napi_callback_info info)1410 napi_value NAPI_MessageSequence::JS_writeRemoteObject(napi_env env, napi_callback_info info)
1411 {
1412     size_t argc = 1;
1413     napi_value argv[ARGV_LENGTH_1] = {0};
1414     napi_value thisVar = nullptr;
1415     void *data = nullptr;
1416     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1417     if (argc != REQUIRED_ARGS_COUNT_1) {
1418         ZLOGE(LOG_LABEL, "requires 1 parameter");
1419         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1420     }
1421     napi_valuetype valueType = napi_null;
1422     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1423     if (valueType != napi_object) {
1424         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1425         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1426     }
1427     sptr<IRemoteObject> remoteObject = NAPI_ohos_rpc_getNativeRemoteObject(env, argv[ARGV_INDEX_0]);
1428     if (remoteObject == nullptr) {
1429         ZLOGE(LOG_LABEL, "remote object is nullptr");
1430         return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
1431     }
1432     NAPI_MessageSequence *napiSequence = nullptr;
1433     napi_unwrap(env, thisVar, (void **)&napiSequence);
1434     if (napiSequence == nullptr) {
1435         ZLOGE(LOG_LABEL, "napiSequence is null");
1436         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1437     }
1438     bool writeResult = napiSequence->nativeParcel_->WriteRemoteObject(remoteObject);
1439     if (writeResult == false) {
1440         ZLOGE(LOG_LABEL, "write remote object failed");
1441         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1442     }
1443     napi_value result = nullptr;
1444     napi_get_undefined(env, &result);
1445     return result;
1446 }
1447 
JS_writeInterfaceToken(napi_env env,napi_callback_info info)1448 napi_value NAPI_MessageSequence::JS_writeInterfaceToken(napi_env env, napi_callback_info info)
1449 {
1450     size_t argc = 1;
1451     napi_value argv[ARGV_LENGTH_1] = {0};
1452     napi_value thisVar = nullptr;
1453     void *data = nullptr;
1454     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1455     if (argc != REQUIRED_ARGS_COUNT_1) {
1456         ZLOGE(LOG_LABEL, "requires 1 parameter");
1457         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1458     }
1459     napi_valuetype valueType = napi_null;
1460     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1461     if (valueType != napi_string) {
1462         ZLOGE(LOG_LABEL, "type mismatch for parameter");
1463         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1464     }
1465     size_t bufferSize = 0;
1466     size_t maxSize = MAX_BYTES_LENGTH;
1467     napi_get_value_string_utf16(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
1468     if (bufferSize >= maxSize) {
1469         ZLOGE(LOG_LABEL, "string length too large");
1470         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1471     }
1472     char16_t stringValue[bufferSize + 1];
1473     size_t jsStringLength = 0;
1474     napi_get_value_string_utf16(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
1475     if (jsStringLength != bufferSize) {
1476         ZLOGE(LOG_LABEL, "string length wrong");
1477         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1478     }
1479 
1480     NAPI_MessageSequence *napiSequence = nullptr;
1481     napi_unwrap(env, thisVar, (void **)&napiSequence);
1482     if (napiSequence == nullptr) {
1483         ZLOGE(LOG_LABEL, "napiSequence is null");
1484         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1485     }
1486 
1487     bool writeResult = napiSequence->nativeParcel_->WriteInterfaceToken(stringValue);
1488     if (writeResult == false) {
1489         ZLOGE(LOG_LABEL, "write interface token failed");
1490         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1491     }
1492     napi_value result = nullptr;
1493     napi_get_undefined(env, &result);
1494     return result;
1495 }
1496 
JS_CloseFileDescriptor(napi_env env,napi_callback_info info)1497 napi_value NAPI_MessageSequence::JS_CloseFileDescriptor(napi_env env, napi_callback_info info)
1498 {
1499     size_t argc = 1;
1500     napi_value argv[ARGV_LENGTH_1] = {0};
1501     napi_value thisVar = nullptr;
1502     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1503     if (argc != 1) {
1504         ZLOGE(LOG_LABEL, "requires 1 parameters");
1505         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
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     int32_t fd = -1;
1514     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
1515     close(fd);
1516     napi_value result = nullptr;
1517     napi_get_undefined(env, &result);
1518     return result;
1519 }
1520 
JS_DupFileDescriptor(napi_env env,napi_callback_info info)1521 napi_value NAPI_MessageSequence::JS_DupFileDescriptor(napi_env env, napi_callback_info info)
1522 {
1523     size_t argc = 1;
1524     napi_value argv[ARGV_LENGTH_1] = {0};
1525     napi_value thisVar = nullptr;
1526     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1527     if (argc != 1) {
1528         ZLOGE(LOG_LABEL, "requires 1 parameters");
1529         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1530     }
1531     napi_valuetype valueType = napi_null;
1532     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1533     if (valueType != napi_number) {
1534         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1535         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1536     }
1537     int32_t fd = -1;
1538     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
1539     int32_t dupResult = dup(fd);
1540     if (dupResult < 0) {
1541         ZLOGE(LOG_LABEL, "os dup function failed");
1542         return napiErr.ThrowError(env, errorDesc::OS_DUP_ERROR);
1543     }
1544     napi_value napiValue;
1545     napi_create_int32(env, dupResult, &napiValue);
1546     return napiValue;
1547 }
1548 
JS_ContainFileDescriptors(napi_env env,napi_callback_info info)1549 napi_value NAPI_MessageSequence::JS_ContainFileDescriptors(napi_env env, napi_callback_info info)
1550 {
1551     size_t argc = 0;
1552     napi_value thisVar = nullptr;
1553     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1554     NAPI_MessageSequence *napiSequence = nullptr;
1555     napi_unwrap(env, thisVar, (void **)&napiSequence);
1556     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1557     bool result = napiSequence->nativeParcel_->ContainFileDescriptors();
1558     napi_value napiValue = nullptr;
1559     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
1560     return napiValue;
1561 }
1562 
JS_WriteFileDescriptor(napi_env env,napi_callback_info info)1563 napi_value NAPI_MessageSequence::JS_WriteFileDescriptor(napi_env env, napi_callback_info info)
1564 {
1565     size_t argc = 1;
1566     napi_value argv[ARGV_LENGTH_1] = {0};
1567     napi_value thisVar = nullptr;
1568     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1569     if (argc != 1) {
1570         ZLOGE(LOG_LABEL, "requires 1 parameters");
1571         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1572     }
1573     napi_valuetype valueType = napi_null;
1574     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1575     if (valueType != napi_number) {
1576         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1577         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1578     }
1579     int32_t fd = -1;
1580     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
1581     NAPI_MessageSequence *napiSequence = nullptr;
1582     napi_unwrap(env, thisVar, (void **)&napiSequence);
1583     if (napiSequence == nullptr) {
1584         ZLOGE(LOG_LABEL, "napiSequence is null");
1585         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1586     }
1587     bool result = napiSequence->nativeParcel_->WriteFileDescriptor(fd);
1588     if (!result) {
1589         ZLOGE(LOG_LABEL, "write file descriptor failed");
1590         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1591     }
1592     napi_value napiValue = nullptr;
1593     napi_get_undefined(env, &napiValue);
1594     return napiValue;
1595 }
1596 
JS_WriteAshmem(napi_env env,napi_callback_info info)1597 napi_value NAPI_MessageSequence::JS_WriteAshmem(napi_env env, napi_callback_info info)
1598 {
1599     size_t argc = 1;
1600     napi_value argv[ARGV_LENGTH_1] = {0};
1601     napi_value thisVar = nullptr;
1602     void *data = nullptr;
1603     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1604     if (argc != 1) {
1605         ZLOGE(LOG_LABEL, "requires 1 parameters");
1606         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1607     }
1608     // check type is Ashmem
1609     napi_value global = nullptr;
1610     napi_value napiValue = nullptr;
1611     napi_get_undefined(env, &napiValue);
1612     napi_status status = napi_get_global(env, &global);
1613     if (status != napi_ok) {
1614         ZLOGE(LOG_LABEL, "get napi global failed");
1615         return napiValue;
1616     }
1617     napi_value constructor = nullptr;
1618     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
1619     if (status != napi_ok) {
1620         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
1621         return napiValue;
1622     }
1623     bool isAshmem = false;
1624     napi_instanceof(env, argv[ARGV_INDEX_0], constructor, &isAshmem);
1625     if (!isAshmem) {
1626         ZLOGE(LOG_LABEL, "parameter is not instanceof Ashmem");
1627         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1628     }
1629     NAPIAshmem *napiAshmem = nullptr;
1630     napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&napiAshmem);
1631     if (napiAshmem == nullptr) {
1632         ZLOGE(LOG_LABEL, "napiAshmem is null");
1633         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1634     }
1635     sptr<Ashmem> nativeAshmem = napiAshmem->GetAshmem();
1636     NAPI_MessageSequence *napiSequence = nullptr;
1637     napi_unwrap(env, thisVar, (void **)&napiSequence);
1638     if (napiSequence == nullptr) {
1639         ZLOGE(LOG_LABEL, "napiSequence is null");
1640         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1641     }
1642     bool result = napiSequence->nativeParcel_->WriteAshmem(nativeAshmem);
1643     if (!result) {
1644         ZLOGE(LOG_LABEL, "write ashmem failed");
1645         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1646     }
1647     return napiValue;
1648 }
1649 
JS_checkWriteRawDataArgs(napi_env env,size_t argc,napi_value * argv)1650 napi_value NAPI_MessageSequence::JS_checkWriteRawDataArgs(napi_env env, size_t argc, napi_value* argv)
1651 {
1652     if (argv == nullptr) {
1653         ZLOGE(LOG_LABEL, "argv is nullptr");
1654         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1655     }
1656     size_t expectedArgc = 2;
1657     if (argc != expectedArgc) {
1658         ZLOGE(LOG_LABEL, "requires 2 parameters");
1659         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1660     }
1661     bool isArray = false;
1662     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1663     if (!isArray) {
1664         bool isTypedArray = false;
1665         napi_is_typedarray(env, argv[ARGV_INDEX_0], &isTypedArray);
1666         if (!isTypedArray) {
1667             ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not array, not typedarray");
1668             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1669         }
1670     }
1671 
1672     napi_valuetype valueType = napi_null;
1673     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1674     if (valueType != napi_number) {
1675         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1676         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1677     }
1678 
1679     napi_value napiValue = nullptr;
1680     napi_get_undefined(env, &napiValue);
1681     return napiValue;
1682 }
1683 
JS_WriteRawDataForArray(napi_env env,napi_value jsArray,uint32_t size,NAPI_MessageSequence * napiSequence)1684 bool NAPI_MessageSequence::JS_WriteRawDataForArray(napi_env env, napi_value jsArray,
1685     uint32_t size, NAPI_MessageSequence *napiSequence)
1686 {
1687     std::vector<int32_t> array;
1688     uint32_t length = 0;
1689     napi_get_array_length(env, jsArray, &length);
1690     for (uint32_t i = 0; i < length; i++) {
1691         bool hasElement = false;
1692         napi_has_element(env, jsArray, i, &hasElement);
1693         if (!hasElement) {
1694             ZLOGE(LOG_LABEL, "parameter check error");
1695             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1696         }
1697 
1698         napi_value element = nullptr;
1699         napi_get_element(env, jsArray, i, &element);
1700 
1701         int32_t value = 0;
1702         napi_get_value_int32(env, element, &value);
1703         array.push_back(value);
1704     }
1705     if (length < size) {
1706         uint32_t padSize = size - length;
1707         ZLOGW(LOG_LABEL, "array length:%{public}u less than parameter size:%{public}u"
1708             " need pad:%{public}u 0", length, size, padSize);
1709         for (uint32_t i = 0; i < padSize; i++) {
1710             array.push_back(0);
1711         }
1712     }
1713     return napiSequence->nativeParcel_->WriteRawData(array.data(), size * BYTE_SIZE_32);
1714 }
1715 
JS_WriteRawDataForTypedArray(napi_env env,napi_value jsTypedArray,size_t size,NAPI_MessageSequence * napiSequence)1716 bool NAPI_MessageSequence::JS_WriteRawDataForTypedArray(napi_env env, napi_value jsTypedArray,
1717     size_t size, NAPI_MessageSequence *napiSequence)
1718 {
1719     napi_typedarray_type type;
1720     char *data = nullptr;
1721     size_t arrayLength = 0;
1722     napi_value arrayBuffer;
1723     size_t byteOffset = 0;
1724     napi_status isGet = napi_get_typedarray_info(env, jsTypedArray, &type,
1725         &arrayLength, (void **)&data, &arrayBuffer, &byteOffset);
1726     if (isGet != napi_ok || type != napi_int32_array) {
1727         ZLOGE(LOG_LABEL, "typedarray get info failed or not napi_int32_array");
1728         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1729     }
1730     if (arrayLength < size) {
1731         ZLOGE(LOG_LABEL, "typedarray length:%{public}zu less than parameter size:%{public}zu",
1732             arrayLength, size);
1733         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1734     }
1735     return napiSequence->nativeParcel_->WriteRawData(data - byteOffset, BYTE_SIZE_32 * size);
1736 }
1737 
JS_WriteRawData(napi_env env,napi_callback_info info)1738 napi_value NAPI_MessageSequence::JS_WriteRawData(napi_env env, napi_callback_info info)
1739 {
1740     size_t argc = 2;
1741     napi_value argv[ARGV_LENGTH_2] = {0};
1742     napi_value thisVar = nullptr;
1743     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1744     napi_value checkArgsResult = JS_checkWriteRawDataArgs(env, argc, argv);
1745     if (checkArgsResult == nullptr) {
1746         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1747         return checkArgsResult;
1748     }
1749 
1750     NAPI_MessageSequence *napiSequence = nullptr;
1751     napi_unwrap(env, thisVar, (void **)&napiSequence);
1752     if (napiSequence == nullptr) {
1753         ZLOGE(LOG_LABEL, "napiSequence is null");
1754         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1755     }
1756 
1757     int32_t size = 0;
1758     napi_status isGetOk = napi_get_value_int32(env, argv[ARGV_INDEX_1], &size);
1759     if (isGetOk != napi_ok || size <= 0) {
1760         ZLOGE(LOG_LABEL, "error for parameter 2 size is %{public}d, get failed", size);
1761         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1762     }
1763     bool result = false;
1764     bool isArray = false;
1765     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1766     if (isArray) {
1767         result = JS_WriteRawDataForArray(env, argv[ARGV_INDEX_0], static_cast<uint32_t>(size), napiSequence);
1768     } else {
1769         result = JS_WriteRawDataForTypedArray(env, argv[ARGV_INDEX_0], static_cast<size_t>(size), napiSequence);
1770     }
1771 
1772     if (!result) {
1773         ZLOGE(LOG_LABEL, "write raw data failed");
1774         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1775     }
1776     napi_value napiValue = nullptr;
1777     napi_get_undefined(env, &napiValue);
1778     return napiValue;
1779 }
1780 
JS_WriteRawDataBuffer(napi_env env,napi_callback_info info)1781 napi_value NAPI_MessageSequence::JS_WriteRawDataBuffer(napi_env env, napi_callback_info info)
1782 {
1783     size_t argc = ARGV_LENGTH_2;
1784     napi_value argv[ARGV_LENGTH_2] = {0};
1785     napi_value thisVar = nullptr;
1786     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1787     if (argc != ARGV_LENGTH_2) {
1788         ZLOGE(LOG_LABEL, "requires 2 parameters");
1789         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1790     }
1791 
1792     bool isArrayBuffer = false;
1793     napi_is_arraybuffer(env, argv[ARGV_INDEX_0], &isArrayBuffer);
1794     if (!isArrayBuffer) {
1795         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not ArrayBuffer");
1796         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1797     }
1798 
1799     napi_valuetype valueType = napi_null;
1800     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1801     if (valueType != napi_number) {
1802         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1803         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1804     }
1805 
1806     void *data = nullptr;
1807     size_t byteLength = 0;
1808     napi_status isGet = napi_get_arraybuffer_info(env, argv[ARGV_INDEX_0], (void **)&data, &byteLength);
1809     if (isGet != napi_ok) {
1810         ZLOGE(LOG_LABEL, "arraybuffer get info failed");
1811         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1812     }
1813 
1814     int64_t size = 0;
1815     napi_status isGetOk = napi_get_value_int64(env, argv[ARGV_INDEX_1], &size);
1816     if (isGetOk != napi_ok || size <= 0 || static_cast<size_t>(size) > byteLength) {
1817         ZLOGE(LOG_LABEL, "error for parameter 2 size is %{public}" PRId64, size);
1818         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1819     }
1820 
1821     NAPI_MessageSequence *napiSequence = nullptr;
1822     napi_unwrap(env, thisVar, (void **)&napiSequence);
1823     if (napiSequence == nullptr) {
1824         ZLOGE(LOG_LABEL, "napiSequence is null");
1825         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1826     }
1827 
1828     if (!napiSequence->nativeParcel_->WriteRawData(data, size)) {
1829         ZLOGE(LOG_LABEL, "write raw data failed");
1830         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1831     }
1832 
1833     napi_value napiValue = nullptr;
1834     napi_get_undefined(env, &napiValue);
1835     return napiValue;
1836 }
1837 
JS_GetRawDataCapacity(napi_env env,napi_callback_info info)1838 napi_value NAPI_MessageSequence::JS_GetRawDataCapacity(napi_env env, napi_callback_info info)
1839 {
1840     size_t argc = 0;
1841     napi_value thisVar = nullptr;
1842     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1843     NAPI_MessageSequence *napiSequence = nullptr;
1844     napi_unwrap(env, thisVar, (void **)&napiSequence);
1845     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1846     uint32_t result = napiSequence->nativeParcel_->GetRawDataCapacity();
1847     napi_value napiValue;
1848     napi_create_uint32(env, result, &napiValue);
1849     return napiValue;
1850 }
1851 
JS_checkWriteArrayBufferArgs(napi_env env,size_t argc,napi_value * argv)1852 napi_value NAPI_MessageSequence::JS_checkWriteArrayBufferArgs(napi_env env, size_t argc, napi_value* argv)
1853 {
1854     if (argv == nullptr) {
1855         ZLOGE(LOG_LABEL, "argv is nullptr");
1856         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1857     }
1858     if (argc != ARGV_LENGTH_2) {
1859         ZLOGE(LOG_LABEL, "requires 2 parameter");
1860         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1861     }
1862 
1863     bool isArrayBuffer = false;
1864     napi_status status = napi_is_arraybuffer(env, argv[ARGV_INDEX_0], &isArrayBuffer);
1865     if (!isArrayBuffer) {
1866         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not ArrayBuffer. status:%{public}d", status);
1867         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1868     }
1869 
1870     napi_valuetype valuetype = napi_null;
1871     status = napi_typeof(env, argv[ARGV_INDEX_1], &valuetype);
1872     if (valuetype != napi_number) {
1873         ZLOGE(LOG_LABEL, "type mismatch for parameter 2, not number. status:%{public}d", status);
1874         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1875     }
1876 
1877     int32_t typeCode = 0;
1878     napi_get_value_int32(env, argv[ARGV_INDEX_1], &typeCode);
1879     if (typeCode < INT8_ARRAY || typeCode > BIGUINT64_ARRAY) {
1880         ZLOGE(LOG_LABEL, "the value of parameter 2 is out of range. typeCode:%{public}d", typeCode);
1881         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1882     }
1883 
1884     napi_value napiValue = nullptr;
1885     napi_get_undefined(env, &napiValue);
1886     return napiValue;
1887 }
1888 
1889 template<typename T>
BufferToVector(void * data,size_t byteLength)1890 static std::vector<T> BufferToVector(void *data, size_t byteLength)
1891 {
1892     const T* dataPtr = reinterpret_cast<const T*>(data);
1893     std::vector<T> vec;
1894     std::copy(dataPtr, dataPtr + byteLength / sizeof(T), std::back_inserter(vec));
1895     return vec;
1896 }
1897 
JS_writeArrayBuffer(napi_env env,napi_callback_info info)1898 napi_value NAPI_MessageSequence::JS_writeArrayBuffer(napi_env env, napi_callback_info info)
1899 {
1900     size_t argc = ARGV_LENGTH_2;
1901     napi_value argv[ARGV_LENGTH_2] = {0};
1902     napi_value thisVar = nullptr;
1903     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1904     napi_value checkArgsResult = JS_checkWriteArrayBufferArgs(env, argc, argv);
1905     if (checkArgsResult == nullptr) {
1906         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1907         return checkArgsResult;
1908     }
1909 
1910     void *data = nullptr;
1911     size_t byteLength = 0;
1912     napi_status getStatus = napi_get_arraybuffer_info(env, argv[ARGV_INDEX_0], (void **)&data, &byteLength);
1913     if (getStatus != napi_ok) {
1914         ZLOGE(LOG_LABEL, "arraybuffer get info failed. getStatus:%{public}d", getStatus);
1915         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1916     }
1917     if (data == nullptr) {
1918         ZLOGE(LOG_LABEL, "data is null");
1919         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1920     }
1921 
1922     NAPI_MessageSequence *napiSequence = nullptr;
1923     napi_unwrap(env, thisVar, (void **)&napiSequence);
1924     if (napiSequence == nullptr) {
1925         ZLOGE(LOG_LABEL, "napiSequence is null");
1926         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1927     }
1928 
1929     CHECK_WRITE_CAPACITY(env, byteLength, napiSequence);
1930 
1931     int32_t typeCode = 0;
1932     napi_get_value_int32(env, argv[ARGV_INDEX_1], &typeCode);
1933 
1934     bool writeSuccess = JS_writeVectorByTypeCode(typeCode, data, byteLength, napiSequence);
1935     if (!writeSuccess) {
1936         ZLOGE(LOG_LABEL, "write buffer failed");
1937         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1938     }
1939 
1940     napi_value napiValue = nullptr;
1941     napi_get_undefined(env, &napiValue);
1942     return napiValue;
1943 }
1944 
JS_writeVectorByTypeCode(int32_t typeCode,void * data,size_t byteLength,NAPI_MessageSequence * napiSequence)1945 bool NAPI_MessageSequence::JS_writeVectorByTypeCode(int32_t typeCode,
1946                                                     void *data,
1947                                                     size_t byteLength,
1948                                                     NAPI_MessageSequence *napiSequence)
1949 {
1950     if (data == nullptr || napiSequence == nullptr) {
1951         ZLOGE(LOG_LABEL, "data or napiSequence is null");
1952         return false;
1953     }
1954     switch (typeCode) {
1955         case INT8_ARRAY: {
1956             return napiSequence->nativeParcel_->WriteInt8Vector(BufferToVector<int8_t>(data, byteLength));
1957         }
1958         case UINT8_ARRAY: {
1959             return napiSequence->nativeParcel_->WriteUInt8Vector(BufferToVector<uint8_t>(data, byteLength));
1960         }
1961         case INT16_ARRAY: {
1962             return napiSequence->nativeParcel_->WriteInt16Vector(BufferToVector<int16_t>(data, byteLength));
1963         }
1964         case UINT16_ARRAY: {
1965             return napiSequence->nativeParcel_->WriteUInt16Vector(BufferToVector<uint16_t>(data, byteLength));
1966         }
1967         case INT32_ARRAY: {
1968             return napiSequence->nativeParcel_->WriteInt32Vector(BufferToVector<int32_t>(data, byteLength));
1969         }
1970         case UINT32_ARRAY: {
1971             return napiSequence->nativeParcel_->WriteUInt32Vector(BufferToVector<uint32_t>(data, byteLength));
1972         }
1973         case FLOAT32_ARRAY: {
1974             return napiSequence->nativeParcel_->WriteFloatVector(BufferToVector<float>(data, byteLength));
1975         }
1976         case FLOAT64_ARRAY: {
1977             return napiSequence->nativeParcel_->WriteDoubleVector(BufferToVector<double>(data, byteLength));
1978         }
1979         case BIGINT64_ARRAY: {
1980             return napiSequence->nativeParcel_->WriteInt64Vector(BufferToVector<int64_t>(data, byteLength));
1981         }
1982         case BIGUINT64_ARRAY: {
1983             return napiSequence->nativeParcel_->WriteUInt64Vector(BufferToVector<uint64_t>(data, byteLength));
1984         }
1985         default:
1986             ZLOGE(LOG_LABEL, "unsupported typeCode:%{public}d", typeCode);
1987             return false;
1988     }
1989 }
1990 
Export(napi_env env,napi_value exports)1991 napi_value NAPI_MessageSequence::Export(napi_env env, napi_value exports)
1992 {
1993     const std::string className = "MessageSequence";
1994     napi_value typeCode = CreateTypeCodeEnum(env);
1995     napi_property_descriptor properties[] = {
1996         DECLARE_NAPI_STATIC_FUNCTION("create", NAPI_MessageSequence::JS_create),
1997         DECLARE_NAPI_FUNCTION("reclaim", NAPI_MessageSequence::JS_reclaim),
1998         DECLARE_NAPI_FUNCTION("writeRemoteObject", NAPI_MessageSequence::JS_writeRemoteObject),
1999         DECLARE_NAPI_FUNCTION("readRemoteObject", NAPI_MessageSequence::JS_readRemoteObject),
2000         DECLARE_NAPI_FUNCTION("writeInterfaceToken", NAPI_MessageSequence::JS_writeInterfaceToken),
2001         DECLARE_NAPI_FUNCTION("readInterfaceToken", NAPI_MessageSequence::JS_readInterfaceToken),
2002         DECLARE_NAPI_FUNCTION("getSize", NAPI_MessageSequence::JS_getSize),
2003         DECLARE_NAPI_FUNCTION("getCapacity", NAPI_MessageSequence::JS_getCapacity),
2004         DECLARE_NAPI_FUNCTION("setSize", NAPI_MessageSequence::JS_setSize),
2005         DECLARE_NAPI_FUNCTION("setCapacity", NAPI_MessageSequence::JS_setCapacity),
2006         DECLARE_NAPI_FUNCTION("getWritableBytes", NAPI_MessageSequence::JS_getWritableBytes),
2007         DECLARE_NAPI_FUNCTION("getReadableBytes", NAPI_MessageSequence::JS_getReadableBytes),
2008         DECLARE_NAPI_FUNCTION("getReadPosition", NAPI_MessageSequence::JS_getReadPosition),
2009         DECLARE_NAPI_FUNCTION("getWritePosition", NAPI_MessageSequence::JS_getWritePosition),
2010         DECLARE_NAPI_FUNCTION("rewindRead", NAPI_MessageSequence::JS_rewindRead),
2011         DECLARE_NAPI_FUNCTION("rewindWrite", NAPI_MessageSequence::JS_rewindWrite),
2012         DECLARE_NAPI_FUNCTION("writeNoException", NAPI_MessageSequence::JS_writeNoException),
2013         DECLARE_NAPI_FUNCTION("readException", NAPI_MessageSequence::JS_readException),
2014         DECLARE_NAPI_FUNCTION("writeByte", NAPI_MessageSequence::JS_writeByte),
2015         DECLARE_NAPI_FUNCTION("writeShort", NAPI_MessageSequence::JS_writeShort),
2016         DECLARE_NAPI_FUNCTION("writeInt", NAPI_MessageSequence::JS_writeInt),
2017         DECLARE_NAPI_FUNCTION("writeLong", NAPI_MessageSequence::JS_writeLong),
2018         DECLARE_NAPI_FUNCTION("writeFloat", NAPI_MessageSequence::JS_writeFloat),
2019         DECLARE_NAPI_FUNCTION("writeDouble", NAPI_MessageSequence::JS_writeDouble),
2020         DECLARE_NAPI_FUNCTION("writeBoolean", NAPI_MessageSequence::JS_writeBoolean),
2021         DECLARE_NAPI_FUNCTION("writeChar", NAPI_MessageSequence::JS_writeChar),
2022         DECLARE_NAPI_FUNCTION("writeString", NAPI_MessageSequence::JS_writeString),
2023         DECLARE_NAPI_FUNCTION("writeParcelable", NAPI_MessageSequence::JS_writeParcelable),
2024         DECLARE_NAPI_FUNCTION("writeByteArray", NAPI_MessageSequence::JS_writeByteArray),
2025         DECLARE_NAPI_FUNCTION("writeShortArray", NAPI_MessageSequence::JS_writeShortArray),
2026         DECLARE_NAPI_FUNCTION("writeIntArray", NAPI_MessageSequence::JS_writeIntArray),
2027         DECLARE_NAPI_FUNCTION("writeLongArray", NAPI_MessageSequence::JS_writeLongArray),
2028         DECLARE_NAPI_FUNCTION("writeFloatArray", NAPI_MessageSequence::JS_writeFloatArray),
2029         DECLARE_NAPI_FUNCTION("writeDoubleArray", NAPI_MessageSequence::JS_writeDoubleArray),
2030         DECLARE_NAPI_FUNCTION("writeBooleanArray", NAPI_MessageSequence::JS_writeBooleanArray),
2031         DECLARE_NAPI_FUNCTION("writeCharArray", NAPI_MessageSequence::JS_writeCharArray),
2032         DECLARE_NAPI_FUNCTION("writeStringArray", NAPI_MessageSequence::JS_writeStringArray),
2033         DECLARE_NAPI_FUNCTION("writeParcelableArray", NAPI_MessageSequence::JS_writeParcelableArray),
2034         DECLARE_NAPI_FUNCTION("writeRemoteObjectArray", NAPI_MessageSequence::JS_writeRemoteObjectArray),
2035         DECLARE_NAPI_FUNCTION("readByte", NAPI_MessageSequence::JS_readByte),
2036         DECLARE_NAPI_FUNCTION("readShort", NAPI_MessageSequence::JS_readShort),
2037         DECLARE_NAPI_FUNCTION("readInt", NAPI_MessageSequence::JS_readInt),
2038         DECLARE_NAPI_FUNCTION("readLong", NAPI_MessageSequence::JS_readLong),
2039         DECLARE_NAPI_FUNCTION("readFloat", NAPI_MessageSequence::JS_readFloat),
2040         DECLARE_NAPI_FUNCTION("readDouble", NAPI_MessageSequence::JS_readDouble),
2041         DECLARE_NAPI_FUNCTION("readBoolean", NAPI_MessageSequence::JS_readBoolean),
2042         DECLARE_NAPI_FUNCTION("readChar", NAPI_MessageSequence::JS_readChar),
2043         DECLARE_NAPI_FUNCTION("readString", NAPI_MessageSequence::JS_readString),
2044         DECLARE_NAPI_FUNCTION("readParcelable", NAPI_MessageSequence::JS_readParcelable),
2045         DECLARE_NAPI_FUNCTION("readByteArray", NAPI_MessageSequence::JS_readByteArray),
2046         DECLARE_NAPI_FUNCTION("readShortArray", NAPI_MessageSequence::JS_readShortArray),
2047         DECLARE_NAPI_FUNCTION("readIntArray", NAPI_MessageSequence::JS_readIntArray),
2048         DECLARE_NAPI_FUNCTION("readLongArray", NAPI_MessageSequence::JS_readLongArray),
2049         DECLARE_NAPI_FUNCTION("readFloatArray", NAPI_MessageSequence::JS_readFloatArray),
2050         DECLARE_NAPI_FUNCTION("readDoubleArray", NAPI_MessageSequence::JS_readDoubleArray),
2051         DECLARE_NAPI_FUNCTION("readBooleanArray", NAPI_MessageSequence::JS_readBooleanArray),
2052         DECLARE_NAPI_FUNCTION("readCharArray", NAPI_MessageSequence::JS_readCharArray),
2053         DECLARE_NAPI_FUNCTION("readStringArray", NAPI_MessageSequence::JS_readStringArray),
2054         DECLARE_NAPI_FUNCTION("readParcelableArray", NAPI_MessageSequence::JS_readParcelableArray),
2055         DECLARE_NAPI_FUNCTION("readRemoteObjectArray", NAPI_MessageSequence::JS_readRemoteObjectArray),
2056         DECLARE_NAPI_STATIC_FUNCTION("closeFileDescriptor", NAPI_MessageSequence::JS_CloseFileDescriptor),
2057         DECLARE_NAPI_STATIC_FUNCTION("dupFileDescriptor", NAPI_MessageSequence::JS_DupFileDescriptor),
2058         DECLARE_NAPI_FUNCTION("writeFileDescriptor", NAPI_MessageSequence::JS_WriteFileDescriptor),
2059         DECLARE_NAPI_FUNCTION("readFileDescriptor", NAPI_MessageSequence::JS_ReadFileDescriptor),
2060         DECLARE_NAPI_FUNCTION("containFileDescriptors", NAPI_MessageSequence::JS_ContainFileDescriptors),
2061         DECLARE_NAPI_FUNCTION("writeAshmem", NAPI_MessageSequence::JS_WriteAshmem),
2062         DECLARE_NAPI_FUNCTION("readAshmem", NAPI_MessageSequence::JS_ReadAshmem),
2063         DECLARE_NAPI_FUNCTION("getRawDataCapacity", NAPI_MessageSequence::JS_GetRawDataCapacity),
2064         DECLARE_NAPI_FUNCTION("writeRawData", NAPI_MessageSequence::JS_WriteRawData),
2065         DECLARE_NAPI_FUNCTION("readRawData", NAPI_MessageSequence::JS_ReadRawData),
2066         DECLARE_NAPI_FUNCTION("writeRawDataBuffer", NAPI_MessageSequence::JS_WriteRawDataBuffer),
2067         DECLARE_NAPI_FUNCTION("readRawDataBuffer", NAPI_MessageSequence::JS_ReadRawDataBuffer),
2068         DECLARE_NAPI_FUNCTION("writeArrayBuffer", NAPI_MessageSequence::JS_writeArrayBuffer),
2069         DECLARE_NAPI_FUNCTION("readArrayBuffer", NAPI_MessageSequence::JS_readArrayBuffer),
2070     };
2071     napi_value constructor = nullptr;
2072     napi_define_class(env, className.c_str(), className.length(), JS_constructor, nullptr,
2073         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
2074     NAPI_ASSERT(env, constructor != nullptr, "define js class MessageSequence failed");
2075     napi_status status = napi_set_named_property(env, exports, "MessageSequence", constructor);
2076     NAPI_ASSERT(env, status == napi_ok, "set property MessageSequence failed");
2077     status = napi_set_named_property(env, exports, "TypeCode", typeCode);
2078     NAPI_ASSERT(env, status == napi_ok, "set property TypeCode failed");
2079     napi_value global = nullptr;
2080     status = napi_get_global(env, &global);
2081     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
2082     status = napi_set_named_property(env, global, "IPCSequenceConstructor_", constructor);
2083     NAPI_ASSERT(env, status == napi_ok, "set message sequence constructor failed");
2084     return exports;
2085 }
2086 
JS_constructor(napi_env env,napi_callback_info info)2087 napi_value NAPI_MessageSequence::JS_constructor(napi_env env, napi_callback_info info)
2088 {
2089     napi_value thisVar = nullptr;
2090     size_t argc = 1;
2091     napi_value argv[ARGV_LENGTH_1] = {0};
2092     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2093     NAPI_ASSERT(env, status == napi_ok, "napi get callback info failed");
2094     MessageParcel *parcel = nullptr;
2095     if (argc > 0) {
2096         napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&parcel);
2097         NAPI_ASSERT(env, parcel != nullptr, "parcel is null");
2098     }
2099     // new native parcel object
2100     auto messageSequence = new (std::nothrow) NAPI_MessageSequence(env, thisVar, parcel);
2101     NAPI_ASSERT(env, messageSequence != nullptr, "new messageSequence failed");
2102     // connect native object to js thisVar
2103     status = napi_wrap(
2104         env, thisVar, messageSequence,
2105         [](napi_env env, void *data, void *hint) {
2106             NAPI_MessageSequence *messageSequence = reinterpret_cast<NAPI_MessageSequence *>(data);
2107             if (!messageSequence->owner) {
2108                 delete messageSequence;
2109             }
2110         },
2111         nullptr, nullptr);
2112     if (status != napi_ok) {
2113         delete messageSequence;
2114         NAPI_ASSERT(env, false, "napi wrap message parcel failed");
2115     }
2116     return thisVar;
2117 }
2118 } // namespace OHOS
2119