1 /*
2  * Copyright (c) 2023 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 "js_utils.h"
19 #include "variable_convertor.h"
20 
21 namespace OHOS {
22 namespace Global {
23 namespace I18n {
CheckNapiValueType(napi_env env,napi_value value)24 bool VariableConvertor::CheckNapiValueType(napi_env env, napi_value value)
25 {
26     if (value != nullptr) {
27         napi_valuetype valueType = napi_valuetype::napi_undefined;
28         napi_typeof(env, value, &valueType);
29         if (valueType != napi_valuetype::napi_undefined && valueType != napi_valuetype::napi_null) {
30             return true;
31         }
32     }
33     return false;
34 }
35 
GetOptionValue(napi_env env,napi_value options,const std::string & optionName,std::string & value)36 void VariableConvertor::GetOptionValue(napi_env env, napi_value options, const std::string &optionName,
37     std::string &value)
38 {
39     napi_value optionValue = nullptr;
40     napi_valuetype type = napi_undefined;
41     napi_status status = napi_typeof(env, options, &type);
42     if (status != napi_ok && type != napi_object) {
43         HILOG_ERROR_I18N("GetOptionValue: Get option failed, option is not an object");
44         return;
45     }
46     bool hasProperty = false;
47     napi_status propStatus = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
48     if (propStatus == napi_ok && hasProperty) {
49         status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
50         if (status == napi_ok) {
51             size_t len;
52             napi_get_value_string_utf8(env, optionValue, nullptr, 0, &len);
53             std::vector<char> optionBuf(len + 1);
54             status = napi_get_value_string_utf8(env, optionValue, optionBuf.data(), len + 1, &len);
55             if (status != napi_ok) {
56                 HILOG_ERROR_I18N("GetOptionValue: Failed to get string item");
57                 return;
58             }
59             value = optionBuf.data();
60         }
61     }
62 }
63 
GetBoolOptionValue(napi_env env,napi_value & options,const std::string & optionName,bool & boolVal)64 bool VariableConvertor::GetBoolOptionValue(napi_env env, napi_value &options, const std::string &optionName,
65     bool &boolVal)
66 {
67     napi_valuetype type = napi_undefined;
68     napi_status status = napi_typeof(env, options, &type);
69     if (status != napi_ok && type != napi_object) {
70         HILOG_ERROR_I18N("option is not an object");
71         ErrorUtil::NapiThrow(env, I18N_NOT_VALID, optionName, "a valid object", true);
72         return false;
73     }
74     bool hasProperty = false;
75     status = napi_has_named_property(env, options, optionName.c_str(), &hasProperty);
76     if (status != napi_ok || !hasProperty) {
77         HILOG_INFO_I18N("option don't have property %{public}s", optionName.c_str());
78         return false;
79     }
80     napi_value optionValue = nullptr;
81     status = napi_get_named_property(env, options, optionName.c_str(), &optionValue);
82     if (status != napi_ok) {
83         HILOG_INFO_I18N("get option %{public}s failed", optionName.c_str());
84         return false;
85     }
86     napi_get_value_bool(env, optionValue, &boolVal);
87     return true;
88 }
89 
GetString(napi_env & env,napi_value & value,int32_t & code)90 std::string VariableConvertor::GetString(napi_env &env, napi_value &value, int32_t &code)
91 {
92     size_t len = 0;
93     napi_status status = napi_get_value_string_utf8(env, value, nullptr, 0, &len);
94     if (status != napi_ok) {
95         HILOG_ERROR_I18N("Get string failed");
96         code = 1;
97         return "";
98     }
99     std::vector<char> buf(len + 1);
100     status = napi_get_value_string_utf8(env, value, buf.data(), len + 1, &len);
101     if (status != napi_ok) {
102         HILOG_ERROR_I18N("Create string failed");
103         code = 1;
104         return "";
105     }
106     std::string result(buf.data());
107     return result;
108 }
109 
GetStringArrayFromJsParam(napi_env env,napi_value & jsArray,const std::string & valueName,std::vector<std::string> & strArray)110 bool VariableConvertor::GetStringArrayFromJsParam(napi_env env, napi_value &jsArray, const std::string& valueName,
111     std::vector<std::string> &strArray)
112 {
113     if (jsArray == nullptr) {
114         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, valueName, "", true);
115         return false;
116     }
117     bool isArray = false;
118     napi_status status = napi_is_array(env, jsArray, &isArray);
119     if (status != napi_ok) {
120         return false;
121     } else if (!isArray) {
122         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, valueName, "an Array", true);
123         return false;
124     }
125     uint32_t arrayLength = 0;
126     napi_get_array_length(env, jsArray, &arrayLength);
127     napi_value element = nullptr;
128     int32_t code = 0;
129     for (uint32_t i = 0; i < arrayLength; ++i) {
130         napi_get_element(env, jsArray, i, &element);
131         std::string str = GetString(env, element, code);
132         if (code != 0) {
133             HILOG_ERROR_I18N("GetStringArrayFromJsParam: Failed to obtain the parameter.");
134             return false;
135         }
136         strArray.push_back(str);
137     }
138     return true;
139 }
140 
CreateString(napi_env env,const std::string & str)141 napi_value VariableConvertor::CreateString(napi_env env, const std::string &str)
142 {
143     napi_value result;
144     napi_status status = napi_create_string_utf8(env, str.c_str(), NAPI_AUTO_LENGTH, &result);
145     if (status != napi_ok) {
146         HILOG_ERROR_I18N("create string js variable failed.");
147         return nullptr;
148     }
149     return result;
150 }
151 
CreateNumber(napi_env env,const int32_t & num)152 napi_value VariableConvertor::CreateNumber(napi_env env, const int32_t &num)
153 {
154     napi_value result;
155     napi_status status = napi_create_int32(env, num, &result);
156     if (status != napi_ok) {
157         HILOG_ERROR_I18N("create number js variable failed.");
158         return nullptr;
159     }
160     return result;
161 }
162 
VerifyType(napi_env env,const std::string & valueName,const std::string & type,napi_value argv)163 void VariableConvertor::VerifyType(napi_env env, const std::string& valueName, const std::string& type,
164     napi_value argv)
165 {
166     napi_valuetype valueType = napi_valuetype::napi_undefined;
167     napi_typeof(env, argv, &valueType);
168     if (type == "string" && valueType != napi_valuetype::napi_string) {
169         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, valueName, type, true);
170     } else if (type == "number" && valueType != napi_valuetype::napi_number) {
171         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, valueName, type, true);
172     }
173 }
174 } // namespace I18n
175 } // namespace Global
176 } // namespace OHOS