• 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     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