• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "simple_number_format_addon.h"
21 
22 namespace OHOS {
23 namespace Global {
24 namespace I18n {
25 static thread_local napi_ref* g_SimpleNumberFormatConstructor = nullptr;
26 
SimpleNumberFormatAddon()27 SimpleNumberFormatAddon::SimpleNumberFormatAddon() {}
28 
~SimpleNumberFormatAddon()29 SimpleNumberFormatAddon::~SimpleNumberFormatAddon() {}
30 
Destructor(napi_env env,void * nativeObject,void * hint)31 void SimpleNumberFormatAddon::Destructor(napi_env env, void *nativeObject, void *hint)
32 {
33     if (!nativeObject) {
34         return;
35     }
36     delete reinterpret_cast<SimpleNumberFormatAddon *>(nativeObject);
37     nativeObject = nullptr;
38 }
39 
InitSimpleNumberFormat(napi_env env,napi_value exports)40 napi_value SimpleNumberFormatAddon::InitSimpleNumberFormat(napi_env env, napi_value exports)
41 {
42     napi_property_descriptor properties[] = {
43         DECLARE_NAPI_FUNCTION("format", Format),
44     };
45 
46     napi_value constructor = nullptr;
47     napi_status status = napi_define_class(env, "SimpleNumberFormat", NAPI_AUTO_LENGTH,
48         SimpleNumberFormatConstructor, nullptr, sizeof(properties) / sizeof(napi_property_descriptor),
49         properties, &constructor);
50     if (status != napi_ok) {
51         HILOG_ERROR_I18N("InitSimpleNumberFormat: Failed to define class SimpleNumberFormat at Init.");
52         return nullptr;
53     }
54 
55     g_SimpleNumberFormatConstructor = new (std::nothrow) napi_ref;
56     if (!g_SimpleNumberFormatConstructor) {
57         HILOG_ERROR_I18N("InitSimpleNumberFormat: Failed to create SimpleNumberFormat ref at init.");
58         return nullptr;
59     }
60     status = napi_create_reference(env, constructor, 1, g_SimpleNumberFormatConstructor);
61     if (status != napi_ok) {
62         HILOG_ERROR_I18N(
63             "InitSimpleNumberFormat: Failed to create reference g_SimpleNumberFormatConstructor at init.");
64         return nullptr;
65     }
66 
67     status = napi_set_named_property(env, exports, "SimpleNumberFormat", constructor);
68     if (status != napi_ok) {
69         HILOG_ERROR_I18N("InitSimpleNumberFormat: Set property failed at init.");
70         return nullptr;
71     }
72     return exports;
73 }
74 
GetSimpleNumberFormatBySkeleton(napi_env env,napi_callback_info info)75 napi_value SimpleNumberFormatAddon::GetSimpleNumberFormatBySkeleton(napi_env env, napi_callback_info info)
76 {
77     size_t argc = 2;
78     napi_value argv[2] = { nullptr };
79     napi_value thisVar = nullptr;
80     void *data = nullptr;
81     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
82     if (status != napi_ok) {
83         HILOG_ERROR_I18N("GetSimpleNumberFormatBySkeleton: Get cb info failed.");
84         return nullptr;
85     }
86 
87     napi_value constructor = nullptr;
88     if (g_SimpleNumberFormatConstructor == nullptr) {
89         HILOG_ERROR_I18N("Failed to create g_SimpleNumberFormatConstructor");
90         return nullptr;
91     }
92     status = napi_get_reference_value(env, *g_SimpleNumberFormatConstructor, &constructor);
93     if (status != napi_ok) {
94         HILOG_ERROR_I18N("GetSimpleNumberFormatBySkeleton: Failed to create reference.");
95         return nullptr;
96     }
97 
98     napi_value result = nullptr;
99     status = napi_new_instance(env, constructor, argc, argv, &result);
100     if (status != napi_ok) {
101         HILOG_ERROR_I18N("GetSimpleNumberFormatBySkeleton: Create instance failed.");
102         return nullptr;
103     }
104     return result;
105 }
106 
Format(napi_env env,napi_callback_info info)107 napi_value SimpleNumberFormatAddon::Format(napi_env env, napi_callback_info info)
108 {
109     size_t argc = 1;
110     napi_value argv[1] = { 0 };
111     napi_value thisVar = nullptr;
112     void *data = nullptr;
113     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
114     if (status != napi_ok) {
115         HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Get cb info failed.");
116         return VariableConvertor::CreateString(env, "");
117     } else if (argc < 1) {
118         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "value", "", true);
119         return VariableConvertor::CreateString(env, "");
120     }
121 
122     napi_valuetype valueType = napi_valuetype::napi_undefined;
123     status = napi_typeof(env, argv[0], &valueType);
124     if (status != napi_ok) {
125         HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Failed to get type of argv[0].");
126         return VariableConvertor::CreateString(env, "");
127     } else if (valueType != napi_valuetype::napi_number) {
128         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "value", "number", true);
129         return VariableConvertor::CreateString(env, "");
130     }
131 
132     double value = 0;
133     status = napi_get_value_double(env, argv[0], &value);
134     if (status != napi_ok) {
135         HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Failed to get value argv[0].");
136         return VariableConvertor::CreateString(env, "");
137     }
138 
139     SimpleNumberFormatAddon* obj = nullptr;
140     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
141     if (status != napi_ok || !obj || !obj->simpleNumberFormat_) {
142         HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Unwrap SimpleNumberFormatAddon failed.");
143         return VariableConvertor::CreateString(env, "");
144     }
145 
146     std::string formatResult = obj->simpleNumberFormat_->Format(value);
147     if (formatResult.empty()) {
148         HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Format result is empty.");
149     }
150     return VariableConvertor::CreateString(env, formatResult);
151 }
152 
SimpleNumberFormatConstructor(napi_env env,napi_callback_info info)153 napi_value SimpleNumberFormatAddon::SimpleNumberFormatConstructor(napi_env env, napi_callback_info info)
154 {
155     size_t argc = 2;
156     napi_value argv[2] = { nullptr };
157     napi_value thisVar = nullptr;
158     void *data = nullptr;
159     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
160     if (status != napi_ok) {
161         HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Get cb info failed.");
162         return nullptr;
163     } else if (argc < 1) {
164         ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "skeleton", "", true);
165         return nullptr;
166     }
167 
168     VariableConvertor::VerifyType(env, "skeleton", napi_valuetype::napi_string, argv[0]);
169 
170     int32_t code = 0;
171     std::string skeleton = VariableConvertor::GetString(env, argv[0], code);
172     if (code != 0) {
173         HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Get argv[0] failed.");
174         return nullptr;
175     }
176 
177     std::unique_ptr<SimpleNumberFormatAddon> obj = std::make_unique<SimpleNumberFormatAddon>();
178     if (!obj) {
179         HILOG_ERROR_I18N("SimpleNumberFormatConstructor: create SimpleNumberFormatAddon failed.");
180         return nullptr;
181     }
182     status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
183         SimpleNumberFormatAddon::Destructor, nullptr, nullptr);
184     if (status != napi_ok) {
185         HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Wrap SimpleNumberFormatAddon failed.");
186         return nullptr;
187     }
188 
189     I18nErrorCode errCode = I18nErrorCode::SUCCESS;
190     napi_value locale = (argc > 1) ? argv[1] : nullptr;
191     obj->simpleNumberFormat_ =
192         SimpleNumberFormatAddon::InitSimpleNumberFormatContext(env, locale, skeleton, errCode);
193     if (errCode == I18nErrorCode::INVALID_NUMBER_FORMAT_SKELETON) {
194         ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "skeleton", "a valid number format skeleton", true);
195         return nullptr;
196     } else if (!obj->simpleNumberFormat_ || errCode != I18nErrorCode::SUCCESS) {
197         HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Construct SimpleNumberFormat failed.");
198         return nullptr;
199     }
200     obj.release();
201     return thisVar;
202 }
203 
InitSimpleNumberFormatContext(napi_env env,napi_value locale,const std::string & skeleton,I18nErrorCode & errCode)204 std::unique_ptr<SimpleNumberFormat> SimpleNumberFormatAddon::InitSimpleNumberFormatContext(napi_env env,
205     napi_value locale, const std::string& skeleton, I18nErrorCode& errCode)
206 {
207     if (locale == nullptr) {
208         std::shared_ptr<LocaleInfo> localeInfo = nullptr;
209         return std::make_unique<SimpleNumberFormat>(skeleton, localeInfo, errCode);
210     }
211 
212     if (VariableConvertor::GetLocaleType(env, locale) == LocaleType::BUILTINS_LOCALE) {
213         std::string localeTag = VariableConvertor::ParseBuiltinsLocale(env, locale);
214         return std::make_unique<SimpleNumberFormat>(skeleton, localeTag, errCode);
215     } else if (VariableConvertor::GetLocaleType(env, locale) == LocaleType::LOCALE_INFO) {
216         std::shared_ptr<LocaleInfo> localeInfo = VariableConvertor::ParseLocaleInfo(env, locale);
217         return std::make_unique<SimpleNumberFormat>(skeleton, localeInfo, errCode);
218     }
219     HILOG_ERROR_I18N("SimpleNumberFormatAddon::InitSimpleNumberFormatContext: Init context failed.");
220     return nullptr;
221 }
222 
CopySimpleNumberFormat()223 std::shared_ptr<SimpleNumberFormat> SimpleNumberFormatAddon::CopySimpleNumberFormat()
224 {
225     return simpleNumberFormat_;
226 }
227 } // namespace I18n
228 } // namespace Global
229 } // namespace OHOS