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 #include "js_utils.h"
16 #include "i18n_hilog.h"
17 #include "utils.h"
18
19 namespace OHOS {
20 namespace Global {
21 namespace I18n {
DefaultConstructor(napi_env env,napi_callback_info info)22 napi_value JSUtils::DefaultConstructor(napi_env env, napi_callback_info info)
23 {
24 return nullptr;
25 }
26
CreateEmptyString(napi_env env)27 napi_value JSUtils::CreateEmptyString(napi_env env)
28 {
29 napi_value result;
30 std::string emptyStr = "";
31 napi_status status = napi_create_string_utf8(env, emptyStr.c_str(), NAPI_AUTO_LENGTH, &result);
32 if (status != napi_ok) {
33 HILOG_ERROR_I18N("JSUtils: create string js variable failed.");
34 }
35 return result;
36 }
37
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::map<std::string,std::string> & map)38 void JSUtils::GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
39 std::map<std::string, std::string> &map)
40 {
41 napi_value optionValue = nullptr;
42 napi_valuetype type = napi_undefined;
43 napi_status status = napi_typeof(env, options, &type);
44 if (status != napi_ok && type != napi_object) {
45 HILOG_ERROR_I18N("Get option failed, option is not an object");
46 return;
47 }
48 bool hasProperty = false;
49 status = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
50 if (status != napi_ok) {
51 HILOG_ERROR_I18N("GetOptionValue: Has not named property:%{public}s", optionName.c_str());
52 return;
53 }
54 if (!hasProperty) {
55 return;
56 }
57 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
58 if (status != napi_ok) {
59 HILOG_ERROR_I18N("GetOptionValue: Get named property for %{public}s failed.", optionName.c_str());
60 return;
61 }
62 size_t len = 0;
63 status = napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
64 if (status != napi_ok) {
65 HILOG_ERROR_I18N("GetOptionValue: get string length failed");
66 return;
67 }
68
69 std::vector<char> optionBuf(len + 1);
70 status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
71 if (status != napi_ok) {
72 HILOG_ERROR_I18N("GetOptionValue: get string value failed");
73 return;
74 }
75 auto ret = map.insert(make_pair(optionName, optionBuf.data()));
76 if (!ret.second) {
77 HILOG_ERROR_I18N("GetOptionValue: map insert failed");
78 }
79 }
80
GetBoolOptionValue(napi_env env,napi_value options,const std::string & optionName,std::map<std::string,std::string> & map)81 void JSUtils::GetBoolOptionValue(napi_env env, napi_value options, const std::string &optionName,
82 std::map<std::string, std::string> &map)
83 {
84 napi_value optionValue = nullptr;
85 napi_valuetype type = napi_undefined;
86 napi_status status = napi_typeof(env, options, &type);
87 if (status != napi_ok && type != napi_object) {
88 HILOG_ERROR_I18N("GetBoolOptionValue: Set option failed, option is not an object");
89 return;
90 }
91 bool hasProperty = false;
92 status = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
93 if (status != napi_ok) {
94 HILOG_ERROR_I18N("GetBoolOptionValue: Has not named property.");
95 return;
96 }
97 if (!hasProperty) {
98 return;
99 }
100 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
101 if (status != napi_ok) {
102 HILOG_ERROR_I18N("GetBoolOptionValue: Get named property for %{public}s failed.", optionName.c_str());
103 return;
104 }
105 bool boolValue = false;
106 status = napi_get_value_bool(env, optionValue, &boolValue);
107 if (status != napi_ok) {
108 HILOG_ERROR_I18N("GetBoolOptionValue: Get bool value failed.");
109 return;
110 }
111 std::string value = boolValue ? "true" : "false";
112 auto ret = map.insert(make_pair(optionName, value));
113 if (!ret.second) {
114 HILOG_ERROR_I18N("GetBoolOptionValue: map insert failed");
115 }
116 }
117
GetLocaleTag(napi_env env,napi_value argv)118 std::string JSUtils::GetLocaleTag(napi_env env, napi_value argv)
119 {
120 if (argv == nullptr) {
121 return "";
122 }
123 napi_valuetype valueType = napi_valuetype::napi_undefined;
124 napi_typeof(env, argv, &valueType);
125 if (valueType != napi_valuetype::napi_string) {
126 HILOG_ERROR_I18N("GetLocaleTag: Parameter type does not match");
127 return "";
128 }
129 size_t len = 0;
130 napi_status status = napi_get_value_string_utf8(env, argv, nullptr, 0, &len);
131 if (status != napi_ok) {
132 HILOG_ERROR_I18N("GetLocaleTag -> string: Get locale tag length failed");
133 return "";
134 }
135 std::vector<char> buf;
136 buf.resize(len + 1);
137 status = napi_get_value_string_utf8(env, argv, buf.data(), len + 1, &len);
138 if (status != napi_ok) {
139 HILOG_ERROR_I18N("GetLocaleTag: Get locale tag failed");
140 return "";
141 }
142 std::string result(buf.data());
143 return result;
144 }
145
GetLocaleTags(napi_env env,napi_value rawLocaleTag,std::vector<std::string> & localeTags)146 void JSUtils::GetLocaleTags(napi_env env, napi_value rawLocaleTag, std::vector<std::string> &localeTags)
147 {
148 size_t len = 0;
149 napi_status status = napi_get_value_string_utf8(env, rawLocaleTag, nullptr, 0, &len);
150 if (status != napi_ok) {
151 HILOG_ERROR_I18N("GetLocaleTag -> void: Get locale tag length failed");
152 return;
153 }
154 std::vector<char> buf(len + 1);
155 status = napi_get_value_string_utf8(env, rawLocaleTag, buf.data(), len + 1, &len);
156 if (status != napi_ok) {
157 HILOG_ERROR_I18N("GetLocaleTags: Get locale tag failed");
158 return;
159 }
160 localeTags.push_back(buf.data());
161 }
162
GetNumberOptionValues(napi_env env,napi_value options,std::map<std::string,std::string> & map)163 void JSUtils::GetNumberOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map)
164 {
165 JSUtils::GetOptionValue(env, options, "currency", map);
166 JSUtils::GetOptionValue(env, options, "currencySign", map);
167 JSUtils::GetOptionValue(env, options, "currencyDisplay", map);
168 JSUtils::GetOptionValue(env, options, "unit", map);
169 JSUtils::GetOptionValue(env, options, "unitDisplay", map);
170 JSUtils::GetOptionValue(env, options, "compactDisplay", map);
171 JSUtils::GetOptionValue(env, options, "signDisplay", map);
172 JSUtils::GetOptionValue(env, options, "localeMatcher", map);
173 JSUtils::GetOptionValue(env, options, "style", map);
174 JSUtils::GetOptionValue(env, options, "numberingSystem", map);
175 JSUtils::GetOptionValue(env, options, "notation", map);
176 JSUtils::GetOptionValue(env, options, "unitUsage", map);
177 JSUtils::GetOptionValue(env, options, "roundingPriority", map);
178 JSUtils::GetOptionValue(env, options, "roundingMode", map);
179 JSUtils::GetBoolOptionValue(env, options, "useGrouping", map);
180 GetIntegerOptionValue(env, options, "minimumIntegerDigits", map);
181 int64_t minFd = GetIntegerOptionValue(env, options, "minimumFractionDigits", map);
182 int64_t maxFd = GetIntegerOptionValue(env, options, "maximumFractionDigits", map);
183 if (minFd != -1 && maxFd != -1 && minFd > maxFd) {
184 HILOG_ERROR_I18N(
185 "GetNumberOptionValues: Invalid parameter value: minimumFractionDigits > maximumFractionDigits");
186 }
187 GetIntegerOptionValue(env, options, "minimumSignificantDigits", map);
188 GetIntegerOptionValue(env, options, "maximumSignificantDigits", map);
189 GetIntegerOptionValue(env, options, "roundingIncrement", map);
190 }
191
GetIntegerOptionValue(napi_env env,napi_value options,const std::string & optionName,std::map<std::string,std::string> & map)192 int64_t JSUtils::GetIntegerOptionValue(napi_env env, napi_value options, const std::string &optionName,
193 std::map<std::string, std::string> &map)
194 {
195 napi_value optionValue = nullptr;
196 int64_t integerValue = -1;
197 napi_valuetype type = napi_undefined;
198 napi_status status = napi_typeof(env, options, &type);
199 if (status != napi_ok && type != napi_object) {
200 HILOG_ERROR_I18N("GetIntegerOptionValue: Set option failed, option is not an object");
201 return integerValue;
202 }
203 bool hasProperty = false;
204 napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
205 if (propStatus == napi_ok && hasProperty) {
206 status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
207 if (status == napi_ok) {
208 status = napi_get_value_int64(env, optionValue, &integerValue);
209 if (status == napi_ok) {
210 map.insert(make_pair(optionName, std::to_string(integerValue)));
211 }
212 }
213 }
214 return integerValue;
215 }
216
SetOptionProperties(napi_env env,napi_value & result,std::map<std::string,std::string> & options,const std::string & option)217 void JSUtils::SetOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
218 const std::string &option)
219 {
220 if (options.count(option) > 0) {
221 std::string optionValue = options[option];
222 napi_value optionJsValue = nullptr;
223 napi_create_string_utf8(env, optionValue.c_str(), NAPI_AUTO_LENGTH, &optionJsValue);
224 napi_set_named_property(env, result, option.c_str(), optionJsValue);
225 } else {
226 napi_value undefined = nullptr;
227 napi_get_undefined(env, &undefined);
228 napi_set_named_property(env, result, option.c_str(), undefined);
229 }
230 }
231
SetBooleanOptionProperties(napi_env env,napi_value & result,std::map<std::string,std::string> & options,const std::string & option)232 void JSUtils::SetBooleanOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
233 const std::string &option)
234 {
235 if (options.count(option) > 0) {
236 std::string optionValue = options[option];
237 bool optionBoolValue = (optionValue == "true");
238 napi_value optionJsValue = nullptr;
239 napi_get_boolean(env, optionBoolValue, &optionJsValue);
240 napi_set_named_property(env, result, option.c_str(), optionJsValue);
241 } else {
242 napi_value undefined = nullptr;
243 napi_get_undefined(env, &undefined);
244 napi_set_named_property(env, result, option.c_str(), undefined);
245 }
246 }
247
SetIntegerOptionProperties(napi_env env,napi_value & result,std::map<std::string,std::string> & options,const std::string & option)248 void JSUtils::SetIntegerOptionProperties(napi_env env, napi_value &result, std::map<std::string, std::string> &options,
249 const std::string &option)
250 {
251 if (options.count(option) > 0) {
252 std::string optionValue = options[option];
253 napi_value optionJsValue = nullptr;
254 int32_t status = 0;
255 int64_t integerValue = ConvertString2Int(optionValue, status);
256 if (status != -1) {
257 napi_create_int64(env, integerValue, &optionJsValue);
258 napi_set_named_property(env, result, option.c_str(), optionJsValue);
259 return;
260 }
261 }
262 napi_value undefined = nullptr;
263 napi_get_undefined(env, &undefined);
264 napi_set_named_property(env, result, option.c_str(), undefined);
265 }
266 } // namespace I18n
267 } // namespace Global
268 } // namespace OHOS