• 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 #include "number_format_addon.h"
16 
17 #include "i18n_hilog.h"
18 #include "js_utils.h"
19 
20 namespace OHOS {
21 namespace Global {
22 namespace I18n {
NumberFormatAddon()23 NumberFormatAddon::NumberFormatAddon()
24 {
25 }
26 
~NumberFormatAddon()27 NumberFormatAddon::~NumberFormatAddon()
28 {
29 }
30 
Destructor(napi_env env,void * nativeObject,void * hint)31 void NumberFormatAddon::Destructor(napi_env env, void *nativeObject, void *hint)
32 {
33     if (!nativeObject) {
34         return;
35     }
36     delete reinterpret_cast<NumberFormatAddon *>(nativeObject);
37     nativeObject = nullptr;
38 }
39 
InitNumberFormat(napi_env env,napi_value exports)40 napi_value NumberFormatAddon::InitNumberFormat(napi_env env, napi_value exports)
41 {
42     napi_property_descriptor properties[] = {
43         DECLARE_NAPI_FUNCTION("format", FormatNumber),
44         DECLARE_NAPI_FUNCTION("formatRange", FormatRangeNumber),
45         DECLARE_NAPI_FUNCTION("resolvedOptions", GetNumberResolvedOptions)
46     };
47 
48     napi_value constructor = nullptr;
49     napi_status status = napi_define_class(env, "NumberFormat", NAPI_AUTO_LENGTH, NumberFormatConstructor, nullptr,
50         sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor);
51     if (status != napi_ok) {
52         HILOG_ERROR_I18N("Define class failed when InitNumberFormat");
53         return nullptr;
54     }
55 
56     status = napi_set_named_property(env, exports, "NumberFormat", constructor);
57     if (status != napi_ok) {
58         HILOG_ERROR_I18N("Set property failed when InitNumberFormat");
59         return nullptr;
60     }
61     return exports;
62 }
63 
NumberFormatConstructor(napi_env env,napi_callback_info info)64 napi_value NumberFormatAddon::NumberFormatConstructor(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         return nullptr;
73     }
74     std::vector<std::string> localeTags;
75     if (argc > 0) {
76         int32_t code = 0;
77         std::vector<std::string> localeArray = JSUtils::GetLocaleArray(env, argv[0], code);
78         if (code != 0) {
79             return nullptr;
80         }
81         localeTags.assign(localeArray.begin(), localeArray.end());
82     }
83     std::map<std::string, std::string> map = {};
84     if (argc > 1) {
85         JSUtils::GetNumberOptionValues(env, argv[1], map);
86     }
87     std::unique_ptr<NumberFormatAddon> obj = std::make_unique<NumberFormatAddon>();
88     if (obj == nullptr) {
89         return nullptr;
90     }
91     status =
92         napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()), NumberFormatAddon::Destructor, nullptr, nullptr);
93     if (status != napi_ok) {
94         HILOG_ERROR_I18N("NumberFormatConstructor: Wrap NumberFormatAddon failed");
95         return nullptr;
96     }
97     if (!obj->InitNumberFormatContext(env, info, localeTags, map)) {
98         HILOG_ERROR_I18N("Init NumberFormat failed");
99         return nullptr;
100     }
101     obj.release();
102     return thisVar;
103 }
104 
InitNumberFormatContext(napi_env env,napi_callback_info info,std::vector<std::string> localeTags,std::map<std::string,std::string> & map)105 bool NumberFormatAddon::InitNumberFormatContext(napi_env env, napi_callback_info info,
106     std::vector<std::string> localeTags, std::map<std::string, std::string> &map)
107 {
108     napi_value global = nullptr;
109     napi_status status = napi_get_global(env, &global);
110     if (status != napi_ok) {
111         HILOG_ERROR_I18N("InitNumberFormatContext: Get global failed");
112         return false;
113     }
114     numberfmt_ = std::make_shared<NumberFormat>(localeTags, map);
115 
116     return numberfmt_ != nullptr;
117 }
118 
FormatNumber(napi_env env,napi_callback_info info)119 napi_value NumberFormatAddon::FormatNumber(napi_env env, napi_callback_info info)
120 {
121     size_t argc = 1;
122     napi_value argv[1] = { 0 };
123     napi_value thisVar = nullptr;
124     void *data = nullptr;
125     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
126     if (status != napi_ok) {
127         return nullptr;
128     }
129     double number = 0;
130     status = napi_get_value_double(env, argv[0], &number);
131     if (status != napi_ok) {
132         return nullptr;
133     }
134     NumberFormatAddon *obj = nullptr;
135     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
136     if (status != napi_ok || !obj || !obj->numberfmt_) {
137         HILOG_ERROR_I18N("FormatNumber: Get NumberFormat object failed");
138         return nullptr;
139     }
140     std::string value = obj->numberfmt_->Format(number);
141     napi_value result = nullptr;
142     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
143     if (status != napi_ok) {
144         HILOG_ERROR_I18N("FormatNumber: Create format string failed");
145         return nullptr;
146     }
147     return result;
148 }
149 
FormatRangeNumber(napi_env env,napi_callback_info info)150 napi_value NumberFormatAddon::FormatRangeNumber(napi_env env, napi_callback_info info)
151 {
152     size_t argc = 2;
153     napi_value argv[2] = { 0 };
154     napi_value thisVar = nullptr;
155     void *data = nullptr;
156     napi_status status = napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
157     if (status != napi_ok) {
158         HILOG_ERROR_I18N("FormatRangeNumber: Get parameter info failed");
159         return JSUtils::CreateEmptyString(env);
160     }
161     if (argc != 2) { // 2 is parameter count
162         HILOG_ERROR_I18N("FormatRangeNumber: Insufficient parameters");
163         return JSUtils::CreateEmptyString(env);
164     }
165     double start = 0;
166     double end = 0;
167     status = napi_get_value_double(env, argv[0], &start);
168     if (status != napi_ok) {
169         HILOG_ERROR_I18N("FormatRangeNumber: Get first param value failed");
170         return JSUtils::CreateEmptyString(env);
171     }
172     status = napi_get_value_double(env, argv[1], &end);
173     if (status != napi_ok) {
174         HILOG_ERROR_I18N("FormatRangeNumber: Get second param value failed");
175         return JSUtils::CreateEmptyString(env);
176     }
177     NumberFormatAddon *obj = nullptr;
178     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
179     if (status != napi_ok || !obj || !obj->numberfmt_) {
180         HILOG_ERROR_I18N("FormatRangeNumber: Get NumberFormat object failed");
181         return JSUtils::CreateEmptyString(env);
182     }
183     std::string value = obj->numberfmt_->FormatRange(start, end);
184     napi_value result;
185     status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &result);
186     if (status != napi_ok) {
187         HILOG_ERROR_I18N("create string js variable failed.");
188         return JSUtils::CreateEmptyString(env);
189     }
190     return result;
191 }
192 
GetNumberResolvedOptions(napi_env env,napi_callback_info info)193 napi_value NumberFormatAddon::GetNumberResolvedOptions(napi_env env, napi_callback_info info)
194 {
195     napi_value thisVar = nullptr;
196     void *data = nullptr;
197     napi_status status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
198     if (status != napi_ok) {
199         return nullptr;
200     }
201     NumberFormatAddon *obj = nullptr;
202     status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&obj));
203     if (status != napi_ok || !obj || !obj->numberfmt_) {
204         HILOG_ERROR_I18N("GetNumberResolvedOptions: Get NumberFormat object failed");
205         return nullptr;
206     }
207     napi_value result = nullptr;
208     status = napi_create_object(env, &result);
209     if (status != napi_ok) {
210         return nullptr;
211     }
212     std::map<std::string, std::string> options = {};
213     obj->numberfmt_->GetResolvedOptions(options);
214     JSUtils::SetOptionProperties(env, result, options, "locale");
215     JSUtils::SetOptionProperties(env, result, options, "currency");
216     JSUtils::SetOptionProperties(env, result, options, "currencySign");
217     JSUtils::SetOptionProperties(env, result, options, "currencyDisplay");
218     JSUtils::SetOptionProperties(env, result, options, "unit");
219     JSUtils::SetOptionProperties(env, result, options, "unitDisplay");
220     JSUtils::SetOptionProperties(env, result, options, "signDisplay");
221     JSUtils::SetOptionProperties(env, result, options, "compactDisplay");
222     JSUtils::SetOptionProperties(env, result, options, "notation");
223     JSUtils::SetOptionProperties(env, result, options, "style");
224     JSUtils::SetOptionProperties(env, result, options, "numberingSystem");
225     JSUtils::SetOptionProperties(env, result, options, "unitUsage");
226     JSUtils::SetBooleanOptionProperties(env, result, options, "useGrouping");
227     JSUtils::SetIntegerOptionProperties(env, result, options, "minimumIntegerDigits");
228     JSUtils::SetIntegerOptionProperties(env, result, options, "minimumFractionDigits");
229     JSUtils::SetIntegerOptionProperties(env, result, options, "maximumFractionDigits");
230     JSUtils::SetIntegerOptionProperties(env, result, options, "minimumSignificantDigits");
231     JSUtils::SetIntegerOptionProperties(env, result, options, "maximumSignificantDigits");
232     JSUtils::SetOptionProperties(env, result, options, "localeMatcher");
233     return result;
234 }
235 
CopyNumberFormat()236 std::shared_ptr<NumberFormat> NumberFormatAddon::CopyNumberFormat()
237 {
238     return numberfmt_;
239 }
240 } // namespace I18n
241 } // namespace Global
242 } // namespace OHOS