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 mashalling 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 mashalling 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     bool result = napiSequence->nativeParcel_->WriteUint32(arrayLength);
1075     if (!result) {
1076         ZLOGE(LOG_LABEL, "write uint32 failed");
1077         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1078     }
1079     for (size_t i = 0; i < arrayLength; i++) {
1080         bool hasElement = false;
1081         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
1082         if (!hasElement) {
1083             ZLOGE(LOG_LABEL, "parameter check error");
1084             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1085         }
1086 
1087         napi_value element = nullptr;
1088         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
1089         napi_valuetype valueType = napi_null;
1090         napi_typeof(env, element, &valueType);
1091         if (valueType == napi_null || valueType == napi_undefined) {
1092             napiSequence->nativeParcel_->WriteInt32(0);
1093             continue;
1094         } else {
1095             napiSequence->nativeParcel_->WriteInt32(1);
1096         }
1097         napi_value callResult = JS_writeParcelableArrayCallJsFunc(env, element, thisVar);
1098         if (callResult == nullptr) {
1099             ZLOGE(LOG_LABEL, "call mashalling failed, element index:%{public}zu", i);
1100             napiSequence->nativeParcel_->RewindWrite(pos);
1101             return callResult;
1102         }
1103     }
1104     napi_value retValue = nullptr;
1105     napi_get_undefined(env, &retValue);
1106     return retValue;
1107 }
1108 
JS_writeRemoteObjectArray(napi_env env,napi_callback_info info)1109 napi_value NAPI_MessageSequence::JS_writeRemoteObjectArray(napi_env env, napi_callback_info info)
1110 {
1111     size_t argc = 1;
1112     napi_value argv[ARGV_LENGTH_1] = {0};
1113     napi_value thisVar = nullptr;
1114     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1115     uint32_t arrayLength = 0;
1116     napi_value checkArgsResult = JS_checkWriteArrayArgs(env, argc, argv, arrayLength);
1117     if (checkArgsResult == nullptr) {
1118         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1119         return checkArgsResult;
1120     }
1121 
1122     NAPI_MessageSequence *napiSequence = nullptr;
1123     napi_unwrap(env, thisVar, (void **)&napiSequence);
1124     if (napiSequence == nullptr) {
1125         ZLOGE(LOG_LABEL, "napiSequence is null");
1126         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1127     }
1128     napi_valuetype valueType = napi_null;
1129     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1130     if (valueType == napi_null || valueType == napi_undefined) {
1131         napiSequence->nativeParcel_->WriteInt32(-1);
1132         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1133         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1134     }
1135     size_t pos = napiSequence->nativeParcel_->GetWritePosition();
1136     bool result =  napiSequence->nativeParcel_->WriteInt32(arrayLength);
1137     for (size_t i = 0; i < arrayLength; i++) {
1138         bool hasElement = false;
1139         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
1140         if (!hasElement) {
1141             ZLOGE(LOG_LABEL, "parameter check error");
1142             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1143         }
1144         napi_value element = nullptr;
1145         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
1146         sptr<IRemoteObject> remoteObject = NAPI_ohos_rpc_getNativeRemoteObject(env, element);
1147         if (remoteObject == nullptr) {
1148             ZLOGE(LOG_LABEL, "parameter check error");
1149             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1150         }
1151         result = napiSequence->nativeParcel_->WriteRemoteObject(remoteObject);
1152         if (!result) {
1153             napiSequence->nativeParcel_->RewindWrite(pos);
1154             ZLOGE(LOG_LABEL, "write string16 failed");
1155             return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1156         }
1157     }
1158     napi_value retValue = nullptr;
1159     napi_get_undefined(env, &retValue);
1160     return retValue;
1161 }
1162 
JS_setSize(napi_env env,napi_callback_info info)1163 napi_value NAPI_MessageSequence::JS_setSize(napi_env env, napi_callback_info info)
1164 {
1165     size_t argc = 1;
1166     napi_value argv[ARGV_LENGTH_1] = {0};
1167     napi_value thisVar = nullptr;
1168     void *data = nullptr;
1169     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1170     if (argc != REQUIRED_ARGS_COUNT_1) {
1171         ZLOGE(LOG_LABEL, "requires 1 parameter");
1172         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1173     }
1174 
1175     napi_valuetype valueType = napi_null;
1176     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1177     if (valueType != napi_number) {
1178         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1179         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1180     }
1181 
1182     uint32_t value = 0;
1183     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
1184 
1185     NAPI_MessageSequence *napiSequence = nullptr;
1186     napi_unwrap(env, thisVar, (void **)&napiSequence);
1187     if (napiSequence == nullptr) {
1188         ZLOGE(LOG_LABEL, "napiSequence is null");
1189         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1190     }
1191 
1192     bool result = napiSequence->nativeParcel_->SetDataSize(static_cast<size_t>(value));
1193     if (!result) {
1194         ZLOGE(LOG_LABEL, "set data size failed");
1195     }
1196     napi_value napiValue = nullptr;
1197     napi_get_undefined(env, &napiValue);
1198     return napiValue;
1199 }
1200 
JS_setCapacity(napi_env env,napi_callback_info info)1201 napi_value NAPI_MessageSequence::JS_setCapacity(napi_env env, napi_callback_info info)
1202 {
1203     size_t argc = 1;
1204     napi_value argv[ARGV_LENGTH_1] = {0};
1205     napi_value thisVar = nullptr;
1206     void *data = nullptr;
1207     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1208     if (argc != REQUIRED_ARGS_COUNT_1) {
1209         ZLOGE(LOG_LABEL, "requires 1 parameter");
1210         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1211     }
1212 
1213     napi_valuetype valueType = napi_null;
1214     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1215     if (valueType != napi_number) {
1216         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1217         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1218     }
1219 
1220     uint32_t value = 0;
1221     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &value);
1222 
1223     NAPI_MessageSequence *napiSequence = nullptr;
1224     napi_unwrap(env, thisVar, (void **)&napiSequence);
1225     if (napiSequence == nullptr) {
1226         ZLOGE(LOG_LABEL, "napiSequence is null");
1227         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1228     }
1229 
1230     bool result = napiSequence->nativeParcel_->SetDataCapacity(static_cast<size_t>(value));
1231     if (result) {
1232         napiSequence->maxCapacityToWrite_ = value;
1233     } else {
1234         ZLOGE(LOG_LABEL, "set data capacity failed");
1235         return napiErr.ThrowError(env, errorDesc::PARCEL_MEMORY_ALLOC_ERROR);
1236     }
1237     napi_value napiValue = nullptr;
1238     napi_get_undefined(env, &napiValue);
1239     return napiValue;
1240 }
1241 
JS_getWritableBytes(napi_env env,napi_callback_info info)1242 napi_value NAPI_MessageSequence::JS_getWritableBytes(napi_env env, napi_callback_info info)
1243 {
1244     size_t argc = 0;
1245     napi_value thisVar = nullptr;
1246     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1247 
1248     NAPI_MessageSequence *napiSequence = nullptr;
1249     napi_unwrap(env, thisVar, (void **)&napiSequence);
1250     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1251 
1252     size_t value = napiSequence->nativeParcel_->GetWritableBytes();
1253     napi_value napiValue = nullptr;
1254     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
1255     return napiValue;
1256 }
1257 
JS_getWritePosition(napi_env env,napi_callback_info info)1258 napi_value NAPI_MessageSequence::JS_getWritePosition(napi_env env, napi_callback_info info)
1259 {
1260     size_t argc = 0;
1261     napi_value thisVar = nullptr;
1262     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1263 
1264     NAPI_MessageSequence *napiSequence = nullptr;
1265     napi_unwrap(env, thisVar, (void **)&napiSequence);
1266     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1267 
1268     size_t value = napiSequence->nativeParcel_->GetWritePosition();
1269     napi_value napiValue = nullptr;
1270     NAPI_CALL(env, napi_create_uint32(env, value, &napiValue));
1271     return napiValue;
1272 }
1273 
JS_rewindWrite(napi_env env,napi_callback_info info)1274 napi_value NAPI_MessageSequence::JS_rewindWrite(napi_env env, napi_callback_info info)
1275 {
1276     size_t argc = 1;
1277     napi_value argv[ARGV_LENGTH_1] = {0};
1278     napi_value thisVar = nullptr;
1279     void *data = nullptr;
1280     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1281     if (argc != 1) {
1282         ZLOGE(LOG_LABEL, "requires 1 parameters");
1283         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1284     }
1285 
1286     napi_valuetype valueType = napi_null;
1287     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1288     if (valueType != napi_number) {
1289         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1290         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1291     }
1292 
1293     uint32_t pos = 0;
1294     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &pos);
1295 
1296     NAPI_MessageSequence *napiSequence = nullptr;
1297     napi_unwrap(env, thisVar, (void **)&napiSequence);
1298     if (napiSequence == nullptr) {
1299         ZLOGE(LOG_LABEL, "napiSequence is null");
1300         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1301     }
1302 
1303     bool result = napiSequence->nativeParcel_->RewindWrite(static_cast<size_t>(pos));
1304     NAPI_ASSERT(env, result == true, "rewind write failed");
1305     napi_value napiValue = nullptr;
1306     napi_get_undefined(env, &napiValue);
1307     return napiValue;
1308 }
1309 
JS_writeNoException(napi_env env,napi_callback_info info)1310 napi_value NAPI_MessageSequence::JS_writeNoException(napi_env env, napi_callback_info info)
1311 {
1312     napi_value thisVar = nullptr;
1313     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1314     NAPI_MessageSequence *napiSequence = nullptr;
1315     napi_unwrap(env, thisVar, (void **)&napiSequence);
1316     if (napiSequence == nullptr) {
1317         ZLOGE(LOG_LABEL, "napiSequence is null");
1318         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1319     }
1320     bool writeResult = napiSequence->nativeParcel_->WriteInt32(0);
1321     if (writeResult == false) {
1322         ZLOGE(LOG_LABEL, "write int32 failed");
1323         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1324     }
1325     napi_value result = nullptr;
1326     napi_get_undefined(env, &result);
1327     return result;
1328 }
1329 
JS_checkReadArrayArgs(napi_env env,napi_callback_info info,size_t & argc,napi_value & thisVar,napi_value * argv)1330 napi_value NAPI_MessageSequence::JS_checkReadArrayArgs(napi_env env,
1331                                                        napi_callback_info info,
1332                                                        size_t &argc,
1333                                                        napi_value &thisVar,
1334                                                        napi_value* argv)
1335 {
1336     if (argv == nullptr) {
1337         ZLOGE(LOG_LABEL, "argv is nullptr");
1338         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1339     }
1340     if (argc != 1) {
1341         ZLOGE(LOG_LABEL, "requires 1 parameters");
1342         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1343     }
1344     void *data = nullptr;
1345     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1346 
1347     bool isArray = false;
1348     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1349     if (!isArray) {
1350         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1351         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1352     }
1353 
1354     napi_value napiValue = nullptr;
1355     napi_get_undefined(env, &napiValue);
1356     return napiValue;
1357 }
1358 
JS_readParcelableArrayCallJsFunc(napi_env env,napi_value & element,napi_value & thisVar)1359 napi_value NAPI_MessageSequence::JS_readParcelableArrayCallJsFunc(napi_env env,
1360     napi_value &element, napi_value &thisVar)
1361 {
1362     napi_value propKey = nullptr;
1363     const char *propKeyStr = "unmarshalling";
1364     napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
1365     napi_value prop = nullptr;
1366     napi_get_property(env, element, propKey, &prop);
1367 
1368     napi_value funcArg[1] = { thisVar };
1369     napi_value callResult = nullptr;
1370     napi_call_function(env, element, prop, 1, funcArg, &callResult);
1371     if (callResult == nullptr) {
1372         return napiErr.ThrowError(env, errorDesc::CALL_JS_METHOD_ERROR);
1373     }
1374 
1375     napi_value retValue = nullptr;
1376     napi_get_undefined(env, &retValue);
1377     return retValue;
1378 }
1379 
JS_create(napi_env env,napi_callback_info info)1380 napi_value NAPI_MessageSequence::JS_create(napi_env env, napi_callback_info info)
1381 {
1382     // new native sequence object
1383     napi_value global = nullptr;
1384     napi_status status = napi_get_global(env, &global);
1385     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
1386     napi_value constructor = nullptr;
1387     status = napi_get_named_property(env, global, "IPCSequenceConstructor_", &constructor);
1388     NAPI_ASSERT(env, status == napi_ok, "get message sequence constructor failed");
1389     napi_value jsMessageSequence;
1390     status = napi_new_instance(env, constructor, 0, nullptr, &jsMessageSequence);
1391     NAPI_ASSERT(env, status == napi_ok, "failed to  construct js MessageSequence");
1392     return jsMessageSequence;
1393 }
1394 
JS_reclaim(napi_env env,napi_callback_info info)1395 napi_value NAPI_MessageSequence::JS_reclaim(napi_env env, napi_callback_info info)
1396 {
1397     size_t argc = 0;
1398     napi_value thisVar = nullptr;
1399     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1400 
1401     NAPI_MessageSequence *napiSequence = nullptr;
1402     napi_remove_wrap(env, thisVar, (void **)&napiSequence);
1403     NAPI_ASSERT(env, napiSequence != nullptr, "napiSequence is null");
1404     delete napiSequence;
1405 
1406     napi_value result = nullptr;
1407     napi_get_undefined(env, &result);
1408     return result;
1409 }
1410 
JS_writeRemoteObject(napi_env env,napi_callback_info info)1411 napi_value NAPI_MessageSequence::JS_writeRemoteObject(napi_env env, napi_callback_info info)
1412 {
1413     size_t argc = 1;
1414     napi_value argv[ARGV_LENGTH_1] = {0};
1415     napi_value thisVar = nullptr;
1416     void *data = nullptr;
1417     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1418     if (argc != REQUIRED_ARGS_COUNT_1) {
1419         ZLOGE(LOG_LABEL, "requires 1 parameter");
1420         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1421     }
1422     napi_valuetype valueType = napi_null;
1423     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1424     if (valueType != napi_object) {
1425         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1426         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1427     }
1428     sptr<IRemoteObject> remoteObject = NAPI_ohos_rpc_getNativeRemoteObject(env, argv[ARGV_INDEX_0]);
1429     if (remoteObject == nullptr) {
1430         ZLOGE(LOG_LABEL, "remote object is nullptr");
1431         return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
1432     }
1433     NAPI_MessageSequence *napiSequence = nullptr;
1434     napi_unwrap(env, thisVar, (void **)&napiSequence);
1435     if (napiSequence == nullptr) {
1436         ZLOGE(LOG_LABEL, "napiSequence is null");
1437         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1438     }
1439     bool writeResult = napiSequence->nativeParcel_->WriteRemoteObject(remoteObject);
1440     if (writeResult == false) {
1441         ZLOGE(LOG_LABEL, "write remote object failed");
1442         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1443     }
1444     napi_value result = nullptr;
1445     napi_get_undefined(env, &result);
1446     return result;
1447 }
1448 
JS_writeInterfaceToken(napi_env env,napi_callback_info info)1449 napi_value NAPI_MessageSequence::JS_writeInterfaceToken(napi_env env, napi_callback_info info)
1450 {
1451     size_t argc = 1;
1452     napi_value argv[ARGV_LENGTH_1] = {0};
1453     napi_value thisVar = nullptr;
1454     void *data = nullptr;
1455     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1456     if (argc != REQUIRED_ARGS_COUNT_1) {
1457         ZLOGE(LOG_LABEL, "requires 1 parameter");
1458         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1459     }
1460     napi_valuetype valueType = napi_null;
1461     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1462     if (valueType != napi_string) {
1463         ZLOGE(LOG_LABEL, "type mismatch for parameter");
1464         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1465     }
1466     size_t bufferSize = 0;
1467     size_t maxSize = MAX_BYTES_LENGTH;
1468     napi_get_value_string_utf16(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
1469     if (bufferSize >= maxSize) {
1470         ZLOGE(LOG_LABEL, "string length too large");
1471         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1472     }
1473     char16_t stringValue[bufferSize + 1];
1474     size_t jsStringLength = 0;
1475     napi_get_value_string_utf16(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
1476     if (jsStringLength != bufferSize) {
1477         ZLOGE(LOG_LABEL, "string length wrong");
1478         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1479     }
1480 
1481     NAPI_MessageSequence *napiSequence = nullptr;
1482     napi_unwrap(env, thisVar, (void **)&napiSequence);
1483     if (napiSequence == nullptr) {
1484         ZLOGE(LOG_LABEL, "napiSequence is null");
1485         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1486     }
1487 
1488     bool writeResult = napiSequence->nativeParcel_->WriteInterfaceToken(stringValue);
1489     if (writeResult == false) {
1490         ZLOGE(LOG_LABEL, "write interface token failed");
1491         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1492     }
1493     napi_value result = nullptr;
1494     napi_get_undefined(env, &result);
1495     return result;
1496 }
1497 
JS_CloseFileDescriptor(napi_env env,napi_callback_info info)1498 napi_value NAPI_MessageSequence::JS_CloseFileDescriptor(napi_env env, napi_callback_info info)
1499 {
1500     size_t argc = 1;
1501     napi_value argv[ARGV_LENGTH_1] = {0};
1502     napi_value thisVar = nullptr;
1503     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1504     if (argc != 1) {
1505         ZLOGE(LOG_LABEL, "requires 1 parameters");
1506         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1507     }
1508     napi_valuetype valueType = napi_null;
1509     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1510     if (valueType != napi_number) {
1511         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1512         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1513     }
1514     int32_t fd = -1;
1515     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
1516     close(fd);
1517     napi_value result = nullptr;
1518     napi_get_undefined(env, &result);
1519     return result;
1520 }
1521 
JS_DupFileDescriptor(napi_env env,napi_callback_info info)1522 napi_value NAPI_MessageSequence::JS_DupFileDescriptor(napi_env env, napi_callback_info info)
1523 {
1524     size_t argc = 1;
1525     napi_value argv[ARGV_LENGTH_1] = {0};
1526     napi_value thisVar = nullptr;
1527     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1528     if (argc != 1) {
1529         ZLOGE(LOG_LABEL, "requires 1 parameters");
1530         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1531     }
1532     napi_valuetype valueType = napi_null;
1533     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1534     if (valueType != napi_number) {
1535         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1536         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1537     }
1538     int32_t fd = -1;
1539     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
1540     int32_t dupResult = dup(fd);
1541     if (dupResult < 0) {
1542         ZLOGE(LOG_LABEL, "os dup function failed");
1543         return napiErr.ThrowError(env, errorDesc::OS_DUP_ERROR);
1544     }
1545     napi_value napiValue;
1546     napi_create_int32(env, dupResult, &napiValue);
1547     return napiValue;
1548 }
1549 
JS_ContainFileDescriptors(napi_env env,napi_callback_info info)1550 napi_value NAPI_MessageSequence::JS_ContainFileDescriptors(napi_env env, napi_callback_info info)
1551 {
1552     size_t argc = 0;
1553     napi_value thisVar = nullptr;
1554     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1555     NAPI_MessageSequence *napiSequence = nullptr;
1556     napi_unwrap(env, thisVar, (void **)&napiSequence);
1557     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1558     bool result = napiSequence->nativeParcel_->ContainFileDescriptors();
1559     napi_value napiValue = nullptr;
1560     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
1561     return napiValue;
1562 }
1563 
JS_WriteFileDescriptor(napi_env env,napi_callback_info info)1564 napi_value NAPI_MessageSequence::JS_WriteFileDescriptor(napi_env env, napi_callback_info info)
1565 {
1566     size_t argc = 1;
1567     napi_value argv[ARGV_LENGTH_1] = {0};
1568     napi_value thisVar = nullptr;
1569     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1570     if (argc != 1) {
1571         ZLOGE(LOG_LABEL, "requires 1 parameters");
1572         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1573     }
1574     napi_valuetype valueType = napi_null;
1575     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1576     if (valueType != napi_number) {
1577         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1578         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1579     }
1580     int32_t fd = -1;
1581     napi_get_value_int32(env, argv[ARGV_INDEX_0], &fd);
1582     NAPI_MessageSequence *napiSequence = nullptr;
1583     napi_unwrap(env, thisVar, (void **)&napiSequence);
1584     if (napiSequence == nullptr) {
1585         ZLOGE(LOG_LABEL, "napiSequence is null");
1586         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1587     }
1588     bool result = napiSequence->nativeParcel_->WriteFileDescriptor(fd);
1589     if (!result) {
1590         ZLOGE(LOG_LABEL, "write file descriptor failed");
1591         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1592     }
1593     napi_value napiValue = nullptr;
1594     napi_get_undefined(env, &napiValue);
1595     return napiValue;
1596 }
1597 
JS_WriteAshmem(napi_env env,napi_callback_info info)1598 napi_value NAPI_MessageSequence::JS_WriteAshmem(napi_env env, napi_callback_info info)
1599 {
1600     size_t argc = 1;
1601     napi_value argv[ARGV_LENGTH_1] = {0};
1602     napi_value thisVar = nullptr;
1603     void *data = nullptr;
1604     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
1605     if (argc != 1) {
1606         ZLOGE(LOG_LABEL, "requires 1 parameters");
1607         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1608     }
1609     // check type is Ashmem
1610     napi_value global = nullptr;
1611     napi_value napiValue = nullptr;
1612     napi_get_undefined(env, &napiValue);
1613     napi_status status = napi_get_global(env, &global);
1614     if (status != napi_ok) {
1615         ZLOGE(LOG_LABEL, "get napi global failed");
1616         return napiValue;
1617     }
1618     napi_value constructor = nullptr;
1619     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
1620     if (status != napi_ok) {
1621         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
1622         return napiValue;
1623     }
1624     bool isAshmem = false;
1625     napi_instanceof(env, argv[ARGV_INDEX_0], constructor, &isAshmem);
1626     if (!isAshmem) {
1627         ZLOGE(LOG_LABEL, "parameter is not instanceof Ashmem");
1628         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1629     }
1630     NAPIAshmem *napiAshmem = nullptr;
1631     napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&napiAshmem);
1632     if (napiAshmem == nullptr) {
1633         ZLOGE(LOG_LABEL, "napiAshmem is null");
1634         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1635     }
1636     sptr<Ashmem> nativeAshmem = napiAshmem->GetAshmem();
1637     NAPI_MessageSequence *napiSequence = nullptr;
1638     napi_unwrap(env, thisVar, (void **)&napiSequence);
1639     if (napiSequence == nullptr) {
1640         ZLOGE(LOG_LABEL, "napiSequence is null");
1641         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1642     }
1643     bool result = napiSequence->nativeParcel_->WriteAshmem(nativeAshmem);
1644     if (!result) {
1645         ZLOGE(LOG_LABEL, "write ashmem failed");
1646         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1647     }
1648     return napiValue;
1649 }
1650 
JS_checkWriteRawDataArgs(napi_env env,size_t argc,napi_value * argv)1651 napi_value NAPI_MessageSequence::JS_checkWriteRawDataArgs(napi_env env, size_t argc, napi_value* argv)
1652 {
1653     if (argv == nullptr) {
1654         ZLOGE(LOG_LABEL, "argv is nullptr");
1655         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1656     }
1657     size_t expectedArgc = 2;
1658     if (argc != expectedArgc) {
1659         ZLOGE(LOG_LABEL, "requires 2 parameters");
1660         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1661     }
1662     bool isArray = false;
1663     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1664     if (!isArray) {
1665         bool isTypedArray = false;
1666         napi_is_typedarray(env, argv[ARGV_INDEX_0], &isTypedArray);
1667         if (!isTypedArray) {
1668             ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not array, not typedarray");
1669             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1670         }
1671     }
1672 
1673     napi_valuetype valueType = napi_null;
1674     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1675     if (valueType != napi_number) {
1676         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1677         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1678     }
1679 
1680     napi_value napiValue = nullptr;
1681     napi_get_undefined(env, &napiValue);
1682     return napiValue;
1683 }
1684 
JS_WriteRawDataForArray(napi_env env,napi_value jsArray,uint32_t size,NAPI_MessageSequence * napiSequence)1685 bool NAPI_MessageSequence::JS_WriteRawDataForArray(napi_env env, napi_value jsArray,
1686     uint32_t size, NAPI_MessageSequence *napiSequence)
1687 {
1688     std::vector<int32_t> array;
1689     uint32_t length = 0;
1690     napi_get_array_length(env, jsArray, &length);
1691     for (uint32_t i = 0; i < length; i++) {
1692         bool hasElement = false;
1693         napi_has_element(env, jsArray, i, &hasElement);
1694         if (!hasElement) {
1695             ZLOGE(LOG_LABEL, "parameter check error");
1696             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1697         }
1698 
1699         napi_value element = nullptr;
1700         napi_get_element(env, jsArray, i, &element);
1701 
1702         int32_t value = 0;
1703         napi_get_value_int32(env, element, &value);
1704         array.push_back(value);
1705     }
1706     if (length < size) {
1707         uint32_t padSize = size - length;
1708         ZLOGW(LOG_LABEL, "array length:%{public}u less than parameter size:%{public}u"
1709             " need pad:%{public}u 0", length, size, padSize);
1710         for (uint32_t i = 0; i < padSize; i++) {
1711             array.push_back(0);
1712         }
1713     }
1714     return napiSequence->nativeParcel_->WriteRawData(array.data(), size * BYTE_SIZE_32);
1715 }
1716 
JS_WriteRawDataForTypedArray(napi_env env,napi_value jsTypedArray,size_t size,NAPI_MessageSequence * napiSequence)1717 bool NAPI_MessageSequence::JS_WriteRawDataForTypedArray(napi_env env, napi_value jsTypedArray,
1718     size_t size, NAPI_MessageSequence *napiSequence)
1719 {
1720     napi_typedarray_type type;
1721     char *data = nullptr;
1722     size_t arrayLength = 0;
1723     napi_value arrayBuffer;
1724     size_t byteOffset = 0;
1725     napi_status isGet = napi_get_typedarray_info(env, jsTypedArray, &type,
1726         &arrayLength, (void **)&data, &arrayBuffer, &byteOffset);
1727     if (isGet != napi_ok || type != napi_int32_array) {
1728         ZLOGE(LOG_LABEL, "typedarray get info failed or not napi_int32_array");
1729         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1730     }
1731     if (arrayLength < size) {
1732         ZLOGE(LOG_LABEL, "typedarray length:%{public}zu less than parameter size:%{public}zu",
1733             arrayLength, size);
1734         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1735     }
1736     return napiSequence->nativeParcel_->WriteRawData(data - byteOffset, BYTE_SIZE_32 * size);
1737 }
1738 
JS_WriteRawData(napi_env env,napi_callback_info info)1739 napi_value NAPI_MessageSequence::JS_WriteRawData(napi_env env, napi_callback_info info)
1740 {
1741     size_t argc = 2;
1742     napi_value argv[ARGV_LENGTH_2] = {0};
1743     napi_value thisVar = nullptr;
1744     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1745     napi_value checkArgsResult = JS_checkWriteRawDataArgs(env, argc, argv);
1746     if (checkArgsResult == nullptr) {
1747         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1748         return checkArgsResult;
1749     }
1750 
1751     NAPI_MessageSequence *napiSequence = nullptr;
1752     napi_unwrap(env, thisVar, (void **)&napiSequence);
1753     if (napiSequence == nullptr) {
1754         ZLOGE(LOG_LABEL, "napiSequence is null");
1755         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1756     }
1757 
1758     int32_t size = 0;
1759     napi_status isGetOk = napi_get_value_int32(env, argv[ARGV_INDEX_1], &size);
1760     if (isGetOk != napi_ok || size <= 0) {
1761         ZLOGE(LOG_LABEL, "error for parameter 2 size is %{public}d, get failed", size);
1762         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1763     }
1764     bool result = false;
1765     bool isArray = false;
1766     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
1767     if (isArray) {
1768         result = JS_WriteRawDataForArray(env, argv[ARGV_INDEX_0], static_cast<uint32_t>(size), napiSequence);
1769     } else {
1770         result = JS_WriteRawDataForTypedArray(env, argv[ARGV_INDEX_0], static_cast<size_t>(size), napiSequence);
1771     }
1772 
1773     if (!result) {
1774         ZLOGE(LOG_LABEL, "write raw data failed");
1775         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1776     }
1777     napi_value napiValue = nullptr;
1778     napi_get_undefined(env, &napiValue);
1779     return napiValue;
1780 }
1781 
JS_WriteRawDataBuffer(napi_env env,napi_callback_info info)1782 napi_value NAPI_MessageSequence::JS_WriteRawDataBuffer(napi_env env, napi_callback_info info)
1783 {
1784     size_t argc = ARGV_LENGTH_2;
1785     napi_value argv[ARGV_LENGTH_2] = {0};
1786     napi_value thisVar = nullptr;
1787     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1788     if (argc != ARGV_LENGTH_2) {
1789         ZLOGE(LOG_LABEL, "requires 2 parameters");
1790         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1791     }
1792 
1793     bool isArrayBuffer = false;
1794     napi_is_arraybuffer(env, argv[ARGV_INDEX_0], &isArrayBuffer);
1795     if (!isArrayBuffer) {
1796         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not ArrayBuffer");
1797         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1798     }
1799 
1800     napi_valuetype valueType = napi_null;
1801     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1802     if (valueType != napi_number) {
1803         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1804         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1805     }
1806 
1807     void *data = nullptr;
1808     size_t byteLength = 0;
1809     napi_status isGet = napi_get_arraybuffer_info(env, argv[ARGV_INDEX_0], (void **)&data, &byteLength);
1810     if (isGet != napi_ok) {
1811         ZLOGE(LOG_LABEL, "arraybuffery get info failed");
1812         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1813     }
1814 
1815     int64_t size = 0;
1816     napi_status isGetOk = napi_get_value_int64(env, argv[ARGV_INDEX_1], &size);
1817     if (isGetOk != napi_ok || size <= 0 || static_cast<size_t>(size) > byteLength) {
1818         ZLOGE(LOG_LABEL, "error for parameter 2 size is %{public}" PRId64, size);
1819         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1820     }
1821 
1822     NAPI_MessageSequence *napiSequence = nullptr;
1823     napi_unwrap(env, thisVar, (void **)&napiSequence);
1824     if (napiSequence == nullptr) {
1825         ZLOGE(LOG_LABEL, "napiSequence is null");
1826         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1827     }
1828 
1829     if (!napiSequence->nativeParcel_->WriteRawData(data, size)) {
1830         ZLOGE(LOG_LABEL, "write raw data failed");
1831         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1832     }
1833 
1834     napi_value napiValue = nullptr;
1835     napi_get_undefined(env, &napiValue);
1836     return napiValue;
1837 }
1838 
JS_GetRawDataCapacity(napi_env env,napi_callback_info info)1839 napi_value NAPI_MessageSequence::JS_GetRawDataCapacity(napi_env env, napi_callback_info info)
1840 {
1841     size_t argc = 0;
1842     napi_value thisVar = nullptr;
1843     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
1844     NAPI_MessageSequence *napiSequence = nullptr;
1845     napi_unwrap(env, thisVar, (void **)&napiSequence);
1846     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
1847     uint32_t result = napiSequence->nativeParcel_->GetRawDataCapacity();
1848     napi_value napiValue;
1849     napi_create_uint32(env, result, &napiValue);
1850     return napiValue;
1851 }
1852 
JS_checkWriteArrayBufferArgs(napi_env env,size_t argc,napi_value * argv)1853 napi_value NAPI_MessageSequence::JS_checkWriteArrayBufferArgs(napi_env env, size_t argc, napi_value* argv)
1854 {
1855     if (argv == nullptr) {
1856         ZLOGE(LOG_LABEL, "argv is nullptr");
1857         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1858     }
1859     if (argc != ARGV_LENGTH_2) {
1860         ZLOGE(LOG_LABEL, "requires 2 parameter");
1861         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1862     }
1863 
1864     bool isArrayBuffer = false;
1865     napi_status status = napi_is_arraybuffer(env, argv[ARGV_INDEX_0], &isArrayBuffer);
1866     if (!isArrayBuffer) {
1867         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not ArrayBuffer. status:%{public}d", status);
1868         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1869     }
1870 
1871     napi_valuetype valuetype = napi_null;
1872     status = napi_typeof(env, argv[ARGV_INDEX_1], &valuetype);
1873     if (valuetype != napi_number) {
1874         ZLOGE(LOG_LABEL, "type mismatch for parameter 2, not number. status:%{public}d", status);
1875         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1876     }
1877 
1878     int32_t typeCode = 0;
1879     napi_get_value_int32(env, argv[ARGV_INDEX_1], &typeCode);
1880     if (typeCode < INT8_ARRAY || typeCode > BIGUINT64_ARRAY) {
1881         ZLOGE(LOG_LABEL, "the value of parameter 2 is out of range. typeCode:%{public}d", typeCode);
1882         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1883     }
1884 
1885     napi_value napiValue = nullptr;
1886     napi_get_undefined(env, &napiValue);
1887     return napiValue;
1888 }
1889 
1890 template<typename T>
BufferToVector(void * data,size_t byteLength)1891 static std::vector<T> BufferToVector(void *data, size_t byteLength)
1892 {
1893     const T* dataPtr = reinterpret_cast<const T*>(data);
1894     std::vector<T> vec;
1895     std::copy(dataPtr, dataPtr + byteLength / sizeof(T), std::back_inserter(vec));
1896     return vec;
1897 }
1898 
JS_writeArrayBuffer(napi_env env,napi_callback_info info)1899 napi_value NAPI_MessageSequence::JS_writeArrayBuffer(napi_env env, napi_callback_info info)
1900 {
1901     size_t argc = ARGV_LENGTH_2;
1902     napi_value argv[ARGV_LENGTH_2] = {0};
1903     napi_value thisVar = nullptr;
1904     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1905     napi_value checkArgsResult = JS_checkWriteArrayBufferArgs(env, argc, argv);
1906     if (checkArgsResult == nullptr) {
1907         ZLOGE(LOG_LABEL, "checkArgsResult is null");
1908         return checkArgsResult;
1909     }
1910 
1911     void *data = nullptr;
1912     size_t byteLength = 0;
1913     napi_status getStatus = napi_get_arraybuffer_info(env, argv[ARGV_INDEX_0], (void **)&data, &byteLength);
1914     if (getStatus != napi_ok) {
1915         ZLOGE(LOG_LABEL, "arraybuffer get info failed. getStatus:%{public}d", getStatus);
1916         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1917     }
1918     if (data == nullptr) {
1919         ZLOGE(LOG_LABEL, "data is null");
1920         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1921     }
1922 
1923     NAPI_MessageSequence *napiSequence = nullptr;
1924     napi_unwrap(env, thisVar, (void **)&napiSequence);
1925     if (napiSequence == nullptr) {
1926         ZLOGE(LOG_LABEL, "napiSequence is null");
1927         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1928     }
1929 
1930     CHECK_WRITE_CAPACITY(env, byteLength, napiSequence);
1931 
1932     int32_t typeCode = 0;
1933     napi_get_value_int32(env, argv[ARGV_INDEX_1], &typeCode);
1934 
1935     bool writeSuccess = JS_writeVectorByTypeCode(typeCode, data, byteLength, napiSequence);
1936     if (!writeSuccess) {
1937         ZLOGE(LOG_LABEL, "write buffer failed");
1938         return napiErr.ThrowError(env, errorDesc::WRITE_DATA_TO_MESSAGE_SEQUENCE_ERROR);
1939     }
1940 
1941     napi_value napiValue = nullptr;
1942     napi_get_undefined(env, &napiValue);
1943     return napiValue;
1944 }
1945 
JS_writeVectorByTypeCode(int32_t typeCode,void * data,size_t byteLength,NAPI_MessageSequence * napiSequence)1946 bool NAPI_MessageSequence::JS_writeVectorByTypeCode(int32_t typeCode,
1947                                                     void *data,
1948                                                     size_t byteLength,
1949                                                     NAPI_MessageSequence *napiSequence)
1950 {
1951     if (data == nullptr || napiSequence == nullptr) {
1952         ZLOGE(LOG_LABEL, "data or napiSequence is null");
1953         return false;
1954     }
1955     switch (typeCode) {
1956         case INT8_ARRAY: {
1957             return napiSequence->nativeParcel_->WriteInt8Vector(BufferToVector<int8_t>(data, byteLength));
1958         }
1959         case UINT8_ARRAY: {
1960             return napiSequence->nativeParcel_->WriteUInt8Vector(BufferToVector<uint8_t>(data, byteLength));
1961         }
1962         case INT16_ARRAY: {
1963             return napiSequence->nativeParcel_->WriteInt16Vector(BufferToVector<int16_t>(data, byteLength));
1964         }
1965         case UINT16_ARRAY: {
1966             return napiSequence->nativeParcel_->WriteUInt16Vector(BufferToVector<uint16_t>(data, byteLength));
1967         }
1968         case INT32_ARRAY: {
1969             return napiSequence->nativeParcel_->WriteInt32Vector(BufferToVector<int32_t>(data, byteLength));
1970         }
1971         case UINT32_ARRAY: {
1972             return napiSequence->nativeParcel_->WriteUInt32Vector(BufferToVector<uint32_t>(data, byteLength));
1973         }
1974         case FLOAT32_ARRAY: {
1975             return napiSequence->nativeParcel_->WriteFloatVector(BufferToVector<float>(data, byteLength));
1976         }
1977         case FLOAT64_ARRAY: {
1978             return napiSequence->nativeParcel_->WriteDoubleVector(BufferToVector<double>(data, byteLength));
1979         }
1980         case BIGINT64_ARRAY: {
1981             return napiSequence->nativeParcel_->WriteInt64Vector(BufferToVector<int64_t>(data, byteLength));
1982         }
1983         case BIGUINT64_ARRAY: {
1984             return napiSequence->nativeParcel_->WriteUInt64Vector(BufferToVector<uint64_t>(data, byteLength));
1985         }
1986         default:
1987             ZLOGE(LOG_LABEL, "unsupported typeCode:%{public}d", typeCode);
1988             return false;
1989     }
1990 }
1991 
Export(napi_env env,napi_value exports)1992 napi_value NAPI_MessageSequence::Export(napi_env env, napi_value exports)
1993 {
1994     const std::string className = "MessageSequence";
1995     napi_value typeCode = CreateTypeCodeEnum(env);
1996     napi_property_descriptor properties[] = {
1997         DECLARE_NAPI_STATIC_FUNCTION("create", NAPI_MessageSequence::JS_create),
1998         DECLARE_NAPI_FUNCTION("reclaim", NAPI_MessageSequence::JS_reclaim),
1999         DECLARE_NAPI_FUNCTION("writeRemoteObject", NAPI_MessageSequence::JS_writeRemoteObject),
2000         DECLARE_NAPI_FUNCTION("readRemoteObject", NAPI_MessageSequence::JS_readRemoteObject),
2001         DECLARE_NAPI_FUNCTION("writeInterfaceToken", NAPI_MessageSequence::JS_writeInterfaceToken),
2002         DECLARE_NAPI_FUNCTION("readInterfaceToken", NAPI_MessageSequence::JS_readInterfaceToken),
2003         DECLARE_NAPI_FUNCTION("getSize", NAPI_MessageSequence::JS_getSize),
2004         DECLARE_NAPI_FUNCTION("getCapacity", NAPI_MessageSequence::JS_getCapacity),
2005         DECLARE_NAPI_FUNCTION("setSize", NAPI_MessageSequence::JS_setSize),
2006         DECLARE_NAPI_FUNCTION("setCapacity", NAPI_MessageSequence::JS_setCapacity),
2007         DECLARE_NAPI_FUNCTION("getWritableBytes", NAPI_MessageSequence::JS_getWritableBytes),
2008         DECLARE_NAPI_FUNCTION("getReadableBytes", NAPI_MessageSequence::JS_getReadableBytes),
2009         DECLARE_NAPI_FUNCTION("getReadPosition", NAPI_MessageSequence::JS_getReadPosition),
2010         DECLARE_NAPI_FUNCTION("getWritePosition", NAPI_MessageSequence::JS_getWritePosition),
2011         DECLARE_NAPI_FUNCTION("rewindRead", NAPI_MessageSequence::JS_rewindRead),
2012         DECLARE_NAPI_FUNCTION("rewindWrite", NAPI_MessageSequence::JS_rewindWrite),
2013         DECLARE_NAPI_FUNCTION("writeNoException", NAPI_MessageSequence::JS_writeNoException),
2014         DECLARE_NAPI_FUNCTION("readException", NAPI_MessageSequence::JS_readException),
2015         DECLARE_NAPI_FUNCTION("writeByte", NAPI_MessageSequence::JS_writeByte),
2016         DECLARE_NAPI_FUNCTION("writeShort", NAPI_MessageSequence::JS_writeShort),
2017         DECLARE_NAPI_FUNCTION("writeInt", NAPI_MessageSequence::JS_writeInt),
2018         DECLARE_NAPI_FUNCTION("writeLong", NAPI_MessageSequence::JS_writeLong),
2019         DECLARE_NAPI_FUNCTION("writeFloat", NAPI_MessageSequence::JS_writeFloat),
2020         DECLARE_NAPI_FUNCTION("writeDouble", NAPI_MessageSequence::JS_writeDouble),
2021         DECLARE_NAPI_FUNCTION("writeBoolean", NAPI_MessageSequence::JS_writeBoolean),
2022         DECLARE_NAPI_FUNCTION("writeChar", NAPI_MessageSequence::JS_writeChar),
2023         DECLARE_NAPI_FUNCTION("writeString", NAPI_MessageSequence::JS_writeString),
2024         DECLARE_NAPI_FUNCTION("writeParcelable", NAPI_MessageSequence::JS_writeParcelable),
2025         DECLARE_NAPI_FUNCTION("writeByteArray", NAPI_MessageSequence::JS_writeByteArray),
2026         DECLARE_NAPI_FUNCTION("writeShortArray", NAPI_MessageSequence::JS_writeShortArray),
2027         DECLARE_NAPI_FUNCTION("writeIntArray", NAPI_MessageSequence::JS_writeIntArray),
2028         DECLARE_NAPI_FUNCTION("writeLongArray", NAPI_MessageSequence::JS_writeLongArray),
2029         DECLARE_NAPI_FUNCTION("writeFloatArray", NAPI_MessageSequence::JS_writeFloatArray),
2030         DECLARE_NAPI_FUNCTION("writeDoubleArray", NAPI_MessageSequence::JS_writeDoubleArray),
2031         DECLARE_NAPI_FUNCTION("writeBooleanArray", NAPI_MessageSequence::JS_writeBooleanArray),
2032         DECLARE_NAPI_FUNCTION("writeCharArray", NAPI_MessageSequence::JS_writeCharArray),
2033         DECLARE_NAPI_FUNCTION("writeStringArray", NAPI_MessageSequence::JS_writeStringArray),
2034         DECLARE_NAPI_FUNCTION("writeParcelableArray", NAPI_MessageSequence::JS_writeParcelableArray),
2035         DECLARE_NAPI_FUNCTION("writeRemoteObjectArray", NAPI_MessageSequence::JS_writeRemoteObjectArray),
2036         DECLARE_NAPI_FUNCTION("readByte", NAPI_MessageSequence::JS_readByte),
2037         DECLARE_NAPI_FUNCTION("readShort", NAPI_MessageSequence::JS_readShort),
2038         DECLARE_NAPI_FUNCTION("readInt", NAPI_MessageSequence::JS_readInt),
2039         DECLARE_NAPI_FUNCTION("readLong", NAPI_MessageSequence::JS_readLong),
2040         DECLARE_NAPI_FUNCTION("readFloat", NAPI_MessageSequence::JS_readFloat),
2041         DECLARE_NAPI_FUNCTION("readDouble", NAPI_MessageSequence::JS_readDouble),
2042         DECLARE_NAPI_FUNCTION("readBoolean", NAPI_MessageSequence::JS_readBoolean),
2043         DECLARE_NAPI_FUNCTION("readChar", NAPI_MessageSequence::JS_readChar),
2044         DECLARE_NAPI_FUNCTION("readString", NAPI_MessageSequence::JS_readString),
2045         DECLARE_NAPI_FUNCTION("readParcelable", NAPI_MessageSequence::JS_readParcelable),
2046         DECLARE_NAPI_FUNCTION("readByteArray", NAPI_MessageSequence::JS_readByteArray),
2047         DECLARE_NAPI_FUNCTION("readShortArray", NAPI_MessageSequence::JS_readShortArray),
2048         DECLARE_NAPI_FUNCTION("readIntArray", NAPI_MessageSequence::JS_readIntArray),
2049         DECLARE_NAPI_FUNCTION("readLongArray", NAPI_MessageSequence::JS_readLongArray),
2050         DECLARE_NAPI_FUNCTION("readFloatArray", NAPI_MessageSequence::JS_readFloatArray),
2051         DECLARE_NAPI_FUNCTION("readDoubleArray", NAPI_MessageSequence::JS_readDoubleArray),
2052         DECLARE_NAPI_FUNCTION("readBooleanArray", NAPI_MessageSequence::JS_readBooleanArray),
2053         DECLARE_NAPI_FUNCTION("readCharArray", NAPI_MessageSequence::JS_readCharArray),
2054         DECLARE_NAPI_FUNCTION("readStringArray", NAPI_MessageSequence::JS_readStringArray),
2055         DECLARE_NAPI_FUNCTION("readParcelableArray", NAPI_MessageSequence::JS_readParcelableArray),
2056         DECLARE_NAPI_FUNCTION("readRemoteObjectArray", NAPI_MessageSequence::JS_readRemoteObjectArray),
2057         DECLARE_NAPI_STATIC_FUNCTION("closeFileDescriptor", NAPI_MessageSequence::JS_CloseFileDescriptor),
2058         DECLARE_NAPI_STATIC_FUNCTION("dupFileDescriptor", NAPI_MessageSequence::JS_DupFileDescriptor),
2059         DECLARE_NAPI_FUNCTION("writeFileDescriptor", NAPI_MessageSequence::JS_WriteFileDescriptor),
2060         DECLARE_NAPI_FUNCTION("readFileDescriptor", NAPI_MessageSequence::JS_ReadFileDescriptor),
2061         DECLARE_NAPI_FUNCTION("containFileDescriptors", NAPI_MessageSequence::JS_ContainFileDescriptors),
2062         DECLARE_NAPI_FUNCTION("writeAshmem", NAPI_MessageSequence::JS_WriteAshmem),
2063         DECLARE_NAPI_FUNCTION("readAshmem", NAPI_MessageSequence::JS_ReadAshmem),
2064         DECLARE_NAPI_FUNCTION("getRawDataCapacity", NAPI_MessageSequence::JS_GetRawDataCapacity),
2065         DECLARE_NAPI_FUNCTION("writeRawData", NAPI_MessageSequence::JS_WriteRawData),
2066         DECLARE_NAPI_FUNCTION("readRawData", NAPI_MessageSequence::JS_ReadRawData),
2067         DECLARE_NAPI_FUNCTION("writeRawDataBuffer", NAPI_MessageSequence::JS_WriteRawDataBuffer),
2068         DECLARE_NAPI_FUNCTION("readRawDataBuffer", NAPI_MessageSequence::JS_ReadRawDataBuffer),
2069         DECLARE_NAPI_FUNCTION("writeArrayBuffer", NAPI_MessageSequence::JS_writeArrayBuffer),
2070         DECLARE_NAPI_FUNCTION("readArrayBuffer", NAPI_MessageSequence::JS_readArrayBuffer),
2071     };
2072     napi_value constructor = nullptr;
2073     napi_define_class(env, className.c_str(), className.length(), JS_constructor, nullptr,
2074         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
2075     NAPI_ASSERT(env, constructor != nullptr, "define js class MessageSequence failed");
2076     napi_status status = napi_set_named_property(env, exports, "MessageSequence", constructor);
2077     NAPI_ASSERT(env, status == napi_ok, "set property MessageSequence failed");
2078     status = napi_set_named_property(env, exports, "TypeCode", typeCode);
2079     NAPI_ASSERT(env, status == napi_ok, "set property TypeCode failed");
2080     napi_value global = nullptr;
2081     status = napi_get_global(env, &global);
2082     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
2083     status = napi_set_named_property(env, global, "IPCSequenceConstructor_", constructor);
2084     NAPI_ASSERT(env, status == napi_ok, "set message sequence constructor failed");
2085     return exports;
2086 }
2087 
JS_constructor(napi_env env,napi_callback_info info)2088 napi_value NAPI_MessageSequence::JS_constructor(napi_env env, napi_callback_info info)
2089 {
2090     napi_value thisVar = nullptr;
2091     size_t argc = 1;
2092     napi_value argv[ARGV_LENGTH_1] = {0};
2093     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
2094     NAPI_ASSERT(env, status == napi_ok, "napi get callback info failed");
2095     MessageParcel *parcel = nullptr;
2096     if (argc > 0) {
2097         napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&parcel);
2098         NAPI_ASSERT(env, parcel != nullptr, "parcel is null");
2099     }
2100     // new native parcel object
2101     auto messageSequence = new (std::nothrow) NAPI_MessageSequence(env, thisVar, parcel);
2102     NAPI_ASSERT(env, messageSequence != nullptr, "new messageSequence failed");
2103     // connect native object to js thisVar
2104     status = napi_wrap(
2105         env, thisVar, messageSequence,
2106         [](napi_env env, void *data, void *hint) {
2107             NAPI_MessageSequence *messageSequence = reinterpret_cast<NAPI_MessageSequence *>(data);
2108             if (!messageSequence->owner) {
2109                 delete messageSequence;
2110             }
2111         },
2112         nullptr, nullptr);
2113     if (status != napi_ok) {
2114         delete messageSequence;
2115         NAPI_ASSERT(env, false, "napi wrap message parcel failed");
2116     }
2117     return thisVar;
2118 }
2119 } // namespace OHOS
2120