1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "js_util.h"
16
17 #include <endian.h>
18 #include <securec.h>
19
20 #include "logger.h"
21
22 namespace OHOS::ObjectStore {
23 constexpr int32_t STR_MAX_LENGTH = 4096;
24 constexpr size_t STR_TAIL_LENGTH = 1;
25
26 /* napi_value <-> bool */
GetValue(napi_env env,napi_value in,bool & out)27 napi_status JSUtil::GetValue(napi_env env, napi_value in, bool &out)
28 {
29 LOG_DEBUG("napi_value <- bool");
30 return napi_get_value_bool(env, in, &out);
31 }
32
SetValue(napi_env env,const bool & in,napi_value & out)33 napi_status JSUtil::SetValue(napi_env env, const bool &in, napi_value &out)
34 {
35 LOG_DEBUG("napi_value -> bool");
36 return napi_get_boolean(env, in, &out);
37 }
38
39 /* napi_value <-> double */
GetValue(napi_env env,napi_value in,double & out)40 napi_status JSUtil::GetValue(napi_env env, napi_value in, double &out)
41 {
42 LOG_DEBUG("napi_value -> double");
43 return napi_get_value_double(env, in, &out);
44 }
45
SetValue(napi_env env,const double & in,napi_value & out)46 napi_status JSUtil::SetValue(napi_env env, const double &in, napi_value &out)
47 {
48 LOG_DEBUG("napi_value <- double");
49 return napi_create_double(env, in, &out);
50 }
51
52 /* napi_value <-> std::string */
GetValue(napi_env env,napi_value in,std::string & out)53 napi_status JSUtil::GetValue(napi_env env, napi_value in, std::string &out)
54 {
55 size_t maxLen = STR_MAX_LENGTH;
56 napi_status status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
57 if (maxLen <= 0) {
58 GET_AND_THROW_LAST_ERROR(env);
59 return status;
60 }
61 char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH];
62 if (buf != nullptr) {
63 size_t len = 0;
64 status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
65 if (status != napi_ok) {
66 GET_AND_THROW_LAST_ERROR(env);
67 }
68 buf[len] = 0;
69 out = std::string(buf);
70 delete[] buf;
71 } else {
72 status = napi_generic_failure;
73 }
74 return status;
75 }
76
SetValue(napi_env env,const std::string & in,napi_value & out)77 napi_status JSUtil::SetValue(napi_env env, const std::string &in, napi_value &out)
78 {
79 LOG_DEBUG("napi_value <- std::string %{public}d", (int)in.length());
80 return napi_create_string_utf8(env, in.c_str(), in.size(), &out);
81 }
82
83 /* napi_value <-> std::vector<std::string> */
GetValue(napi_env env,napi_value in,std::vector<std::string> & out)84 napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector<std::string> &out)
85 {
86 LOG_DEBUG("napi_value -> std::vector<std::string>");
87 bool isArray = false;
88 napi_is_array(env, in, &isArray);
89 LOG_ERROR_RETURN(isArray, "not an array", napi_invalid_arg);
90
91 uint32_t length = 0;
92 napi_status status = napi_get_array_length(env, in, &length);
93 LOG_ERROR_RETURN((status == napi_ok) && (length > 0), "get_array failed!", napi_invalid_arg);
94 for (uint32_t i = 0; i < length; ++i) {
95 napi_value item = nullptr;
96 status = napi_get_element(env, in, i, &item);
97 LOG_ERROR_RETURN((item != nullptr) && (status == napi_ok), "no element", napi_invalid_arg);
98 std::string value;
99 status = GetValue(env, item, value);
100 LOG_ERROR_RETURN(status == napi_ok, "not a string", napi_invalid_arg);
101 out.push_back(value);
102 }
103 return status;
104 }
105
SetValue(napi_env env,const std::vector<std::string> & in,napi_value & out)106 napi_status JSUtil::SetValue(napi_env env, const std::vector<std::string> &in, napi_value &out)
107 {
108 LOG_DEBUG("napi_value <- std::vector<std::string>");
109 napi_status status = napi_create_array_with_length(env, in.size(), &out);
110 LOG_ERROR_RETURN(status == napi_ok, "create array failed!", status);
111 int index = 0;
112 for (auto &item : in) {
113 napi_value element = nullptr;
114 SetValue(env, item, element);
115 status = napi_set_element(env, out, index++, element);
116 LOG_ERROR_RETURN((status == napi_ok), "napi_set_element failed!", status);
117 }
118 return status;
119 }
120
121 /* napi_value <-> std::vector<uint8_t> */
GetValue(napi_env env,napi_value in,std::vector<uint8_t> & out)122 napi_status JSUtil::GetValue(napi_env env, napi_value in, std::vector<uint8_t> &out)
123 {
124 out.clear();
125 LOG_DEBUG("napi_value -> std::vector<uint8_t> ");
126 napi_typedarray_type type = napi_biguint64_array;
127 size_t length = 0;
128 napi_value buffer = nullptr;
129 size_t offset = 0;
130 void *data = nullptr;
131 napi_status status = napi_get_typedarray_info(env, in, &type, &length, &data, &buffer, &offset);
132 LOG_DEBUG("array type=%{public}d length=%{public}d offset=%{public}d status=%{public}d", (int)type, (int)length,
133 (int)offset, status);
134 LOG_ERROR_RETURN(status == napi_ok, "napi_get_typedarray_info failed!", napi_invalid_arg);
135 LOG_ERROR_RETURN(type == napi_uint8_array, "is not Uint8Array!", napi_invalid_arg);
136 LOG_ERROR_RETURN((length > 0) && (data != nullptr), "invalid data!", napi_invalid_arg);
137 out.assign((uint8_t *)data, ((uint8_t *)data) + length);
138 return status;
139 }
140
SetValue(napi_env env,const std::vector<uint8_t> & in,napi_value & out)141 napi_status JSUtil::SetValue(napi_env env, const std::vector<uint8_t> &in, napi_value &out)
142 {
143 LOG_DEBUG("napi_value <- std::vector<uint8_t> ");
144 LOG_ERROR_RETURN(in.size() > 0, "invalid std::vector<uint8_t>", napi_invalid_arg);
145 void *data = nullptr;
146 napi_value buffer = nullptr;
147 napi_status status = napi_create_arraybuffer(env, in.size(), &data, &buffer);
148 LOG_ERROR_RETURN((status == napi_ok), "create array buffer failed!", status);
149
150 if (memcpy_s(data, in.size(), in.data(), in.size()) != EOK) {
151 LOG_ERROR("memcpy_s not EOK");
152 return napi_invalid_arg;
153 }
154 status = napi_create_typedarray(env, napi_uint8_array, in.size(), buffer, 0, &out);
155 LOG_ERROR_RETURN((status == napi_ok), "napi_value <- std::vector<uint8_t> invalid value", status);
156 return status;
157 }
158 } // namespace OHOS::ObjectStore
159