• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include "napi_utils.h"
17 
18 #include "time_common.h"
19 
20 namespace OHOS {
21 namespace MiscServices {
22 namespace Time {
23 static constexpr int32_t STR_MAX_LENGTH = 4096;
24 static constexpr size_t STR_TAIL_LENGTH = 1;
25 static constexpr const char *SYSTEM_ERROR = "system error";
ConvertErrorCode(int32_t timeErrorCode)26 int32_t NapiUtils::ConvertErrorCode(int32_t timeErrorCode)
27 {
28     switch (timeErrorCode) {
29         case MiscServices::E_TIME_NOT_SYSTEM_APP:
30             return JsErrorCode::SYSTEM_APP_ERROR;
31         case MiscServices::E_TIME_NO_PERMISSION:
32             return JsErrorCode::PERMISSION_ERROR;
33         case MiscServices::E_TIME_PARAMETERS_INVALID:
34             return JsErrorCode::PARAMETER_ERROR;
35         case MiscServices::E_TIME_NTP_UPDATE_FAILED:
36             return JsErrorCode::NTP_UPDATE_ERROR;
37         case MiscServices::E_TIME_NTP_NOT_UPDATE:
38             return JsErrorCode::NTP_NOT_UPDATE_ERROR;
39         default:
40             return JsErrorCode::ERROR;
41     }
42 }
43 
CreateNapiNumber(napi_env env,int32_t objName)44 napi_value NapiUtils::CreateNapiNumber(napi_env env, int32_t objName)
45 {
46     napi_value prop = nullptr;
47     napi_create_int32(env, objName, &prop);
48     return prop;
49 }
50 
GetUndefinedValue(napi_env env)51 napi_value NapiUtils::GetUndefinedValue(napi_env env)
52 {
53     napi_value result{};
54     napi_get_undefined(env, &result);
55     return result;
56 }
57 
GetValue(napi_env env,napi_value in,std::string & out)58 napi_status NapiUtils::GetValue(napi_env env, napi_value in, std::string &out)
59 {
60     napi_valuetype type = napi_undefined;
61     napi_status status = napi_typeof(env, in, &type);
62     CHECK_RETURN(TIME_MODULE_JS_NAPI, (status == napi_ok) && (type == napi_string), "invalid type", napi_invalid_arg);
63     size_t maxLen = STR_MAX_LENGTH;
64     napi_get_value_string_utf8(env, in, nullptr, 0, &maxLen);
65     if (maxLen >= STR_MAX_LENGTH) {
66         return napi_invalid_arg;
67     }
68     char buf[STR_MAX_LENGTH + STR_TAIL_LENGTH]{};
69     size_t len = 0;
70     status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
71     if (status == napi_ok) {
72         out = std::string(buf);
73     }
74     return status;
75 }
76 
ThrowError(napi_env env,const char * napiMessage,int32_t napiCode)77 napi_status NapiUtils::ThrowError(napi_env env, const char *napiMessage, int32_t napiCode)
78 {
79     napi_value message = nullptr;
80     napi_value code = nullptr;
81     napi_value result = nullptr;
82     napi_create_string_utf8(env, napiMessage, NAPI_AUTO_LENGTH, &message);
83     napi_create_error(env, nullptr, message, &result);
84     napi_create_int32(env, napiCode, &code);
85     napi_set_named_property(env, result, "code", code);
86     napi_throw(env, result);
87     return napi_ok;
88 }
89 
GetErrorMessage(int32_t errCode)90 std::string NapiUtils::GetErrorMessage(int32_t errCode)
91 {
92     auto it = CODE_TO_MESSAGE.find(errCode);
93     if (it != CODE_TO_MESSAGE.end()) {
94         return it->second;
95     }
96     return std::string(SYSTEM_ERROR);
97 }
98 
GetCallbackErrorValue(napi_env env,int32_t errCode,const std::string & message)99 napi_value NapiUtils::GetCallbackErrorValue(napi_env env, int32_t errCode, const std::string &message)
100 {
101     napi_value result = nullptr;
102     napi_value eCode = nullptr;
103     if (errCode == JsErrorCode::ERROR_OK) {
104         napi_get_undefined(env, &result);
105         return result;
106     }
107     NAPI_CALL(env, napi_create_object(env, &result));
108     if (errCode == JsErrorCode::ERROR) {
109         NAPI_CALL(env, napi_create_int32(env, errCode, &eCode));
110         NAPI_CALL(env, napi_set_named_property(env, result, "code", eCode));
111 
112         napi_value str;
113         size_t str_len = strlen(message.c_str());
114         NAPI_CALL(env, napi_create_string_utf8(env, message.c_str(), str_len, &str));
115         NAPI_CALL(env, napi_set_named_property(env, result, "message", str));
116     }
117     return result;
118 }
119 
NapiGetNull(napi_env env)120 napi_value NapiUtils::NapiGetNull(napi_env env)
121 {
122     napi_value result = nullptr;
123     napi_get_null(env, &result);
124     return result;
125 }
126 
SetPromise(napi_env env,napi_deferred deferred,int32_t errorCode,const std::string & message,napi_value result)127 void NapiUtils::SetPromise(napi_env env, napi_deferred deferred, int32_t errorCode, const std::string &message,
128     napi_value result)
129 {
130     if (errorCode == JsErrorCode::ERROR_OK) {
131         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result));
132         return;
133     }
134     NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, GetCallbackErrorValue(env, errorCode, message)));
135 }
136 
SetCallback(napi_env env,napi_ref callbackIn,int32_t errorCode,const std::string & message,napi_value result)137 void NapiUtils::SetCallback(napi_env env, napi_ref callbackIn, int32_t errorCode, const std::string &message,
138     napi_value result)
139 {
140     napi_value undefined = nullptr;
141     napi_get_undefined(env, &undefined);
142 
143     napi_value callback = nullptr;
144     napi_value resultOut = nullptr;
145     napi_get_reference_value(env, callbackIn, &callback);
146     napi_value results[2] = { 0 };
147     results[0] = GetCallbackErrorValue(env, errorCode, message);
148     results[1] = result;
149     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, ARGC_TWO, &results[0], &resultOut));
150 }
151 
ReturnCallbackPromise(napi_env env,const CallbackPromiseInfo & info,napi_value result)152 void NapiUtils::ReturnCallbackPromise(napi_env env, const CallbackPromiseInfo &info, napi_value result)
153 {
154     if (info.isCallback) {
155         SetCallback(env, info.callback, info.errorCode, info.message, result);
156     } else {
157         SetPromise(env, info.deferred, info.errorCode, info.message, result);
158     }
159 }
160 
JSParaError(napi_env env,napi_ref callback)161 napi_value NapiUtils::JSParaError(napi_env env, napi_ref callback)
162 {
163     if (callback) {
164         return GetCallbackErrorValue(env, ERROR, NapiUtils::GetErrorMessage(JsErrorCode::PARAMETER_ERROR));
165     } else {
166         napi_value promise = nullptr;
167         napi_deferred deferred = nullptr;
168         napi_create_promise(env, &deferred, &promise);
169         SetPromise(env, deferred, ERROR, NapiUtils::GetErrorMessage(JsErrorCode::PARAMETER_ERROR), NapiGetNull(env));
170         return promise;
171     }
172 }
173 
ParseParametersBySetTime(napi_env env,const napi_value (& argv)[SET_TIME_MAX_PARA],size_t argc,int64_t & times,napi_ref & callback)174 napi_value NapiUtils::ParseParametersBySetTime(napi_env env, const napi_value (&argv)[SET_TIME_MAX_PARA], size_t argc,
175     int64_t &times, napi_ref &callback)
176 {
177     NAPI_ASSERTP_RETURN(env, argc >= SET_TIME_MAX_PARA - 1, "Wrong number of arguments");
178     napi_valuetype valueType = napi_undefined;
179 
180     // argv[0]: times or date object
181     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
182     NAPI_ASSERTP_RETURN(env, valueType == napi_number || valueType == napi_object,
183                         "Parameter error. The type of time must be number or date.");
184     if (valueType == napi_number) {
185         napi_get_value_int64(env, argv[0], &times);
186         NAPI_ASSERTP_RETURN(env, times >= 0, "Wrong argument timer. Positive number expected.");
187     } else {
188         bool hasProperty = false;
189         napi_valuetype resValueType = napi_undefined;
190         NAPI_CALL(env, napi_has_named_property(env, argv[0], "getTime", &hasProperty));
191         NAPI_ASSERTP_RETURN(env, hasProperty, "type expected.");
192         napi_value getTimeFunc = nullptr;
193         napi_get_named_property(env, argv[0], "getTime", &getTimeFunc);
194         napi_value getTimeResult = nullptr;
195         napi_call_function(env, argv[0], getTimeFunc, 0, nullptr, &getTimeResult);
196         NAPI_CALL(env, napi_typeof(env, getTimeResult, &resValueType));
197         NAPI_ASSERTP_RETURN(env, resValueType == napi_number, "type mismatch");
198         napi_get_value_int64(env, getTimeResult, &times);
199     }
200 
201     // argv[1]:callback
202     if (argc >= SET_TIME_MAX_PARA) {
203         NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
204         NAPI_ASSERTP_RETURN(env, valueType == napi_function, "Parameter error. The type of callback must be function.");
205         napi_create_reference(env, argv[1], 1, &callback);
206     }
207     return NapiGetNull(env);
208 }
209 
ParseParametersBySetTimezone(napi_env env,const napi_value (& argv)[SET_TIMEZONE_MAX_PARA],size_t argc,std::string & timezoneId,napi_ref & callback)210 napi_value NapiUtils::ParseParametersBySetTimezone(napi_env env, const napi_value (&argv)[SET_TIMEZONE_MAX_PARA],
211     size_t argc, std::string &timezoneId, napi_ref &callback)
212 {
213     NAPI_ASSERTP_RETURN(env, argc >= SET_TIMEZONE_MAX_PARA - 1, "Wrong number of arguments");
214     napi_valuetype valueType = napi_undefined;
215 
216     // argv[0]: timezoneid
217     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
218     NAPI_ASSERTP_RETURN(env, valueType == napi_string, "Parameter error. The type of timezone must be string.");
219     char timeZoneChars[MAX_TIME_ZONE_ID];
220     size_t copied;
221     napi_get_value_string_utf8(env, argv[0], timeZoneChars, MAX_TIME_ZONE_ID - 1, &copied);
222     TIME_HILOGD(TIME_MODULE_JNI, "timezone str: %{public}s", timeZoneChars);
223 
224     timezoneId = std::string(timeZoneChars);
225 
226     // argv[1]:callback
227     if (argc >= SET_TIMEZONE_MAX_PARA) {
228         NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
229         NAPI_ASSERTP_RETURN(env, valueType == napi_function, "Parameter error. The type of callback must be function.");
230         napi_create_reference(env, argv[1], 1, &callback);
231     }
232     return NapiGetNull(env);
233 }
234 
ParseParametersGet(napi_env env,const napi_value (& argv)[SET_TIMEZONE_MAX_PARA],size_t argc,napi_ref & callback)235 napi_value NapiUtils::ParseParametersGet(napi_env env, const napi_value (&argv)[SET_TIMEZONE_MAX_PARA], size_t argc,
236     napi_ref &callback)
237 {
238     napi_valuetype valueType = napi_undefined;
239     if (argc == 1) {
240         NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
241         NAPI_ASSERTP_RETURN(env, valueType == napi_function, "Parameter error. The type of callback must be function.");
242         napi_create_reference(env, argv[0], 1, &callback);
243     }
244     return NapiGetNull(env);
245 }
246 
ParseParametersGetNA(napi_env env,const napi_value (& argv)[SET_TIMEZONE_MAX_PARA],size_t argc,napi_ref & callback,bool * isNano)247 napi_value NapiUtils::ParseParametersGetNA(napi_env env, const napi_value (&argv)[SET_TIMEZONE_MAX_PARA], size_t argc,
248     napi_ref &callback, bool *isNano)
249 {
250     napi_valuetype valueType = napi_undefined;
251     if (argc == 1) {
252         NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
253         if (valueType == napi_function) {
254             napi_create_reference(env, argv[0], 1, &callback);
255         } else if (valueType == napi_boolean) {
256             napi_get_value_bool(env, argv[0], isNano);
257         }
258     } else if (argc == ARGC_TWO) {
259         napi_get_value_bool(env, argv[0], isNano);
260         napi_create_reference(env, argv[1], 1, &callback);
261     }
262     return NapiGetNull(env);
263 }
264 } // namespace Time
265 } // namespace MiscServices
266 } // namespace OHOS