• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "error_util.h"
17 #include "i18n_hilog.h"
18 #include "locale_info_addon.h"
19 #include "variable_convertor.h"
20 
21 namespace OHOS {
22 namespace Global {
23 namespace I18n {
24 const std::map<napi_valuetype, std::string> VariableConvertor::NAPI_TYPE_MAP {
25     {napi_valuetype::napi_boolean, "boolean"},
26     {napi_valuetype::napi_number, "number"},
27     {napi_valuetype::napi_string, "string"},
28     {napi_valuetype::napi_bigint, "bigint"},
29     {napi_valuetype::napi_symbol, "symbol"},
30     {napi_valuetype::napi_object, "object"},
31     {napi_valuetype::napi_null, "null"},
32     {napi_valuetype::napi_undefined, "undefined"},
33 };
CheckNapiIsNull(napi_env env,napi_value value)34 bool VariableConvertor::CheckNapiIsNull(napi_env env, napi_value value)
35 {
36     if (value != nullptr) {
37         napi_valuetype valueType = napi_valuetype::napi_undefined;
38         napi_typeof(env, value, &valueType);
39         if (valueType != napi_valuetype::napi_undefined && valueType != napi_valuetype::napi_null) {
40             return true;
41         }
42     }
43     return false;
44 }
45 
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::string & value)46 void VariableConvertor::GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
47     std::string &value)
48 {
49     napi_value optionValue = nullptr;
50     napi_valuetype type = napi_undefined;
51     napi_status status = napi_typeof(env, options, &type);
52     if (status != napi_ok && type != napi_object) {
53         HILOG_ERROR_I18N("GetOptionValue: Get option failed, option is not an object");
54         return;
55     }
56     bool hasProperty = false;
57     napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
58     if (propStatus == napi_ok && hasProperty) {
59         status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
60         if (status == napi_ok) {
61             size_t len;
62             napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
63             std::vector<char> optionBuf(len + 1);
64             status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
65             if (status != napi_ok) {
66                 HILOG_ERROR_I18N("GetOptionValue: Failed to get string item");
67                 return;
68             }
69             value = optionBuf.data();
70         }
71     }
72 }
73 
GetBoolOptionValue(napi_env env,napi_value & options,const std::string & optionName,bool & boolVal)74 bool VariableConvertor::GetBoolOptionValue(napi_env env, napi_value &options, const std::string &optionName,
75     bool &boolVal)
76 {
77     napi_valuetype type = napi_undefined;
78     napi_status status = napi_typeof(env, options, &type);
79     if (status != napi_ok && type != napi_object) {
80         HILOG_ERROR_I18N("option is not an object");
81         ErrorUtil::NapiThrow(env, I18N_NOT_VALID, optionName, "a valid object", true);
82         return false;
83     }
84     bool hasProperty = false;
85     status = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
86     if (status != napi_ok || !hasProperty) {
87         HILOG_INFO_I18N("option don't have property %{public}s", optionName.c_str());
88         return false;
89     }
90     napi_value optionValue = nullptr;
91     status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
92     if (status != napi_ok) {
93         HILOG_INFO_I18N("get option %{public}s failed", optionName.c_str());
94         return false;
95     }
96     napi_get_value_bool(env, optionValue, &boolVal);
97     return true;
98 }
99 
GetString(napi_env & env,napi_value & value,int32_t & code)100 std::string VariableConvertor::GetString(napi_env &env, napi_value &value, int32_t &code)
101 {
102     size_t len = 0;
103     napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
104     if (status != napi_ok) {
105         HILOG_ERROR_I18N("Get string failed");
106         code = 1;
107         return "";
108     }
109     std::vector<char> buf(len + 1);
110     status = napi_get_value_string_utf8(env, value, buf.data(), len + 1, &len);
111     if (status != napi_ok) {
112         HILOG_ERROR_I18N("Create string failed");
113         code = 1;
114         return "";
115     }
116     std::string result(buf.data());
117     return result;
118 }
119 
GetStringArrayFromJsParam(napi_env env,napi_value & jsArray,const std::string & valueName,std::vector<std::string> & strArray)120 bool VariableConvertor::GetStringArrayFromJsParam(napi_env env, napi_value &jsArray, const std::string& valueName,
121     std::vector<std::string> &strArray)
122 {
123     if (jsArray == nullptr) {
124         ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, valueName, true);
125         return false;
126     }
127     bool isArray = false;
128     napi_status status = napi_is_array(env, jsArray, &isArray);
129     if (status != napi_ok) {
130         return false;
131     } else if (!isArray) {
132         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, valueName, "an Array", true);
133         return false;
134     }
135     uint32_t arrayLength = 0;
136     napi_get_array_length(env, jsArray, &arrayLength);
137     napi_value element = nullptr;
138     int32_t code = 0;
139     for (uint32_t i = 0; i < arrayLength; ++i) {
140         napi_get_element(env, jsArray, i, &element);
141         std::string str = GetString(env, element, code);
142         if (code != 0) {
143             HILOG_ERROR_I18N("GetStringArrayFromJsParam: Failed to obtain the parameter.");
144             return false;
145         }
146         strArray.push_back(str);
147     }
148     return true;
149 }
150 
CreateString(napi_env env,const std::string & str)151 napi_value VariableConvertor::CreateString(napi_env env, const std::string &str)
152 {
153     napi_value result;
154     napi_status status = napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &result);
155     if (status != napi_ok) {
156         HILOG_ERROR_I18N("create string js variable failed.");
157         return nullptr;
158     }
159     return result;
160 }
161 
CreateNumber(napi_env env,const int32_t & num)162 napi_value VariableConvertor::CreateNumber(napi_env env, const int32_t &num)
163 {
164     napi_value result;
165     napi_status status = napi_create_int32(env, num, &result);
166     if (status != napi_ok) {
167         HILOG_ERROR_I18N("create number js variable failed.");
168         return nullptr;
169     }
170     return result;
171 }
172 
VerifyType(napi_env env,const std::string & valueName,napi_valuetype napiType,napi_value argv)173 void VariableConvertor::VerifyType(napi_env env, const std::string& valueName, napi_valuetype napiType,
174     napi_value argv)
175 {
176     napi_valuetype valueType = napi_valuetype::napi_undefined;
177     napi_status status = napi_typeof(env, argv, &valueType);
178     if (status != napi_ok || valueType != napiType) {
179         auto iter = NAPI_TYPE_MAP.find(napiType);
180         std::string type = iter != NAPI_TYPE_MAP.end() ? iter->second : "";
181         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, valueName, type, true);
182     }
183 }
184 
SetEnumValue(napi_env env,napi_value enumObj,const std::string & enumName,int32_t enumVal)185 napi_status VariableConvertor::SetEnumValue(napi_env env, napi_value enumObj, const std::string& enumName,
186     int32_t enumVal)
187 {
188     napi_value name = nullptr;
189     napi_status status = napi_create_string_utf8(env, enumName.c_str(), NAPI_AUTO_LENGTH, &name);
190     if (status != napi_ok) {
191         HILOG_ERROR_I18N("VariableConvertor::SetEnumValue: create string %{public}s failed.", enumName.c_str());
192         return status;
193     }
194     napi_value value = nullptr;
195     status = napi_create_int32(env, enumVal, &value);
196     if (status != napi_ok) {
197         HILOG_ERROR_I18N("VariableConvertor::SetEnumValue: create int32 %{public}d failed.", enumVal);
198         return status;
199     }
200     status = napi_set_property(env, enumObj, name, value);
201     if (status != napi_ok) {
202         HILOG_ERROR_I18N("VariableConvertor::SetEnumValue: set property %{public}s failed.", enumName.c_str());
203         return status;
204     }
205     status = napi_set_property(env, enumObj, value, name);
206     if (status != napi_ok) {
207         HILOG_ERROR_I18N("VariableConvertor::SetEnumValue: set property %{public}d failed.", enumVal);
208         return status;
209     }
210     return napi_ok;
211 }
212 
ParseIntlLocale(napi_env env,napi_value intlLocale)213 std::shared_ptr<LocaleInfo> VariableConvertor::ParseIntlLocale(napi_env env, napi_value intlLocale)
214 {
215     napi_valuetype valueType = napi_valuetype::napi_undefined;
216     napi_status status = napi_typeof(env, intlLocale, &valueType);
217     if (status != napi_ok) {
218         HILOG_ERROR_I18N("ParseIntlLocale: Failed to get type of intlLocale.");
219         return nullptr;
220     } else if (valueType != napi_valuetype::napi_object) {
221         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "intl.Locale", true);
222         return nullptr;
223     }
224 
225     LocaleInfoAddon *localeInfoAddon = nullptr;
226     status = napi_unwrap(env, intlLocale, reinterpret_cast<void **>(&localeInfoAddon));
227     if (status != napi_ok) {
228         HILOG_ERROR_I18N("ParseIntlLocale: Failed to unwrap intlLocale.");
229         return nullptr;
230     } else if (!localeInfoAddon) {
231         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "locale", "intl.Locale", true);
232         return nullptr;
233     } else if (!localeInfoAddon->GetLocaleInfo()) {
234         ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "locale", "a valid intl.Locale", true);
235         return nullptr;
236     }
237     return localeInfoAddon->GetLocaleInfo();
238 }
239 } // namespace I18n
240 } // namespace Global
241 } // namespace OHOS