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 "i18n_hilog.h"
17 #include "locale_config.h"
18 #include "ohos/init_data.h"
19 #include "unicode/locid.h"
20 #include "utils.h"
21 #include "simple_number_format.h"
22
23 namespace OHOS {
24 namespace Global {
25 namespace I18n {
26 bool SimpleNumberFormat::icuInitialized = SimpleNumberFormat::Init();
27
SimpleNumberFormat(const std::string & skeleton,std::shared_ptr<LocaleInfo> localeInfo,I18nErrorCode & errCode)28 SimpleNumberFormat::SimpleNumberFormat(const std::string& skeleton, std::shared_ptr<LocaleInfo> localeInfo,
29 I18nErrorCode& errCode)
30 {
31 if (skeleton.empty()) {
32 HILOG_ERROR_I18N("SimpleNumberFormat: Skeleton is empty.");
33 errCode = I18nErrorCode::INVALID_NUMBER_FORMAT_SKELETON;
34 return;
35 }
36 std::string locale;
37 if (localeInfo == nullptr) {
38 locale = LocaleConfig::GetSystemLocale();
39 } else {
40 locale = localeInfo->GetBaseName();
41 }
42 if (locale.empty() || !LocaleConfig::IsValidTag(locale)) {
43 HILOG_ERROR_I18N("SimpleNumberFormat: Locale %{public}s is invalid.", locale.c_str());
44 errCode = I18nErrorCode::INVALID_LOCALE_TAG;
45 return;
46 }
47 UErrorCode status = U_ZERO_ERROR;
48 icu::Locale icuLocale = icu::Locale::forLanguageTag(icu::StringPiece(locale), status);
49 if (U_FAILURE(status)) {
50 HILOG_ERROR_I18N("SimpleNumberFormat: Create icu::Locale failed.");
51 errCode = I18nErrorCode::FAILED;
52 return;
53 }
54
55 icu::number::UnlocalizedNumberFormatter unlocalizedNumberFormat =
56 icu::number::NumberFormatter::forSkeleton(skeleton.c_str(), status);
57 if (U_FAILURE(status)) {
58 HILOG_ERROR_I18N("SimpleNumberFormat: Create UnlocalizedNumberFormatter failed.");
59 if (status == U_NUMBER_SKELETON_SYNTAX_ERROR) {
60 HILOG_ERROR_I18N("SimpleNumberFormat: Invalid skeleton %{public}s.", skeleton.c_str());
61 errCode = I18nErrorCode::INVALID_NUMBER_FORMAT_SKELETON;
62 return;
63 }
64 errCode = I18nErrorCode::FAILED;
65 return;
66 }
67 simpleNumberFormat = unlocalizedNumberFormat.locale(icuLocale);
68 initSuccess = true;
69 }
70
~SimpleNumberFormat()71 SimpleNumberFormat::~SimpleNumberFormat() {}
72
Format(double number)73 std::string SimpleNumberFormat::Format(double number)
74 {
75 icu::number::FormattedNumber formattedNumber = FormatToFormattedNumber(number);
76 UErrorCode status = U_ZERO_ERROR;
77 icu::UnicodeString formatResult = formattedNumber.toString(status);
78 if (U_FAILURE(status)) {
79 HILOG_ERROR_I18N("SimpleNumberFormat::Format: FormattedNumber convert to string failed.");
80 return PseudoLocalizationProcessor("");
81 }
82 std::string result;
83 formatResult.toUTF8String(result);
84 return PseudoLocalizationProcessor(result);
85 }
86
Init()87 bool SimpleNumberFormat::Init()
88 {
89 SetHwIcuDirectory();
90 return true;
91 }
92
FormatToFormattedNumber(double number)93 icu::number::FormattedNumber SimpleNumberFormat::FormatToFormattedNumber(double number)
94 {
95 if (!initSuccess) {
96 HILOG_ERROR_I18N("SimpleNumberFormat::FormatToFormattedNumber: Init failed.");
97 return {};
98 }
99 UErrorCode status = U_ZERO_ERROR;
100 icu::number::FormattedNumber formattedNumber = simpleNumberFormat.formatDouble(number, status);
101 if (U_FAILURE(status)) {
102 HILOG_ERROR_I18N("SimpleNumberFormat::FormatToFormattedNumber: Format double failed.");
103 return {};
104 }
105 return formattedNumber;
106 }
107 } // namespace I18n
108 } // namespace Global
109 } // namespace OHOS
110