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