• 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 "js_utils.h"
19 #include "locale_config.h"
20 #include "variable_convertor.h"
21 #include "i18n_normalizer_addon.h"
22 
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 static thread_local napi_ref* g_normalizerConstructor = nullptr;
27 
28 const char *I18nNormalizerAddon::NORMALIZER_MODE_NFC_NAME = "NFC";
29 const char *I18nNormalizerAddon::NORMALIZER_MODE_NFD_NAME = "NFD";
30 const char *I18nNormalizerAddon::NORMALIZER_MODE_NFKC_NAME = "NFKC";
31 const char *I18nNormalizerAddon::NORMALIZER_MODE_NFKD_NAME = "NFKD";
32 
I18nNormalizerAddon()33 I18nNormalizerAddon::I18nNormalizerAddon() {}
~I18nNormalizerAddon()34 I18nNormalizerAddon::~I18nNormalizerAddon()
35 {
36 }
37 
Destructor(napi_env env,void * nativeObject,void * hint)38 void I18nNormalizerAddon::Destructor(napi_env env, void *nativeObject, void *hint)
39 {
40     if (!nativeObject) {
41         return;
42     }
43     delete reinterpret_cast<I18nNormalizerAddon *>(nativeObject);
44     nativeObject = nullptr;
45 }
46 
InitI18nNormalizer(napi_env env,napi_value exports)47 napi_value I18nNormalizerAddon::InitI18nNormalizer(napi_env env, napi_value exports)
48 {
49     napi_property_descriptor properties[] = {
50         DECLARE_NAPI_FUNCTION("normalize", Normalize),
51     };
52     napi_value constructor = nullptr;
53     napi_status status = napi_define_class(env, "Normalizer", NAPI_AUTO_LENGTH, I18nNormalizerConstructor, nullptr,
54         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
55     if (status != napi_ok) {
56         HILOG_ERROR_I18N("InitI18nNormalizer: Failed to define class Normalizer at Init");
57         return nullptr;
58     }
59     exports = I18nNormalizerAddon::InitNormalizer(env, exports);
60     g_normalizerConstructor = new (std::nothrow) napi_ref;
61     if (!g_normalizerConstructor) {
62         HILOG_ERROR_I18N("InitI18nNormalizer: Failed to create Normalizer ref at init");
63         return nullptr;
64     }
65     status = napi_create_reference(env, constructor, 1, g_normalizerConstructor);
66     if (status != napi_ok) {
67         HILOG_ERROR_I18N("InitI18nNormalizer: Failed to create reference g_normalizerConstructor at init.");
68         return nullptr;
69     }
70     return exports;
71 }
72 
InitNormalizer(napi_env env,napi_value exports)73 napi_value I18nNormalizerAddon::InitNormalizer(napi_env env, napi_value exports)
74 {
75     napi_property_descriptor properties[] = {
76         DECLARE_NAPI_STATIC_FUNCTION("getInstance", GetI18nNormalizerInstance)
77     };
78     napi_value constructor = nullptr;
79     napi_status status = napi_define_class(env, "I18nNormalizer", NAPI_AUTO_LENGTH, JSUtils::DefaultConstructor,
80         nullptr, sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
81     if (status != napi_ok) {
82         HILOG_ERROR_I18N("InitNormalizer: Failed to define class Normalizer.");
83         return nullptr;
84     }
85     status = napi_set_named_property(env, exports, "Normalizer", constructor);
86     if (status != napi_ok) {
87         HILOG_ERROR_I18N("InitNormalizer: Set property failed When InitNormalizer.");
88         return nullptr;
89     }
90     return exports;
91 }
92 
I18nNormalizerConstructor(napi_env env,napi_callback_info info)93 napi_value I18nNormalizerAddon::I18nNormalizerConstructor(napi_env env, napi_callback_info info)
94 {
95     size_t argc = 1;
96     napi_value argv[1] = { nullptr };
97     napi_value thisVar = nullptr;
98     void *data = nullptr;
99     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
100     if (status != napi_ok) {
101         return nullptr;
102     }
103     if (argc < 1) {
104         ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "mode", true);
105         return nullptr;
106     }
107     napi_valuetype valueType = napi_valuetype::napi_undefined;
108     status = napi_typeof(env, argv[0], &valueType);
109     if (status != napi_ok) {
110         return nullptr;
111     }
112     if (valueType != napi_valuetype::napi_number) {
113         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "mode", "number", true);
114         return nullptr;
115     }
116     int32_t normalizerMode;
117     status = napi_get_value_int32(env, argv[0], &normalizerMode);
118     if (status != napi_ok) {
119         return nullptr;
120     }
121     if (normalizerMode != NORMALIZER_MODE_NFC && normalizerMode != NORMALIZER_MODE_NFD &&
122         normalizerMode != NORMALIZER_MODE_NFKC && normalizerMode != NORMALIZER_MODE_NFKD) {
123         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "mode", "a valid mode", true);
124         return nullptr;
125     }
126 
127     std::unique_ptr<I18nNormalizerAddon> obj = std::make_unique<I18nNormalizerAddon>();
128     if (obj == nullptr) {
129         return nullptr;
130     }
131     status =
132         napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), I18nNormalizerAddon::Destructor, nullptr, nullptr);
133     if (status != napi_ok) {
134         return nullptr;
135     }
136     I18nNormalizerMode mode = I18nNormalizerMode(normalizerMode);
137     I18nErrorCode errorCode = I18nErrorCode::SUCCESS;
138     obj->normalizer_ = std::make_unique<I18nNormalizer>(mode, errorCode);
139     if (errorCode != I18nErrorCode::SUCCESS || !obj->normalizer_) {
140         return nullptr;
141     }
142     obj.release();
143     return thisVar;
144 }
145 
Normalize(napi_env env,napi_callback_info info)146 napi_value I18nNormalizerAddon::Normalize(napi_env env, napi_callback_info info)
147 {
148     size_t argc = 1;
149     napi_value argv[1] = { nullptr };
150     napi_value thisVar = nullptr;
151     void *data = nullptr;
152     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
153     if (status != napi_ok) {
154         return nullptr;
155     }
156     if (argc < 1) {
157         ErrorUtil::NapiNotFoundError(env, I18N_NOT_FOUND, "text", true);
158         return nullptr;
159     }
160     napi_valuetype valueType = napi_valuetype::napi_undefined;
161     status = napi_typeof(env, argv[0], &valueType);
162     if (status != napi_ok) {
163         return nullptr;
164     }
165     if (valueType != napi_valuetype::napi_string) {
166         HILOG_ERROR_I18N("Invalid parameter type");
167         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "text", "string", true);
168         return nullptr;
169     }
170     int32_t code = 0;
171     std::string text = VariableConvertor::GetString(env, argv[0], code);
172     if (code != 0) {
173         return nullptr;
174     }
175 
176     I18nNormalizerAddon *obj = nullptr;
177     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
178     if (status != napi_ok || obj == nullptr || obj->normalizer_ == nullptr) {
179         HILOG_ERROR_I18N("Get Normalizer object failed");
180         return nullptr;
181     }
182     I18nErrorCode errorCode = I18nErrorCode::SUCCESS;
183     std::string normalizedText = obj->normalizer_->Normalize(text.c_str(), static_cast<int32_t>(text.length()),
184         errorCode);
185     if (errorCode != I18nErrorCode::SUCCESS) {
186         return nullptr;
187     }
188     napi_value result = nullptr;
189     status = napi_create_string_utf8(env, normalizedText.c_str(), NAPI_AUTO_LENGTH, &result);
190     if (status != napi_ok) {
191         HILOG_ERROR_I18N("Create result failed");
192         return nullptr;
193     }
194     return result;
195 }
196 
CreateI18NNormalizerModeEnum(napi_env env)197 napi_value I18nNormalizerAddon::CreateI18NNormalizerModeEnum(napi_env env)
198 {
199     napi_value i18nNormalizerModel = nullptr;
200     napi_status status = napi_create_object(env, &i18nNormalizerModel);
201     if (status != napi_ok) {
202         return nullptr;
203     }
204     status = VariableConvertor::SetEnumValue(env, i18nNormalizerModel, NORMALIZER_MODE_NFC_NAME, NORMALIZER_MODE_NFC);
205     if (status != napi_ok) {
206         return nullptr;
207     }
208     status = VariableConvertor::SetEnumValue(env, i18nNormalizerModel, NORMALIZER_MODE_NFD_NAME, NORMALIZER_MODE_NFD);
209     if (status != napi_ok) {
210         return nullptr;
211     }
212     status =
213         VariableConvertor::SetEnumValue(env, i18nNormalizerModel, NORMALIZER_MODE_NFKC_NAME, NORMALIZER_MODE_NFKC);
214     if (status != napi_ok) {
215         return nullptr;
216     }
217     status =
218         VariableConvertor::SetEnumValue(env, i18nNormalizerModel, NORMALIZER_MODE_NFKD_NAME, NORMALIZER_MODE_NFKD);
219     if (status != napi_ok) {
220         return nullptr;
221     }
222     return i18nNormalizerModel;
223 }
224 
GetI18nNormalizerInstance(napi_env env,napi_callback_info info)225 napi_value I18nNormalizerAddon::GetI18nNormalizerInstance(napi_env env, napi_callback_info info)
226 {
227     size_t argc = 1;
228     napi_value argv[1] = { nullptr };
229     napi_value thisVar = nullptr;
230     void *data = nullptr;
231     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
232     if (status != napi_ok) {
233         HILOG_ERROR_I18N("Failed to get parameter of Normalizer.createInstance");
234         return nullptr;
235     }
236 
237     napi_value constructor = nullptr;
238     if (g_normalizerConstructor == nullptr) {
239         HILOG_ERROR_I18N("Failed to create g_normalizerConstructor");
240         return nullptr;
241     }
242     status = napi_get_reference_value(env, *g_normalizerConstructor, &constructor);
243     if (status != napi_ok) {
244         HILOG_ERROR_I18N("Failed to create reference of normalizer Constructor");
245         return nullptr;
246     }
247 
248     napi_value result = nullptr;
249     status = napi_new_instance(env, constructor, argc, argv, &result);
250     if (status != napi_ok) {
251         HILOG_ERROR_I18N("create normalizer instance failed");
252         return nullptr;
253     }
254     return result;
255 }
256 } // namespace I18n
257 } // namespace Global
258 } // namespace OHOS