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 status = napi_get_reference_value(env, *g_SimpleNumberFormatConstructor, &constructor);
89 if (status != napi_ok) {
90 HILOG_ERROR_I18N("GetSimpleNumberFormatBySkeleton: Failed to create reference.");
91 return nullptr;
92 }
93
94 napi_value result = nullptr;
95 status = napi_new_instance(env, constructor, argc, argv, &result);
96 if (status != napi_ok) {
97 HILOG_ERROR_I18N("GetSimpleNumberFormatBySkeleton: Create instance failed.");
98 return nullptr;
99 }
100 return result;
101 }
102
Format(napi_env env,napi_callback_info info)103 napi_value SimpleNumberFormatAddon::Format(napi_env env, napi_callback_info info)
104 {
105 size_t argc = 1;
106 napi_value argv[1] = { 0 };
107 napi_value thisVar = nullptr;
108 void *data = nullptr;
109 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
110 if (status != napi_ok) {
111 HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Get cb info failed.");
112 return VariableConvertor::CreateString(env, "");
113 } else if (argc < 1) {
114 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "value", "", true);
115 return VariableConvertor::CreateString(env, "");
116 }
117
118 napi_valuetype valueType = napi_valuetype::napi_undefined;
119 status = napi_typeof(env, argv[0], &valueType);
120 if (status != napi_ok) {
121 HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Failed to get type of argv[0].");
122 return VariableConvertor::CreateString(env, "");
123 } else if (valueType != napi_valuetype::napi_number) {
124 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "value", "number", true);
125 return VariableConvertor::CreateString(env, "");
126 }
127
128 double value = 0;
129 status = napi_get_value_double(env, argv[0], &value);
130 if (status != napi_ok) {
131 HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Failed to get value argv[0].");
132 return VariableConvertor::CreateString(env, "");
133 }
134
135 SimpleNumberFormatAddon* obj = nullptr;
136 status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
137 if (status != napi_ok || !obj || !obj->simpleNumberFormat_) {
138 HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Unwrap SimpleNumberFormatAddon failed.");
139 return VariableConvertor::CreateString(env, "");
140 }
141
142 std::string formatResult = obj->simpleNumberFormat_->Format(value);
143 if (formatResult.empty()) {
144 HILOG_ERROR_I18N("SimpleNumberFormatAddon::Format: Format result is empty.");
145 }
146 return VariableConvertor::CreateString(env, formatResult);
147 }
148
SimpleNumberFormatConstructor(napi_env env,napi_callback_info info)149 napi_value SimpleNumberFormatAddon::SimpleNumberFormatConstructor(napi_env env, napi_callback_info info)
150 {
151 size_t argc = 2;
152 napi_value argv[2] = { nullptr };
153 napi_value thisVar = nullptr;
154 void *data = nullptr;
155 napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
156 if (status != napi_ok) {
157 HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Get cb info failed.");
158 return nullptr;
159 } else if (argc < 1) {
160 ErrorUtil::NapiThrow(env, I18N_NOT_FOUND, "skeleton", "", true);
161 return nullptr;
162 }
163
164 VariableConvertor::VerifyType(env, "skeleton", napi_valuetype::napi_string, argv[0]);
165
166 int32_t code = 0;
167 std::string skeleton = VariableConvertor::GetString(env, argv[0], code);
168 if (code != 0) {
169 HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Get argv[0] failed.");
170 return nullptr;
171 }
172
173 std::shared_ptr<LocaleInfo> localeInfo = (argc > 1)? VariableConvertor::ParseIntlLocale(env, argv[1]) : nullptr;
174
175 std::unique_ptr<SimpleNumberFormatAddon> obj = std::make_unique<SimpleNumberFormatAddon>();
176 if (!obj) {
177 HILOG_ERROR_I18N("SimpleNumberFormatConstructor: create SimpleNumberFormatAddon failed.");
178 return nullptr;
179 }
180 status = napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
181 SimpleNumberFormatAddon::Destructor, nullptr, nullptr);
182 if (status != napi_ok) {
183 HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Wrap SimpleNumberFormatAddon failed.");
184 return nullptr;
185 }
186
187 I18nErrorCode errCode = I18nErrorCode::SUCCESS;
188 obj->simpleNumberFormat_ = std::make_shared<SimpleNumberFormat>(skeleton, localeInfo, errCode);
189 if (errCode == I18nErrorCode::INVALID_NUMBER_FORMAT_SKELETON) {
190 ErrorUtil::NapiThrow(env, I18N_NOT_VALID, "skeleton", "a valid number format skeleton", true);
191 return nullptr;
192 } else if (!obj->simpleNumberFormat_ || errCode != I18nErrorCode::SUCCESS) {
193 HILOG_ERROR_I18N("SimpleNumberFormatConstructor: Construct SimpleNumberFormat failed.");
194 return nullptr;
195 }
196 obj.release();
197 return thisVar;
198 }
199
CopySimpleNumberFormat()200 std::shared_ptr<SimpleNumberFormat> SimpleNumberFormatAddon::CopySimpleNumberFormat()
201 {
202 return simpleNumberFormat_;
203 }
204 } // namespace I18n
205 } // namespace Global
206 } // namespace OHOS