1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_message_sequence.h"
17 
18 #include <cinttypes>
19 #include <cstring>
20 #include <unistd.h>
21 
22 #include "hilog/log.h"
23 #include "ipc_debug.h"
24 #include "log_tags.h"
25 #include "napi_ashmem.h"
26 #include "napi_remote_object.h"
27 #include "napi_rpc_common.h"
28 #include "string_ex.h"
29 
30 namespace OHOS {
31 using namespace OHOS::HiviewDFX;
32 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_NAPI, "NAPI_MessageSequenceRead" };
33 
JS_getSize(napi_env env,napi_callback_info info)34 napi_value NAPI_MessageSequence::JS_getSize(napi_env env, napi_callback_info info)
35 {
36     size_t argc = 0;
37     napi_value thisVar = nullptr;
38     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
39 
40     NAPI_MessageSequence *napiSequence = nullptr;
41     napi_unwrap(env, thisVar, (void **)&napiSequence);
42     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
43 
44     size_t value = napiSequence->nativeParcel_->GetDataSize();
45     napi_value napiValue = nullptr;
46     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
47     return napiValue;
48 }
49 
JS_getCapacity(napi_env env,napi_callback_info info)50 napi_value NAPI_MessageSequence::JS_getCapacity(napi_env env, napi_callback_info info)
51 {
52     size_t argc = 0;
53     napi_value thisVar = nullptr;
54     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
55 
56     NAPI_MessageSequence *napiSequence = nullptr;
57     napi_unwrap(env, thisVar, (void **)&napiSequence);
58     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
59 
60     size_t value = napiSequence->nativeParcel_->GetDataCapacity();
61     napi_value napiValue = nullptr;
62     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
63     return napiValue;
64 }
65 
JS_getReadableBytes(napi_env env,napi_callback_info info)66 napi_value NAPI_MessageSequence::JS_getReadableBytes(napi_env env, napi_callback_info info)
67 {
68     size_t argc = 0;
69     napi_value thisVar = nullptr;
70     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
71 
72     NAPI_MessageSequence *napiSequence = nullptr;
73     napi_unwrap(env, thisVar, (void **)&napiSequence);
74     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
75 
76     size_t value = napiSequence->nativeParcel_->GetReadableBytes();
77     napi_value napiValue = nullptr;
78     NAPI_CALL(env, napi_create_uint32(env, static_cast<uint32_t>(value), &napiValue));
79     return napiValue;
80 }
81 
JS_getReadPosition(napi_env env,napi_callback_info info)82 napi_value NAPI_MessageSequence::JS_getReadPosition(napi_env env, napi_callback_info info)
83 {
84     size_t argc = 0;
85     napi_value thisVar = nullptr;
86     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
87 
88     NAPI_MessageSequence *napiSequence = nullptr;
89     napi_unwrap(env, thisVar, (void **)&napiSequence);
90     NAPI_ASSERT_BASE(env, napiSequence != nullptr, "napiSequence is null", nullptr);
91 
92     size_t value = napiSequence->nativeParcel_->GetReadPosition();
93     napi_value napiValue = nullptr;
94     NAPI_CALL(env, napi_create_uint32(env, value, &napiValue));
95     return napiValue;
96 }
97 
JS_rewindRead(napi_env env,napi_callback_info info)98 napi_value NAPI_MessageSequence::JS_rewindRead(napi_env env, napi_callback_info info)
99 {
100     size_t argc = 1;
101     napi_value argv[ARGV_LENGTH_1] = {0};
102     napi_value thisVar = nullptr;
103     void *data = nullptr;
104     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
105     if (argc != 1) {
106         ZLOGE(LOG_LABEL, "requires 1 parameters");
107         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
108     }
109 
110     napi_valuetype valueType = napi_null;
111     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
112     if (valueType != napi_number) {
113         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
114         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
115     }
116 
117     uint32_t pos = 0;
118     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &pos);
119 
120     NAPI_MessageSequence *napiSequence = nullptr;
121     napi_unwrap(env, thisVar, (void **)&napiSequence);
122     if (napiSequence == nullptr) {
123         ZLOGE(LOG_LABEL, "napiSequence is null");
124         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
125     }
126 
127     bool result = napiSequence->nativeParcel_->RewindRead(static_cast<size_t>(pos));
128     NAPI_ASSERT(env, result == true, "rewind read failed");
129     napi_value napiValue = nullptr;
130     napi_get_undefined(env, &napiValue);
131     return napiValue;
132 }
133 
JS_readRemoteObject(napi_env env,napi_callback_info info)134 napi_value NAPI_MessageSequence::JS_readRemoteObject(napi_env env, napi_callback_info info)
135 {
136     size_t argc = 0;
137     napi_value thisVar = nullptr;
138     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
139 
140     NAPI_MessageSequence *napiSequence = nullptr;
141     napi_unwrap(env, thisVar, (void **)&napiSequence);
142     if (napiSequence == nullptr) {
143         ZLOGE(LOG_LABEL, "napiSequence is null");
144         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
145     }
146 
147     sptr<IRemoteObject> value = napiSequence->nativeParcel_->ReadRemoteObject();
148     napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
149     if (napiValue == nullptr) {
150         uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
151             std::chrono::steady_clock::now().time_since_epoch()).count());
152         ZLOGE(LOG_LABEL, "remote object is null time:%{public}" PRIu64, curTime);
153         return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
154     }
155     return napiValue;
156 }
157 
JS_readInterfaceToken(napi_env env,napi_callback_info info)158 napi_value NAPI_MessageSequence::JS_readInterfaceToken(napi_env env, napi_callback_info info)
159 {
160     size_t argc = 0;
161     napi_value thisVar = nullptr;
162     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
163 
164     NAPI_MessageSequence *napiSequence = nullptr;
165     napi_unwrap(env, thisVar, (void **)&napiSequence);
166     if (napiSequence == nullptr) {
167         ZLOGE(LOG_LABEL, "napiSequence is null");
168         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
169     }
170 
171     std::u16string parcelString = napiSequence->nativeParcel_->ReadInterfaceToken();
172     napi_value napiValue = nullptr;
173     napi_create_string_utf16(env, parcelString.c_str(), parcelString.length(), &napiValue);
174     return napiValue;
175 }
176 
JS_readException(napi_env env,napi_callback_info info)177 napi_value NAPI_MessageSequence::JS_readException(napi_env env, napi_callback_info info)
178 {
179     napi_value result = nullptr;
180     napi_get_undefined(env, &result);
181     napi_value thisVar = nullptr;
182     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
183     NAPI_MessageSequence *napiSequence = nullptr;
184     napi_unwrap(env, thisVar, (void **)&napiSequence);
185     if (napiSequence == nullptr) {
186         ZLOGE(LOG_LABEL, "napiSequence is null");
187         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
188     }
189 
190     int32_t code = napiSequence->nativeParcel_->ReadInt32();
191     if (code == 0) {
192         return result;
193     }
194     std::u16string str = napiSequence->nativeParcel_->ReadString16();
195     napi_throw_error(env, nullptr, Str16ToStr8(str).c_str());
196     return result;
197 }
198 
JS_readByte(napi_env env,napi_callback_info info)199 napi_value NAPI_MessageSequence::JS_readByte(napi_env env, napi_callback_info info)
200 {
201     size_t argc = 0;
202     napi_value thisVar = nullptr;
203     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
204     NAPI_MessageSequence *napiSequence = nullptr;
205     napi_unwrap(env, thisVar, (void **)&napiSequence);
206     if (napiSequence == nullptr) {
207         ZLOGE(LOG_LABEL, "napiSequence is null");
208         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
209     }
210 
211     int8_t value = napiSequence->nativeParcel_->ReadInt8();
212     napi_value napiValue = nullptr;
213     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
214     return napiValue;
215 }
216 
JS_readShort(napi_env env,napi_callback_info info)217 napi_value NAPI_MessageSequence::JS_readShort(napi_env env, napi_callback_info info)
218 {
219     size_t argc = 0;
220     napi_value thisVar = nullptr;
221     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
222     NAPI_MessageSequence *napiSequence = nullptr;
223     napi_unwrap(env, thisVar, (void **)&napiSequence);
224     if (napiSequence == nullptr) {
225         ZLOGE(LOG_LABEL, "napiSequence is null");
226         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
227     }
228 
229     int16_t value = napiSequence->nativeParcel_->ReadInt16();
230     napi_value napiValue = nullptr;
231     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
232     return napiValue;
233 }
234 
JS_readInt(napi_env env,napi_callback_info info)235 napi_value NAPI_MessageSequence::JS_readInt(napi_env env, napi_callback_info info)
236 {
237     size_t argc = 0;
238     napi_value thisVar = nullptr;
239     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
240     NAPI_MessageSequence *napiSequence = nullptr;
241     napi_unwrap(env, thisVar, (void **)&napiSequence);
242     if (napiSequence == nullptr) {
243         ZLOGE(LOG_LABEL, "napiSequence is null");
244         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
245     }
246 
247     int32_t value = napiSequence->nativeParcel_->ReadInt32();
248     napi_value napiValue = nullptr;
249     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
250     return napiValue;
251 }
252 
JS_readLong(napi_env env,napi_callback_info info)253 napi_value NAPI_MessageSequence::JS_readLong(napi_env env, napi_callback_info info)
254 {
255     size_t argc = 0;
256     napi_value thisVar = nullptr;
257     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
258     NAPI_MessageSequence *napiSequence = nullptr;
259     napi_unwrap(env, thisVar, (void **)&napiSequence);
260     if (napiSequence == nullptr) {
261         ZLOGE(LOG_LABEL, "napiSequence is null");
262         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
263     }
264 
265     int64_t value = napiSequence->nativeParcel_->ReadInt64();
266     napi_value napiValue = nullptr;
267     NAPI_CALL(env, napi_create_int64(env, value, &napiValue));
268     return napiValue;
269 }
270 
JS_readFloat(napi_env env,napi_callback_info info)271 napi_value NAPI_MessageSequence::JS_readFloat(napi_env env, napi_callback_info info)
272 {
273     size_t argc = 0;
274     napi_value thisVar = nullptr;
275     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
276     NAPI_MessageSequence *napiSequence = nullptr;
277     napi_unwrap(env, thisVar, (void **)&napiSequence);
278     if (napiSequence == nullptr) {
279         ZLOGE(LOG_LABEL, "napiSequence is null");
280         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
281     }
282 
283     double value = napiSequence->nativeParcel_->ReadDouble();
284     napi_value napiValue = nullptr;
285     NAPI_CALL(env, napi_create_double(env, value, &napiValue));
286     return napiValue;
287 }
288 
JS_readDouble(napi_env env,napi_callback_info info)289 napi_value NAPI_MessageSequence::JS_readDouble(napi_env env, napi_callback_info info)
290 {
291     // This function implementation is the same as JS_readFloat
292     return NAPI_MessageSequence::JS_readFloat(env, info);
293 }
294 
JS_readBoolean(napi_env env,napi_callback_info info)295 napi_value NAPI_MessageSequence::JS_readBoolean(napi_env env, napi_callback_info info)
296 {
297     size_t argc = 0;
298     napi_value thisVar = nullptr;
299     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
300     NAPI_MessageSequence *napiSequence = nullptr;
301     napi_unwrap(env, thisVar, (void **)&napiSequence);
302     if (napiSequence == nullptr) {
303         ZLOGE(LOG_LABEL, "napiSequence is null");
304         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
305     }
306 
307     int8_t value = napiSequence->nativeParcel_->ReadInt8();
308     napi_value napiValue = nullptr;
309     NAPI_CALL(env, napi_get_boolean(env, value, &napiValue));
310     return napiValue;
311 }
312 
JS_readChar(napi_env env,napi_callback_info info)313 napi_value NAPI_MessageSequence::JS_readChar(napi_env env, napi_callback_info info)
314 {
315     size_t argc = 0;
316     napi_value thisVar = nullptr;
317     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
318     NAPI_MessageSequence *napiSequence = nullptr;
319     napi_unwrap(env, thisVar, (void **)&napiSequence);
320     if (napiSequence == nullptr) {
321         ZLOGE(LOG_LABEL, "napiSequence is null");
322         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
323     }
324 
325     uint8_t value = napiSequence->nativeParcel_->ReadUint8();
326     napi_value result = nullptr;
327     napi_create_uint32(env, static_cast<uint32_t>(value), &result);
328     return result;
329 }
330 
JS_readString(napi_env env,napi_callback_info info)331 napi_value NAPI_MessageSequence::JS_readString(napi_env env, napi_callback_info info)
332 {
333     size_t argc = 0;
334     napi_value thisVar = nullptr;
335     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
336     NAPI_MessageSequence *napiSequence = nullptr;
337     napi_unwrap(env, thisVar, (void **)&napiSequence);
338     if (napiSequence == nullptr) {
339         ZLOGE(LOG_LABEL, "napiSequence is null");
340         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
341     }
342 
343     std::u16string parcelString = napiSequence->nativeParcel_->ReadString16();
344     napi_value napiValue = nullptr;
345     napi_create_string_utf16(env, parcelString.c_str(), parcelString.length(), &napiValue);
346     return napiValue;
347 }
348 
JS_readParcelable(napi_env env,napi_callback_info info)349 napi_value NAPI_MessageSequence::JS_readParcelable(napi_env env, napi_callback_info info)
350 {
351     size_t argc = 1;
352     napi_value argv[ARGV_LENGTH_1] = {0};
353     napi_value thisVar = nullptr;
354     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
355     if (argc != 1) {
356         ZLOGE(LOG_LABEL, "requires 1 parameters");
357         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
358     }
359 
360     NAPI_MessageSequence *napiSequence = nullptr;
361     napi_unwrap(env, thisVar, (void **)&napiSequence);
362     if (napiSequence == nullptr) {
363         ZLOGE(LOG_LABEL, "napiSequence is null");
364         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
365     }
366 
367     int32_t len = napiSequence->nativeParcel_->ReadInt32();
368     if (len > 0) {
369         napi_value propKey = nullptr;
370         const char *propKeyStr = "unmarshalling";
371         napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
372         napi_value prop = nullptr;
373         napi_get_property(env, argv[ARGV_INDEX_0], propKey, &prop);
374 
375         napi_value funcArg[1] = {thisVar};
376         napi_value callResult = nullptr;
377         napi_call_function(env, argv[ARGV_INDEX_0], prop, 1, funcArg, &callResult);
378         if (callResult != nullptr) {
379             return callResult;
380         }
381         ZLOGI(LOG_LABEL, "call unmarshalling failed");
382     }
383 
384     return napiErr.ThrowError(env, errorDesc::CALL_JS_METHOD_ERROR);
385 }
386 
JS_readByteArray(napi_env env,napi_callback_info info)387 napi_value NAPI_MessageSequence::JS_readByteArray(napi_env env, napi_callback_info info)
388 {
389     size_t argc = 0;
390     napi_value thisVar = nullptr;
391     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
392     NAPI_MessageSequence *napiSequence = nullptr;
393     napi_unwrap(env, thisVar, (void **)&napiSequence);
394     if (napiSequence == nullptr) {
395         ZLOGE(LOG_LABEL, "napiSequence is null");
396         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
397     }
398     uint32_t arrayLength = napiSequence->nativeParcel_->ReadUint32();
399 
400     if (argc > 0) {
401         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiSequence);
402         napi_value argv[ARGV_LENGTH_1] = {0};
403         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
404         if (checkArgsResult == nullptr) {
405             ZLOGE(LOG_LABEL, "checkArgsResult is null");
406             return checkArgsResult;
407         }
408 
409         for (uint32_t i = 0; i < arrayLength; i++) {
410             int8_t val = napiSequence->nativeParcel_->ReadInt8();
411             napi_value num = nullptr;
412             napi_create_int32(env, val, &num);
413             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
414         }
415         napi_value napiValue = nullptr;
416         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
417         return napiValue;
418     }
419 
420     if (arrayLength == 0) {
421         napi_value result = nullptr;
422         napi_create_array(env, &result);
423         return result;
424     }
425     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiSequence);
426     napi_value result = nullptr;
427     napi_create_array_with_length(env, (size_t)arrayLength, &result);
428     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
429         int8_t val = napiSequence->nativeParcel_->ReadInt8();
430         napi_value num = nullptr;
431         napi_create_int32(env, val, &num);
432         napi_set_element(env, result, i, num);
433     }
434     return result;
435 }
436 
JS_readShortArray(napi_env env,napi_callback_info info)437 napi_value NAPI_MessageSequence::JS_readShortArray(napi_env env, napi_callback_info info)
438 {
439     size_t argc = 0;
440     napi_value thisVar = nullptr;
441     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
442 
443     NAPI_MessageSequence *napiSequence = nullptr;
444     napi_unwrap(env, thisVar, (void **)&napiSequence);
445     if (napiSequence == nullptr) {
446         ZLOGE(LOG_LABEL, "napiSequence is null");
447         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
448     }
449 
450     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
451     if (argc > 0) {
452         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
453         napi_value argv[ARGV_LENGTH_1] = {0};
454         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
455         if (checkArgsResult == nullptr) {
456             ZLOGE(LOG_LABEL, "checkArgsResult is null");
457             return checkArgsResult;
458         }
459 
460         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
461             int16_t val = napiSequence->nativeParcel_->ReadInt16();
462             napi_value num = nullptr;
463             napi_create_int32(env, val, &num);
464             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
465         }
466         napi_value napiValue = nullptr;
467         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
468         return napiValue;
469     }
470 
471     if (arrayLength <= 0) {
472         napi_value result = nullptr;
473         napi_create_array(env, &result);
474         return result;
475     }
476     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
477     napi_value result = nullptr;
478     napi_create_array_with_length(env, (size_t)arrayLength, &result);
479 
480     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
481         int16_t val = napiSequence->nativeParcel_->ReadInt16();
482         napi_value num = nullptr;
483         napi_create_int32(env, val, &num);
484         napi_set_element(env, result, i, num);
485     }
486     return result;
487 }
488 
JS_readIntArray(napi_env env,napi_callback_info info)489 napi_value NAPI_MessageSequence::JS_readIntArray(napi_env env, napi_callback_info info)
490 {
491     size_t argc = 0;
492     napi_value thisVar = nullptr;
493     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
494 
495     NAPI_MessageSequence *napiSequence = nullptr;
496     napi_unwrap(env, thisVar, (void **)&napiSequence);
497     if (napiSequence == nullptr) {
498         ZLOGE(LOG_LABEL, "napiSequence is null");
499         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
500     }
501 
502     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
503     if (argc > 0) {
504         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
505         napi_value argv[ARGV_LENGTH_1] = {0};
506         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
507         if (checkArgsResult == nullptr) {
508             ZLOGE(LOG_LABEL, "checkArgsResult is null");
509             return checkArgsResult;
510         }
511 
512         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
513             int32_t val = napiSequence->nativeParcel_->ReadInt32();
514             napi_value num = nullptr;
515             napi_create_int32(env, val, &num);
516             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
517         }
518         napi_value napiValue = nullptr;
519         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
520         return napiValue;
521     }
522 
523     if (arrayLength <= 0) {
524         napi_value result = nullptr;
525         napi_create_array(env, &result);
526         return result;
527     }
528     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
529     napi_value result = nullptr;
530     napi_create_array_with_length(env, (size_t)arrayLength, &result);
531 
532     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
533         int32_t val = napiSequence->nativeParcel_->ReadInt32();
534         napi_value num = nullptr;
535         napi_create_int32(env, val, &num);
536         napi_set_element(env, result, i, num);
537     }
538     return result;
539 }
540 
JS_readLongArray(napi_env env,napi_callback_info info)541 napi_value NAPI_MessageSequence::JS_readLongArray(napi_env env, napi_callback_info info)
542 {
543     size_t argc = 0;
544     napi_value thisVar = nullptr;
545     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
546 
547     NAPI_MessageSequence *napiSequence = nullptr;
548     napi_unwrap(env, thisVar, (void **)&napiSequence);
549     if (napiSequence == nullptr) {
550         ZLOGE(LOG_LABEL, "napiSequence is null");
551         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
552     }
553 
554     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
555     if (argc > 0) {
556         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
557         napi_value argv[ARGV_LENGTH_1] = {0};
558         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
559         if (checkArgsResult == nullptr) {
560             ZLOGE(LOG_LABEL, "checkArgsResult is null");
561             return checkArgsResult;
562         }
563 
564         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
565             int64_t val = napiSequence->nativeParcel_->ReadInt64();
566             napi_value num = nullptr;
567             napi_create_int64(env, val, &num);
568             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
569         }
570         napi_value napiValue = nullptr;
571         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
572         return napiValue;
573     }
574 
575     if (arrayLength <= 0) {
576         napi_value result = nullptr;
577         napi_create_array(env, &result);
578         return result;
579     }
580     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_64, napiSequence);
581     napi_value result = nullptr;
582     napi_create_array_with_length(env, (size_t)arrayLength, &result);
583 
584     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
585         int64_t val = napiSequence->nativeParcel_->ReadInt64();
586         napi_value num = nullptr;
587         napi_create_int64(env, val, &num);
588         napi_set_element(env, result, i, num);
589     }
590     return result;
591 }
592 
JS_readFloatArray(napi_env env,napi_callback_info info)593 napi_value NAPI_MessageSequence::JS_readFloatArray(napi_env env, napi_callback_info info)
594 {
595     size_t argc = 0;
596     napi_value thisVar = nullptr;
597     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
598 
599     NAPI_MessageSequence *napiSequence = nullptr;
600     napi_unwrap(env, thisVar, (void **)&napiSequence);
601     if (napiSequence == nullptr) {
602         ZLOGE(LOG_LABEL, "napiSequence is null");
603         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
604     }
605 
606     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
607     if (argc > 0) {
608         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
609         napi_value argv[ARGV_LENGTH_1] = {0};
610         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
611         if (checkArgsResult == nullptr) {
612             ZLOGE(LOG_LABEL, "checkArgsResult is null");
613             return checkArgsResult;
614         }
615 
616         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
617             double val = napiSequence->nativeParcel_->ReadDouble();
618             napi_value num = nullptr;
619             napi_create_double(env, val, &num);
620             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
621         }
622         napi_value napiValue = nullptr;
623         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
624         return napiValue;
625     }
626 
627     if (arrayLength <= 0) {
628         napi_value result = nullptr;
629         napi_create_array(env, &result);
630         return result;
631     }
632     CHECK_READ_LENGTH(env, (size_t)arrayLength, sizeof(double), napiSequence);
633     napi_value result = nullptr;
634     napi_create_array_with_length(env, (size_t)arrayLength, &result);
635 
636     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
637         double val = napiSequence->nativeParcel_->ReadDouble();
638         napi_value num = nullptr;
639         napi_create_double(env, val, &num);
640         napi_set_element(env, result, i, num);
641     }
642     return result;
643 }
644 
JS_readDoubleArray(napi_env env,napi_callback_info info)645 napi_value NAPI_MessageSequence::JS_readDoubleArray(napi_env env, napi_callback_info info)
646 {
647     // This function implementation is the same as JS_readFloatArray
648     return NAPI_MessageSequence::JS_readFloatArray(env, info);
649 }
650 
651 
JS_readBooleanArray(napi_env env,napi_callback_info info)652 napi_value NAPI_MessageSequence::JS_readBooleanArray(napi_env env, napi_callback_info info)
653 {
654     size_t argc = 0;
655     napi_value thisVar = nullptr;
656     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
657 
658     NAPI_MessageSequence *napiSequence = nullptr;
659     napi_unwrap(env, thisVar, (void **)&napiSequence);
660     if (napiSequence == nullptr) {
661         ZLOGE(LOG_LABEL, "napiSequence is null");
662         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
663     }
664 
665     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
666     if (argc > 0) {
667         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
668         napi_value argv[ARGV_LENGTH_1] = {0};
669         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
670         if (checkArgsResult == nullptr) {
671             ZLOGE(LOG_LABEL, "checkArgsResult is null");
672             return checkArgsResult;
673         }
674 
675         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
676             int8_t val = napiSequence->nativeParcel_->ReadInt8();
677             napi_value boolean = nullptr;
678             napi_get_boolean(env, val, &boolean);
679             napi_set_element(env, argv[ARGV_INDEX_0], i, boolean);
680         }
681         napi_value napiValue = nullptr;
682         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
683         return napiValue;
684     }
685 
686     if (arrayLength <= 0) {
687         napi_value result = nullptr;
688         napi_create_array(env, &result);
689         return result;
690     }
691 
692     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
693     napi_value result = nullptr;
694     napi_create_array_with_length(env, (size_t)arrayLength, &result);
695 
696     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
697         int8_t val = napiSequence->nativeParcel_->ReadInt8();
698         napi_value boolean = nullptr;
699         napi_get_boolean(env, val, &boolean);
700         napi_set_element(env, result, i, boolean);
701     }
702     return result;
703 }
704 
705 
JS_readCharArray(napi_env env,napi_callback_info info)706 napi_value NAPI_MessageSequence::JS_readCharArray(napi_env env, napi_callback_info info)
707 {
708     size_t argc = 0;
709     napi_value thisVar = nullptr;
710     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
711 
712     NAPI_MessageSequence *napiSequence = nullptr;
713     napi_unwrap(env, thisVar, (void **)&napiSequence);
714     if (napiSequence == nullptr) {
715         ZLOGE(LOG_LABEL, "napiSequence is null");
716         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
717     }
718 
719     uint32_t arrayLength = napiSequence->nativeParcel_->ReadUint32();
720     if (argc > 0) {
721         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
722         napi_value argv[ARGV_LENGTH_1] = {0};
723         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
724         if (checkArgsResult == nullptr) {
725             ZLOGE(LOG_LABEL, "checkArgsResult is null");
726             return checkArgsResult;
727         }
728 
729         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
730             uint8_t val = napiSequence->nativeParcel_->ReadUint8();
731             napi_value num = nullptr;
732             napi_create_uint32(env, static_cast<uint32_t>(val), &num);
733             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
734         }
735         napi_value napiValue = nullptr;
736         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
737         return napiValue;
738     }
739 
740     if (arrayLength == 0) {
741         napi_value result = nullptr;
742         napi_create_array(env, &result);
743         return result;
744     }
745     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
746     napi_value result = nullptr;
747     napi_create_array_with_length(env, (size_t)arrayLength, &result);
748 
749     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
750         uint8_t val = napiSequence->nativeParcel_->ReadUint8();
751         napi_value num = nullptr;
752         napi_create_uint32(env, static_cast<uint32_t>(val), &num);
753         napi_set_element(env, result, i, num);
754     }
755     return result;
756 }
757 
JS_readStringArray(napi_env env,napi_callback_info info)758 napi_value NAPI_MessageSequence::JS_readStringArray(napi_env env, napi_callback_info info)
759 {
760     size_t argc = 0;
761     napi_value thisVar = nullptr;
762     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
763 
764     NAPI_MessageSequence *napiSequence = nullptr;
765     napi_unwrap(env, thisVar, (void **)&napiSequence);
766     if (napiSequence == nullptr) {
767         ZLOGE(LOG_LABEL, "napiSequence is null");
768         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
769     }
770 
771     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
772     if (argc > 0) {
773         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
774         napi_value argv[ARGV_LENGTH_1] = {0};
775         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
776         if (checkArgsResult == nullptr) {
777             ZLOGE(LOG_LABEL, "checkArgsResult is null");
778             return checkArgsResult;
779         }
780 
781         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
782             if (napiSequence->nativeParcel_->GetReadableBytes() <= 0) {
783                 break;
784             }
785             std::u16string parcelString = napiSequence->nativeParcel_->ReadString16();
786             napi_value val = nullptr;
787             napi_create_string_utf16(env, parcelString.c_str(), parcelString.length(), &val);
788             napi_set_element(env, argv[ARGV_INDEX_0], i, val);
789         }
790         napi_value napiValue = nullptr;
791         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
792         return napiValue;
793     }
794 
795     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiSequence);
796     napi_value result = nullptr;
797     napi_create_array(env, &result);
798     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
799         if (napiSequence->nativeParcel_->GetReadableBytes() <= 0) {
800             break;
801         }
802         std::u16string parcelString = napiSequence->nativeParcel_->ReadString16();
803         napi_value val = nullptr;
804         napi_create_string_utf16(env, parcelString.c_str(), parcelString.length(), &val);
805         napi_set_element(env, result, i, val);
806     }
807     return result;
808 }
809 
JS_readParcelableArray(napi_env env,napi_callback_info info)810 napi_value NAPI_MessageSequence::JS_readParcelableArray(napi_env env, napi_callback_info info)
811 {
812     size_t argc = 1;
813     napi_value thisVar = nullptr;
814     napi_value argv[ARGV_LENGTH_1] = {0};
815     napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
816     if (checkArgsResult == nullptr) {
817         ZLOGE(LOG_LABEL, "checkArgsResult is null");
818         return checkArgsResult;
819     }
820 
821     NAPI_MessageSequence *napiSequence = nullptr;
822     napi_unwrap(env, thisVar, (void **)&napiSequence);
823     if (napiSequence == nullptr) {
824         ZLOGE(LOG_LABEL, "napiSequence is null");
825         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
826     }
827 
828     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
829     // checking here is not accurate, but we can defend some extreme attacking case.
830     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiSequence);
831 
832     uint32_t length = 0;
833     napi_get_array_length(env, argv[ARGV_INDEX_0], &length);
834     if (static_cast<int32_t>(length) != arrayLength) {
835         ZLOGE(LOG_LABEL, "Bad length while reading Sequenceable array");
836         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
837     }
838 
839     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
840         int32_t len = napiSequence->nativeParcel_->ReadInt32();
841         if (len > 0) {
842             bool hasElement = false;
843             napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
844             if (!hasElement) {
845                 ZLOGE(LOG_LABEL, "parameter check error");
846                 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
847             }
848             napi_value element = nullptr;
849             napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
850             napi_value callJsFuncResult = JS_readParcelableArrayCallJsFunc(env, element, thisVar);
851             if (callJsFuncResult == nullptr) {
852                 ZLOGE(LOG_LABEL, "call unmarshalling failed, element index:%{public}d", i);
853                 return callJsFuncResult;
854             }
855         }
856     }
857     napi_value result = nullptr;
858     napi_get_undefined(env, &result);
859     return result;
860 }
861 
JS_readRemoteObjectArray(napi_env env,napi_callback_info info)862 napi_value NAPI_MessageSequence::JS_readRemoteObjectArray(napi_env env, napi_callback_info info)
863 {
864     napi_value result = nullptr;
865     napi_get_undefined(env, &result);
866 
867     size_t argc = 0;
868     napi_value argv[ARGV_LENGTH_1] = {0};
869     napi_value thisVar = nullptr;
870     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
871 
872     NAPI_MessageSequence *napiSequence = nullptr;
873     napi_unwrap(env, thisVar, (void **)&napiSequence);
874     if (napiSequence == nullptr) {
875         ZLOGE(LOG_LABEL, "napiSequence is null");
876         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
877     }
878 
879     int32_t arrayLength = napiSequence->nativeParcel_->ReadInt32();
880     if (argc > 0) { // uses passed in array
881         napi_value checkArgsResult = JS_checkReadArrayArgs(env, info, argc, thisVar, argv);
882         if (checkArgsResult == nullptr) {
883             ZLOGE(LOG_LABEL, "checkArgsResult is null");
884             return checkArgsResult;
885         }
886         uint32_t length = 0;
887         napi_get_array_length(env, argv[ARGV_INDEX_0], &length);
888         if (static_cast<int32_t>(length) != arrayLength) {
889             ZLOGE(LOG_LABEL, "Bad length while reading RemoteObject array");
890             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
891         }
892         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
893             sptr<IRemoteObject> value = napiSequence->nativeParcel_->ReadRemoteObject();
894             napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
895             napi_set_element(env, argv[ARGV_INDEX_0], i, napiValue);
896         }
897         return result;
898     }
899 
900     if (arrayLength <= 0) {
901         napi_get_null(env, &result);
902         return result;
903     }
904     napi_create_array(env, &result);
905     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
906         sptr<IRemoteObject> value = napiSequence->nativeParcel_->ReadRemoteObject();
907         napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
908         napi_set_element(env, result, i, napiValue);
909     }
910     return result;
911 }
912 
JS_ReadFileDescriptor(napi_env env,napi_callback_info info)913 napi_value NAPI_MessageSequence::JS_ReadFileDescriptor(napi_env env, napi_callback_info info)
914 {
915     size_t argc = 0;
916     napi_value thisVar = nullptr;
917     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
918     NAPI_MessageSequence *napiSequence = nullptr;
919     napi_unwrap(env, thisVar, (void **)&napiSequence);
920     if (napiSequence == nullptr) {
921         ZLOGE(LOG_LABEL, "napiSequence is null");
922         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
923     }
924     int32_t result = napiSequence->nativeParcel_->ReadFileDescriptor();
925     if (result == -1) {
926         ZLOGE(LOG_LABEL, "read file descriptor failed");
927         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
928     }
929     napi_value napiValue;
930     napi_create_int32(env, result, &napiValue);
931     return napiValue;
932 }
933 
JS_ReadAshmem(napi_env env,napi_callback_info info)934 napi_value NAPI_MessageSequence::JS_ReadAshmem(napi_env env, napi_callback_info info)
935 {
936     size_t argc = 0;
937     napi_value thisVar = nullptr;
938     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
939 
940     NAPI_MessageSequence *napiSequence = nullptr;
941     napi_unwrap(env, thisVar, (void **)&napiSequence);
942     if (napiSequence == nullptr) {
943         ZLOGE(LOG_LABEL, "napiSequence is null");
944         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
945     }
946     sptr<Ashmem> nativeAshmem = napiSequence->nativeParcel_->ReadAshmem();
947     if (nativeAshmem == nullptr) {
948         ZLOGE(LOG_LABEL, "nativeAshmem is null");
949         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
950     }
951     napi_value global = nullptr;
952     napi_value napiValue = nullptr;
953     napi_get_undefined(env, &napiValue);
954     napi_status status = napi_get_global(env, &global);
955     if (status != napi_ok) {
956         ZLOGE(LOG_LABEL, "get napi global failed");
957         return napiValue;
958     }
959     napi_value constructor = nullptr;
960     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
961     if (status != napi_ok) {
962         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
963         return napiValue;
964     }
965     napi_value jsAshmem;
966     status = napi_new_instance(env, constructor, 0, nullptr, &jsAshmem);
967     if (status != napi_ok) {
968         ZLOGE(LOG_LABEL, "failed to  construct js Ashmem");
969         return napiValue;
970     }
971     NAPIAshmem *napiAshmem = nullptr;
972     napi_unwrap(env, jsAshmem, (void **)&napiAshmem);
973     if (napiAshmem == nullptr) {
974         ZLOGE(LOG_LABEL, "napiAshmem is null");
975         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
976     }
977     napiAshmem->SetAshmem(nativeAshmem);
978     return jsAshmem;
979 }
980 
JS_ReadRawData(napi_env env,napi_callback_info info)981 napi_value NAPI_MessageSequence::JS_ReadRawData(napi_env env, napi_callback_info info)
982 {
983     size_t argc = 1;
984     napi_value argv[ARGV_LENGTH_1] = {0};
985     napi_value thisVar = nullptr;
986     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
987     if (argc != 1) {
988         ZLOGE(LOG_LABEL, "requires 1 parameters");
989         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
990     }
991     napi_valuetype valueType = napi_null;
992     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
993     if (valueType != napi_number) {
994         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
995         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
996     }
997     int32_t arraySize = 0;
998     napi_get_value_int32(env, argv[ARGV_INDEX_0], &arraySize);
999     napi_value result = nullptr;
1000     if (arraySize <= 0) {
1001         ZLOGE(LOG_LABEL, "arraySize is %{public}d, error", arraySize);
1002         napi_create_array(env, &result);
1003         return result;
1004     }
1005     NAPI_MessageSequence *napiSequence = nullptr;
1006     napi_unwrap(env, thisVar, (void **)&napiSequence);
1007     if (napiSequence == nullptr) {
1008         ZLOGE(LOG_LABEL, "napiSequence is null");
1009         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1010     }
1011     const void *rawData = napiSequence->nativeParcel_->ReadRawData(arraySize * BYTE_SIZE_32);
1012     if (rawData == nullptr) {
1013         ZLOGE(LOG_LABEL, "rawData is null");
1014         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1015     }
1016     // [c++] rawData -> byteBuffer()[js]
1017     napi_value arrayBuffer = nullptr;
1018     void *arrayBufferPtr = nullptr;
1019     size_t bufferSize = static_cast<size_t>(arraySize) * BYTE_SIZE_32;
1020 
1021     napi_status isCreateBufferOk = napi_create_arraybuffer(env, bufferSize, &arrayBufferPtr, &arrayBuffer);
1022     if (isCreateBufferOk != napi_ok) {
1023         ZLOGE(LOG_LABEL, "JS_ReadRawData create arrayBuffer failed");
1024         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1025     }
1026 
1027     napi_status isCreateArrayOk =
1028         napi_create_typedarray(env, napi_int32_array, arraySize, arrayBuffer, 0, &result);
1029     if (isCreateArrayOk != napi_ok) {
1030         ZLOGE(LOG_LABEL, "JS_ReadRawData create Typedarray failed");
1031         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1032     }
1033 
1034     errno_t status = memcpy_s(arrayBufferPtr, bufferSize, rawData, bufferSize);
1035     NAPI_ASSERT(env, status == EOK, "JS_ReadRawData memcpy_s is failed");
1036     return result;
1037 }
1038 
JS_ReadRawDataBuffer(napi_env env,napi_callback_info info)1039 napi_value NAPI_MessageSequence::JS_ReadRawDataBuffer(napi_env env, napi_callback_info info)
1040 {
1041     size_t argc = ARGV_LENGTH_1;
1042     napi_value argv[ARGV_LENGTH_1] = {0};
1043     napi_value thisVar = nullptr;
1044     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1045     if (argc != ARGV_LENGTH_1) {
1046         ZLOGE(LOG_LABEL, "requires 1 parameters");
1047         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1048     }
1049 
1050     napi_valuetype valueType = napi_null;
1051     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1052     if (valueType != napi_number) {
1053         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1054         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1055     }
1056     int64_t arraySize = 0;
1057     napi_get_value_int64(env, argv[ARGV_INDEX_0], &arraySize);
1058     napi_value result = nullptr;
1059     if (arraySize <= 0) {
1060         ZLOGE(LOG_LABEL, "arraySize is %{public}" PRId64 ", error", arraySize);
1061         napi_create_array(env, &result);
1062         return result;
1063     }
1064     NAPI_MessageSequence *napiSequence = nullptr;
1065     napi_unwrap(env, thisVar, (void **)&napiSequence);
1066     if (napiSequence == nullptr) {
1067         ZLOGE(LOG_LABEL, "napiSequence is null");
1068         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1069     }
1070     const void *rawData = napiSequence->nativeParcel_->ReadRawData(arraySize);
1071     if (rawData == nullptr) {
1072         ZLOGE(LOG_LABEL, "rawData is null");
1073         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1074     }
1075 
1076     napi_value arrayBuffer = nullptr;
1077     void *arrayBufferPtr = nullptr;
1078     size_t bufferSize = static_cast<size_t>(arraySize);
1079     napi_status isCreateBufferOk = napi_create_arraybuffer(env, bufferSize, &arrayBufferPtr, &arrayBuffer);
1080     if (isCreateBufferOk != napi_ok) {
1081         ZLOGE(LOG_LABEL, "JS_ReadRawData create arrayBuffer failed");
1082         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1083     }
1084 
1085     errno_t status = memcpy_s(arrayBufferPtr, bufferSize, rawData, bufferSize);
1086     NAPI_ASSERT(env, status == EOK, "JS_ReadRawDataBuffer memcpy_s fail");
1087     return arrayBuffer;
1088 }
1089 
1090 template<typename T>
JS_CopyVectorToBuffer(napi_env env,std::vector<T> vector,size_t bufferSize)1091 napi_value NAPI_MessageSequence::JS_CopyVectorToBuffer(napi_env env, std::vector<T> vector, size_t bufferSize)
1092 {
1093     napi_value arrayBuffer = nullptr;
1094     void* arrayBufferPtr = nullptr;
1095 
1096     napi_status createStatus = napi_create_arraybuffer(env, bufferSize, &arrayBufferPtr, &arrayBuffer);
1097     if (createStatus != napi_ok) {
1098         ZLOGE(LOG_LABEL, "create arrayBuffer failed. status:%{public}d", createStatus);
1099         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1100     }
1101     errno_t status = memcpy_s(arrayBufferPtr, bufferSize, vector.data(), bufferSize);
1102     NAPI_ASSERT(env, status == EOK, "memcpy_s is failed");
1103 
1104     return arrayBuffer;
1105 }
1106 
JS_readArrayBuffer(napi_env env,napi_callback_info info)1107 napi_value NAPI_MessageSequence::JS_readArrayBuffer(napi_env env, napi_callback_info info)
1108 {
1109     size_t argc = ARGV_LENGTH_1;
1110     napi_value argv[ARGV_LENGTH_1] = {0};
1111     napi_value thisVar = nullptr;
1112     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1113     if (argc != REQUIRED_ARGS_COUNT_1) {
1114         ZLOGE(LOG_LABEL, "requires 1 parameter");
1115         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1116     }
1117 
1118     napi_valuetype valueType = napi_null;
1119     napi_status status = napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1120     if (valueType != napi_number) {
1121         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not number. status:%{public}d", status);
1122         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1123     }
1124 
1125     NAPI_MessageSequence *napiSequence = nullptr;
1126     napi_unwrap(env, thisVar, (void **)&napiSequence);
1127     if (napiSequence == nullptr) {
1128         ZLOGE(LOG_LABEL, "napiSequence is null");
1129         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1130     }
1131 
1132     int32_t typeCode = 0;
1133     napi_get_value_int32(env, argv[ARGV_INDEX_0], &typeCode);
1134     if (typeCode < INT8_ARRAY || typeCode > BIGUINT64_ARRAY) {
1135         ZLOGE(LOG_LABEL, "the value of parameter 1 is out of range. typeCode:%{public}d", typeCode);
1136         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1137     }
1138 
1139     return JS_readVectorByTypeCode(env, typeCode, napiSequence);
1140 }
1141 
JS_readVectorByTypeCode(napi_env env,int32_t typeCode,NAPI_MessageSequence * napiSequence)1142 napi_value NAPI_MessageSequence::JS_readVectorByTypeCode(napi_env env,
1143                                                          int32_t typeCode,
1144                                                          NAPI_MessageSequence *napiSequence)
1145 {
1146     switch (typeCode) {
1147         case INT8_ARRAY: {
1148             return JS_readInt8ArrayBuffer(env, napiSequence);
1149         }
1150         case UINT8_ARRAY: {
1151             return JS_readUInt8ArrayBuffer(env, napiSequence);
1152         }
1153         case INT16_ARRAY: {
1154             return JS_readInt16ArrayBuffer(env, napiSequence);
1155         }
1156         case UINT16_ARRAY: {
1157             return JS_readUInt16ArrayBuffer(env, napiSequence);
1158         }
1159         case INT32_ARRAY: {
1160             return JS_readInt32ArrayBuffer(env, napiSequence);
1161         }
1162         case UINT32_ARRAY: {
1163             return JS_readUInt32ArrayBuffer(env, napiSequence);
1164         }
1165         case FLOAT32_ARRAY: {
1166             return JS_readFloatArrayBuffer(env, napiSequence);
1167         }
1168         case FLOAT64_ARRAY: {
1169             return JS_readDoubleArrayBuffer(env, napiSequence);
1170         }
1171         case BIGINT64_ARRAY: {
1172             return JS_readInt64ArrayBuffer(env, napiSequence);
1173         }
1174         case BIGUINT64_ARRAY: {
1175             return JS_readUInt64ArrayBuffer(env, napiSequence);
1176         }
1177         default:
1178             ZLOGE(LOG_LABEL, "unsupported typeCode:%{public}d", typeCode);
1179             return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1180     }
1181 }
1182 
JS_readInt8ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1183 napi_value NAPI_MessageSequence::JS_readInt8ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1184 {
1185     std::vector<int8_t> int8Vector;
1186     if (!napiSequence->nativeParcel_->ReadInt8Vector(&int8Vector)) {
1187         ZLOGE(LOG_LABEL, "read Int8Vector failed");
1188         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1189     }
1190     size_t bufferSize = int8Vector.size();
1191     return JS_CopyVectorToBuffer(env, int8Vector, bufferSize);
1192 }
1193 
JS_readUInt8ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1194 napi_value NAPI_MessageSequence::JS_readUInt8ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1195 {
1196     std::vector<uint8_t> uint8Vector;
1197     if (!napiSequence->nativeParcel_->ReadUInt8Vector(&uint8Vector)) {
1198         ZLOGE(LOG_LABEL, "read UInt8Vector failed");
1199         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1200     }
1201     size_t bufferSize = uint8Vector.size();
1202     return JS_CopyVectorToBuffer(env, uint8Vector, bufferSize);
1203 }
1204 
JS_readInt16ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1205 napi_value NAPI_MessageSequence::JS_readInt16ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1206 {
1207     std::vector<int16_t> int16Vector;
1208     if (!napiSequence->nativeParcel_->ReadInt16Vector(&int16Vector)) {
1209         ZLOGE(LOG_LABEL, "read Int16Vector failed");
1210         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1211     }
1212     size_t bufferSize = int16Vector.size() * BYTE_SIZE_16;
1213     return JS_CopyVectorToBuffer(env, int16Vector, bufferSize);
1214 }
1215 
JS_readUInt16ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1216 napi_value NAPI_MessageSequence::JS_readUInt16ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1217 {
1218     std::vector<uint16_t> uint16Vector;
1219     if (!napiSequence->nativeParcel_->ReadUInt16Vector(&uint16Vector)) {
1220         ZLOGE(LOG_LABEL, "read UInt16Vector failed");
1221         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1222     }
1223     size_t bufferSize = uint16Vector.size() * BYTE_SIZE_16;
1224     return JS_CopyVectorToBuffer(env, uint16Vector, bufferSize);
1225 }
1226 
JS_readInt32ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1227 napi_value NAPI_MessageSequence::JS_readInt32ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1228 {
1229     std::vector<int32_t> int32Vector;
1230     if (!napiSequence->nativeParcel_->ReadInt32Vector(&int32Vector)) {
1231         ZLOGE(LOG_LABEL, "read Int32Vector failed");
1232         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1233     }
1234     size_t bufferSize = int32Vector.size() * BYTE_SIZE_32;
1235     return JS_CopyVectorToBuffer(env, int32Vector, bufferSize);
1236 }
1237 
JS_readUInt32ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1238 napi_value NAPI_MessageSequence::JS_readUInt32ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1239 {
1240     std::vector<uint32_t> uint32Vector;
1241     if (!napiSequence->nativeParcel_->ReadUInt32Vector(&uint32Vector)) {
1242         ZLOGE(LOG_LABEL, "read UInt32Vector failed");
1243         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1244     }
1245     size_t bufferSize = uint32Vector.size() * BYTE_SIZE_32;
1246     return JS_CopyVectorToBuffer(env, uint32Vector, bufferSize);
1247 }
1248 
JS_readFloatArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1249 napi_value NAPI_MessageSequence::JS_readFloatArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1250 {
1251     std::vector<float> floatVector;
1252     if (!napiSequence->nativeParcel_->ReadFloatVector(&floatVector)) {
1253         ZLOGE(LOG_LABEL, "read FloatVector failed");
1254         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1255     }
1256     size_t bufferSize = floatVector.size() * BYTE_SIZE_32;
1257     return JS_CopyVectorToBuffer(env, floatVector, bufferSize);
1258 }
1259 
JS_readDoubleArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1260 napi_value NAPI_MessageSequence::JS_readDoubleArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1261 {
1262     std::vector<double> doubleVector;
1263     if (!napiSequence->nativeParcel_->ReadDoubleVector(&doubleVector)) {
1264         ZLOGE(LOG_LABEL, "read DoubleVector failed");
1265         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1266     }
1267     size_t bufferSize = doubleVector.size() * BYTE_SIZE_64;
1268     return JS_CopyVectorToBuffer(env, doubleVector, bufferSize);
1269 }
1270 
JS_readInt64ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1271 napi_value NAPI_MessageSequence::JS_readInt64ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1272 {
1273     std::vector<int64_t> int64Vector;
1274     if (!napiSequence->nativeParcel_->ReadInt64Vector(&int64Vector)) {
1275         ZLOGE(LOG_LABEL, "read Int64Vector failed");
1276         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1277     }
1278     size_t bufferSize = int64Vector.size() * BYTE_SIZE_64;
1279     return JS_CopyVectorToBuffer(env, int64Vector, bufferSize);
1280 }
1281 
JS_readUInt64ArrayBuffer(napi_env env,NAPI_MessageSequence * napiSequence)1282 napi_value NAPI_MessageSequence::JS_readUInt64ArrayBuffer(napi_env env, NAPI_MessageSequence *napiSequence)
1283 {
1284     std::vector<uint64_t> uint64vector;
1285     if (!napiSequence->nativeParcel_->ReadUInt64Vector(&uint64vector)) {
1286         ZLOGE(LOG_LABEL, "read UInt64Vector failed");
1287         return napiErr.ThrowError(env, errorDesc::READ_DATA_FROM_MESSAGE_SEQUENCE_ERROR);
1288     }
1289     size_t bufferSize = uint64vector.size() * BYTE_SIZE_64;
1290     return JS_CopyVectorToBuffer(env, uint64vector, bufferSize);
1291 }
1292 } // namespace OHOS