• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "displaynames_addon.h"
16 
17 #include "error_util.h"
18 #include "intl_addon.h"
19 #include "i18n_hilog.h"
20 #include "js_utils.h"
21 
22 namespace OHOS {
23 namespace Global {
24 namespace I18n {
DisplayNamesAddon()25 DisplayNamesAddon::DisplayNamesAddon() : env_(nullptr) {}
26 
~DisplayNamesAddon()27 DisplayNamesAddon::~DisplayNamesAddon()
28 {
29 }
30 
Destructor(napi_env env,void * nativeObject,void * hint)31 void DisplayNamesAddon::Destructor(napi_env env, void *nativeObject, void *hint)
32 {
33     if (!nativeObject) {
34         return;
35     }
36     delete reinterpret_cast<DisplayNamesAddon *>(nativeObject);
37     nativeObject = nullptr;
38 }
39 
InitDisplayNames(napi_env env,napi_value exports)40 napi_value DisplayNamesAddon::InitDisplayNames(napi_env env, napi_value exports)
41 {
42     napi_property_descriptor properties[] = {
43         DECLARE_NAPI_FUNCTION("of", Of),
44         DECLARE_NAPI_FUNCTION("resolvedOptions", ResolvedOptions),
45         DECLARE_NAPI_STATIC_FUNCTION("supportedLocalesOf", SupportedLocalesOf),
46     };
47 
48     napi_value constructor;
49     napi_status status = napi_define_class(env, "DisplayNames", NAPI_AUTO_LENGTH, DisplayNamesConstructor, nullptr,
50         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
51     if (status != napi_ok) {
52         HILOG_ERROR_I18N("InitDisplayNames: Define class failed when InitDisplayNames");
53         return nullptr;
54     }
55 
56     status = napi_set_named_property(env, exports, "DisplayNames", constructor);
57     if (status != napi_ok) {
58         HILOG_ERROR_I18N("InitDisplayNames: Set property failed when InitDisplayNames");
59         return nullptr;
60     }
61     return exports;
62 }
63 
DisplayNamesConstructor(napi_env env,napi_callback_info info)64 napi_value DisplayNamesAddon::DisplayNamesConstructor(napi_env env, napi_callback_info info)
65 {
66     size_t argc = 2;
67     napi_value argv[2] = { nullptr };
68     napi_value thisVar = nullptr;
69     void *data = nullptr;
70     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
71     if (status != napi_ok) {
72         HILOG_ERROR_I18N("DisplayNamesConstructor: napi get callback info failed.");
73         return nullptr;
74     }
75     std::vector<std::string> localeTags;
76     if (argc < 2) {  // 2 indicates the number of parameters
77         HILOG_ERROR_I18N("DisplayNamesConstructor: Two arguments are needed, but only get %{public}zu.", argc);
78         ErrorUtil::NapiThrowUndefined(env, "options is undefined");
79         return nullptr;
80     }
81     int32_t code = 0;
82     std::vector<std::string> localeArray = JSUtils::GetLocaleArray(env, argv[0], code);
83     localeTags.assign(localeArray.begin(), localeArray.end());
84     std::map<std::string, std::string> map = {};
85     GetOptionValues(env, argv[1], map);
86     DisplayNamesAddon* obj = new(std::nothrow) DisplayNamesAddon();
87     if (obj == nullptr) {
88         HILOG_ERROR_I18N("DisplayNamesConstructor: make unique ptr failed.");
89         return nullptr;
90     }
91     status =
92         napi_wrap(env, thisVar, reinterpret_cast<void *>(obj), DisplayNamesAddon::Destructor, nullptr, nullptr);
93     if (status != napi_ok) {
94         HILOG_ERROR_I18N("DisplayNamesConstructor: Wrap DisplayNamesAddon failed");
95         delete obj;
96         return nullptr;
97     }
98     if (!obj->InitDisplayNamesContext(env, info, localeTags, map)) {
99         return nullptr;
100     }
101     return thisVar;
102 }
103 
InitDisplayNamesContext(napi_env env,napi_callback_info info,const std::vector<std::string> & localeTags,const std::map<std::string,std::string> & map)104 bool DisplayNamesAddon::InitDisplayNamesContext(napi_env env, napi_callback_info info,
105     const std::vector<std::string> &localeTags, const std::map<std::string, std::string> &map)
106 {
107     env_ = env;
108     displaynames_ = std::make_unique<DisplayNames>(localeTags, map);
109     if (displaynames_ == nullptr) {
110         HILOG_ERROR_I18N("InitDisplayNamesContext: make_unique DisplayNames failed");
111         return false;
112     }
113     I18nErrorCode errorCode = displaynames_->GetError();
114     if (errorCode == I18nErrorCode::MISSING_PARAM) {
115         HILOG_ERROR_I18N("InitDisplayNamesContext: MISSING_PARAM failed");
116         ErrorUtil::NapiThrowUndefined(env, "type is undefined");
117         return false;
118     } else if (errorCode == I18nErrorCode::INVALID_PARAM) {
119         HILOG_ERROR_I18N("InitDisplayNamesContext: INVALID_PARAM failed");
120         ErrorUtil::NapiThrowUndefined(env, "getStringOption failed");
121         return false;
122     } else if (errorCode == I18nErrorCode::INVALID_LOCALE_TAG) {
123         HILOG_ERROR_I18N("InitDisplayNamesContext: invalid locale");
124         ErrorUtil::NapiThrowUndefined(env, "invalid locale");
125         return false;
126     }
127     return errorCode == I18nErrorCode::SUCCESS;
128 }
129 
SupportedLocalesOf(napi_env env,napi_callback_info info)130 napi_value DisplayNamesAddon::SupportedLocalesOf(napi_env env, napi_callback_info info)
131 {
132     size_t argc = 2;
133     napi_value argv[2] = { nullptr };
134     napi_value thisVar = nullptr;
135     void *data = nullptr;
136     std::vector<std::string> resultLocales = {};
137     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
138     if (status != napi_ok) {
139         HILOG_ERROR_I18N("DisplayNamesAddon::SupportedLocalesOf: napi get callback info failed.");
140         return JSUtils::CreateArray(env, resultLocales);
141     }
142     std::vector<std::string> localeTags;
143     if (argc > 0) {
144         int32_t code = 0;
145         std::vector<std::string> localeArray = JSUtils::GetLocaleArray(env, argv[0], code);
146         if (code != 0) {
147             HILOG_ERROR_I18N("DisplayNamesAddon::SupportedLocalesOf: JSUtils:GetLocaleArray failed.");
148             ErrorUtil::NapiThrowUndefined(env, "kValue is not String or Object");
149             return JSUtils::CreateArray(env, resultLocales);
150         }
151         localeTags.assign(localeArray.begin(), localeArray.end());
152     }
153     std::map<std::string, std::string> map = {};
154     if (argc > 1) {
155         JSUtils::GetOptionValue(env, argv[1], "localeMatcher", map);
156     }
157     I18nErrorCode i18nStatus = I18nErrorCode::SUCCESS;
158     resultLocales = DisplayNames::SupportedLocalesOf(localeTags, map, i18nStatus);
159     if (i18nStatus == I18nErrorCode::INVALID_PARAM) {
160         HILOG_ERROR_I18N("DisplayNamesAddon::SupportedLocalesOf: SupportedLocalesOf invalid param");
161         ErrorUtil::NapiThrowUndefined(env, "getStringOption failed");
162     } else if (i18nStatus == I18nErrorCode::INVALID_LOCALE_TAG) {
163         HILOG_ERROR_I18N("DisplayNamesAddon::SupportedLocalesOf: SupportedLocalesOf invalid locale");
164         ErrorUtil::NapiThrowUndefined(env, "invalid locale");
165     }
166     return JSUtils::CreateArray(env, resultLocales);
167 }
168 
Of(napi_env env,napi_callback_info info)169 napi_value DisplayNamesAddon::Of(napi_env env, napi_callback_info info)
170 {
171     size_t argc = 1;
172     napi_value argv[1] = { nullptr };
173     napi_value thisVar = nullptr;
174     void *data = nullptr;
175     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
176     if (status != napi_ok) {
177         HILOG_ERROR_I18N("DisplayNamesAddon::Of: napi get callback info failed.");
178         return JSUtils::CreateEmptyString(env);
179     }
180     if (argc < 1) {
181         HILOG_ERROR_I18N("DisplayNamesAddon::Of: missing code param.");
182         ErrorUtil::NapiThrowUndefined(env, "code is undefined");
183         return JSUtils::CreateEmptyString(env);
184     }
185     int32_t errorCode = 0;
186     std::string code = JSUtils::GetString(env, argv[0], errorCode);
187     if (errorCode != 0) {
188         return JSUtils::CreateEmptyString(env);
189     }
190 
191     DisplayNamesAddon *obj = nullptr;
192     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
193     if (status != napi_ok || !obj || !obj->displaynames_) {
194         HILOG_ERROR_I18N("DisplayNamesAddon::Of: Get DisplayNames object failed");
195         return JSUtils::CreateEmptyString(env);
196     }
197     std::string displayResult = obj->displaynames_->Display(code);
198     I18nErrorCode i18nErrorCode = obj->displaynames_->GetError();
199     if (i18nErrorCode != I18nErrorCode::SUCCESS) {
200         std::string errorMessage = obj->displaynames_->GetErrorMessage();
201         HILOG_ERROR_I18N("DisplayNamesAddon::Of: %{public}s.", errorMessage.c_str());
202         ErrorUtil::NapiThrowUndefined(env, errorMessage);
203         return JSUtils::CreateEmptyString(env);
204     }
205     return JSUtils::CreateString(env, displayResult);
206 }
207 
ResolvedOptions(napi_env env,napi_callback_info info)208 napi_value DisplayNamesAddon::ResolvedOptions(napi_env env, napi_callback_info info)
209 {
210     napi_value result = nullptr;
211     napi_status status = napi_create_object(env, &result);
212     if (status != napi_ok) {
213         return JSUtils::CreateEmptyObject(env);
214     }
215 
216     napi_value thisVar = nullptr;
217     void *data = nullptr;
218     status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
219     if (status != napi_ok) {
220         return result;
221     }
222     DisplayNamesAddon *obj = nullptr;
223     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
224     if (status != napi_ok || !obj || !obj->displaynames_) {
225         HILOG_ERROR_I18N("DisplayNamesAddon::ResolvedOptions: Get DisplayNames object failed");
226         return result;
227     }
228     std::map<std::string, std::string> options = obj->displaynames_->ResolvedOptions();
229     JSUtils::SetOptionProperties(env, result, options, "locale");
230     JSUtils::SetOptionProperties(env, result, options, "style");
231     JSUtils::SetOptionProperties(env, result, options, "type");
232     JSUtils::SetOptionProperties(env, result, options, "fallback");
233     JSUtils::SetOptionProperties(env, result, options, "languageDisplay");
234     return result;
235 }
236 
GetOptionValues(napi_env env,napi_value options,std::map<std::string,std::string> & map)237 void DisplayNamesAddon::GetOptionValues(napi_env env, napi_value options, std::map<std::string, std::string> &map)
238 {
239     JSUtils::GetOptionValue(env, options, "localeMatcher", map);
240     JSUtils::GetOptionValue(env, options, "style", map);
241     JSUtils::GetOptionValue(env, options, "type", map);
242     JSUtils::GetOptionValue(env, options, "fallback", map);
243     JSUtils::GetOptionValue(env, options, "languageDisplay", map);
244 }
245 } // namespace I18n
246 } // namespace Global
247 } // namespace OHOS