• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef OHOS_GLOBAL_I18N_NUMBER_FORMAT_H
16 #define OHOS_GLOBAL_I18N_NUMBER_FORMAT_H
17 
18 #include <map>
19 #include <mutex>
20 #include <set>
21 #include <unordered_map>
22 #include <vector>
23 #include "unicode/formattedvalue.h"
24 #include "unicode/numberformatter.h"
25 #include "unicode/locid.h"
26 #include "unicode/numfmt.h"
27 #include "unicode/unum.h"
28 #include "unicode/decimfmt.h"
29 #include "unicode/localebuilder.h"
30 #include "unicode/numsys.h"
31 #include "unicode/measfmt.h"
32 #include "unicode/measunit.h"
33 #include "unicode/measure.h"
34 #include "unicode/currunit.h"
35 #include "unicode/fmtable.h"
36 #include "unicode/ures.h"
37 #include "unicode/ulocdata.h"
38 #include "number_utils.h"
39 #include "number_utypes.h"
40 #include "i18n_types.h"
41 #include "locale_info.h"
42 #include "measure_data.h"
43 #include "relative_time_format.h"
44 #include "unicode/numberrangeformatter.h"
45 
46 namespace OHOS {
47 namespace Global {
48 namespace I18n {
49 struct FormatPartParam {
50     int previousLimit;
51     bool lastFieldGroup;
52     int groupLeapLength;
53     double number;
54     std::string napiType;
55 };
56 
57 class NumberFormat {
58 public:
59     NumberFormat(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs);
60     NumberFormat(const std::vector<std::string> &localeTags,
61         std::map<std::string, std::string> &configs, bool flag);
62     virtual ~NumberFormat();
63     std::string Format(double number);
64     std::string FormatBigInt(const std::string &number);
65     bool IsRelativeTimeFormat(double number);
66     icu::number::FormattedNumber FormatToFormattedNumber(double number);
67     icu::FormattedRelativeDateTime FormatToFormattedRelativeDateTime(double number);
68     std::string FormatRange(double start, double end);
69     std::string FormatJsRange(double first, double second);
70     void GetResolvedOptions(std::map<std::string, std::string> &map, bool setDefault = false);
71     std::string GetCurrency() const;
72     std::string GetCurrencySign() const;
73     std::string GetStyle() const;
74     std::string GetNumberingSystem() const;
75     std::string GetUseGrouping() const;
76     std::string GetMinimumIntegerDigits() const;
77     std::string GetMinimumFractionDigits() const;
78     std::string GetMaximumFractionDigits() const;
79     std::string GetMinimumSignificantDigits() const;
80     std::string GetMaximumSignificantDigits() const;
81     std::string GetLocaleMatcher() const;
82     void FormatToParts(std::vector<std::vector<std::string>> &result);
83     void FormatToParts(double number, std::vector<std::vector<std::string>> &result);
84     void FormatBigIntToParts(std::string &number, std::vector<std::vector<std::string>> &result);
85     void FormatRangeToParts(const double &first, const double &second,
86         std::vector<std::vector<std::string>> &result);
87     static std::vector<std::string> SupportedLocalesOf(const std::vector<std::string> &requestLocales,
88         const std::map<std::string, std::string> &configs, I18nErrorCode &status);
89     static std::string GetIcuDefaultLocale();
90     static std::string CheckNumberFormatOptions(std::map<std::string, std::string> &map, int32_t &code);
91     static std::string GetNumberPatternSample(const std::string& localeTag,
92         const std::pair<std::string, std::string>& numberPattern);
93 
94 private:
95     icu::Locale locale;
96     std::string currency;
97     std::string currencySign = "standard";
98     std::string currencyDisplayString;
99     std::string unit;
100     std::string unitDisplayString;
101     std::string styleString;
102     std::string numberingSystem;
103     std::string useGrouping;
104     std::string notationString;
105     std::string signDisplayString = "auto";
106     std::string compactDisplay;
107     std::string minimumIntegerDigits;
108     std::string minimumFractionDigits;
109     std::string maximumFractionDigits;
110     std::string minimumSignificantDigits;
111     std::string maximumSignificantDigits;
112     std::string localeBaseName;
113     std::string localeMatcher;
114     std::string unitUsage;
115     std::string unitType;
116     std::string unitMeasSys;
117     std::string roundingPriorityStr;
118     std::string roundingModeStr;
119     std::string groupingSymbol;
120     std::string decimalSymbol;
121     std::string preferredTemperature;
122     std::string measurement;
123     std::string effectiveLocale;
124     size_t roundingIncrement = 1;
125     bool createSuccess = false;
126     bool isSetFraction = false;
127     bool fromArkTs = false;
128     std::unique_ptr<LocaleInfo> localeInfo = nullptr;
129     std::unique_ptr<RelativeTimeFormat> relativeTimeFormat = nullptr;
130     icu::number::LocalizedNumberFormatter numberFormat;
131     icu::number::LocalizedNumberRangeFormatter numberRangeFormat;
132     icu::number::UnlocalizedNumberFormatter styleFormatter;
133     icu::number::Notation notation = icu::number::Notation::simple();
134     UNumberRoundingPriority roundingPriority = UNumberRoundingPriority::UNUM_ROUNDING_PRIORITY_STRICT;
135     UNumberFormatRoundingMode roundingMode = UNumberFormatRoundingMode::UNUM_ROUND_HALFUP;
136     UNumberUnitWidth unitDisplay = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT;
137     UNumberUnitWidth currencyDisplay = UNumberUnitWidth::UNUM_UNIT_WIDTH_SHORT;
138     UNumberSignDisplay signDisplay = UNumberSignDisplay::UNUM_SIGN_AUTO;
139     static const int MAX_UNIT_NUM = 500;
140     static const int DEFAULT_FRACTION_DIGITS = 3;
141     static const int DEFAULT_MAX_SIGNIFICANT_DIGITS = 21;
142     static const char *DEVICE_TYPE_NAME;
143     static const int POW_BASE_NUMBER = 10;
144     static const int CURRENCY_LEN = 3;
145     static constexpr uint32_t PERUNIT_STRING = 5;
146     static std::mutex numToCurrencyMutex;
147     static bool initISO4217;
148     static std::unordered_map<std::string, std::string> numToCurrency;
149     icu::MeasureUnit unitArray[MAX_UNIT_NUM];
150     static bool icuInitialized;
151     static bool Init();
152     static std::unordered_map<std::string, UNumberUnitWidth> unitStyle;
153     static std::unordered_map<std::string, UNumberUnitWidth> currencyStyle;
154     static std::unordered_map<std::string, UNumberSignDisplay> signAutoStyle;
155     static std::unordered_map<std::string, UNumberSignDisplay> signAccountingStyle;
156     static std::unordered_map<std::string, std::string> measurementSystem;
157     static std::unordered_map<std::string, UNumberUnitWidth> defaultUnitStyle;
158     static std::unordered_map<std::string, UNumberUnitWidth> defaultCurrencyStyle;
159     static std::unordered_map<std::string, UNumberRoundingPriority> roundingPriorityStyle;
160     static std::unordered_map<std::string, UNumberFormatRoundingMode> roundingModeStyle;
161     static std::vector<size_t> roundingIncrementList;
162     static std::map<std::string, std::string> RelativeTimeFormatConfigs;
163     static std::unordered_map<std::string, int> defaultCurrencyFractionMap;
164     static bool ReadISO4217Datas();
165     static void CheckNumberFormatOptionsExt(std::map<std::string, std::string> &map, int32_t &code,
166         const std::string &optionName, int min, int max);
167     static std::string CheckFormatOptions(std::map<std::string, std::string> &map, int32_t &code);
168     static std::string GetCurrencyFromConfig(const std::string& currency);
169 
170     void CreateRelativeTimeFormat(const std::string& locale);
171     void ParseConfigs(std::map<std::string, std::string> &configs);
172     void ParseDigitsConfigs(std::map<std::string, std::string> &configs);
173     void ParseRoundingConfigs(std::map<std::string, std::string> &configs);
174     void GetDigitsResolvedOptions(std::map<std::string, std::string> &map, bool setDefault);
175     void GetDigitsResolvedOptionsExt(std::map<std::string, std::string> &map, bool setDefault);
176     void GetMinimumFractionDigitsOption(std::map<std::string, std::string> &map);
177     void GetMaximumFractionDigitsOption(std::map<std::string, std::string> &map);
178     int GetCurrencyFractionDigits(std::map<std::string, std::string> &map);
179     void ParseExtParam(const std::string& localeTag);
180     void GetDigitsResolvedOptions(std::map<std::string, std::string> &map);
181     void InitProperties(icu::number::UnlocalizedNumberFormatter &formatter);
182     void InitUnitProperties(icu::number::UnlocalizedNumberFormatter &formatter);
183     void InitNumberPattern(icu::number::UnlocalizedNumberFormatter &formatter);
184     void InitCurrencyProperties(icu::number::UnlocalizedNumberFormatter &formatter);
185     void InitPercentStyleProperties(icu::number::UnlocalizedNumberFormatter &formatter);
186     void InitUseGroupingProperties(icu::number::UnlocalizedNumberFormatter &formatter);
187     void InitNotationProperties(icu::number::UnlocalizedNumberFormatter &formatter);
188     void InitSignProperties(icu::number::UnlocalizedNumberFormatter &formatter);
189     void InitDigitsProperties(icu::number::UnlocalizedNumberFormatter &formatter);
190     void InitNumberFormat();
191     void SetUnit(std::string &preferredUnit);
192     void SetDefaultStyle();
193     void SetPrecisionWithByte(double number, const std::string& finalUnit);
194     void HandleRoundingPriority(icu::number::UnlocalizedNumberFormatter &formatter);
195     void SetRoundingProperties(icu::number::UnlocalizedNumberFormatter &formatter);
196     int32_t GetMinimumSignificantDigitsIntValue();
197     int32_t GetMaximumSignificantDigitsIntValue();
198     int32_t GetMaximumFractionDigitsValue();
199     int32_t GetMinimumFractionDigitsValue();
200     void RelativeDateTimeFormatToParts(double number, std::string &finalUnit,
201         std::vector<std::vector<std::string>> &result);
202     bool IsRelativeTimeFormat(double number, std::string &unitForConvert);
203     void AddFormatParts(std::string typeString, std::vector<std::vector<std::string>> &result,
204         icu::UnicodeString &formatResult, int32_t start, int32_t end);
205     std::string GetSubString(icu::UnicodeString &formatResult, int32_t start, int32_t end);
206     icu::number::FormattedNumber FormatDecimalToFormattedNumber(const std::string &number);
207     void FormattedNumberParts(icu::number::FormattedNumber &formattedNumber,
208         std::vector<std::vector<std::string>> &result, const std::string &napiType, const double &number);
209     void FindAllFormatParts(icu::FormattedValue &formattedNumber, std::vector<std::vector<std::string>> &result,
210         double number, const std::string &napiType, icu::UnicodeString &formatResult);
211     void FindAllFormatParts(icu::FormattedValue &formattedNumber, std::vector<std::vector<std::string>> &result,
212         const double &first, const double &second, icu::UnicodeString &formatResult);
213     void SetEveryFormatPartItem(icu::ConstrainedFieldPosition &cfpo, icu::UnicodeString &formatResult,
214         std::vector<std::vector<std::string>> &result, FormatPartParam &param);
215     void FormatableRangeToParts(double first, double second,
216         std::vector<std::vector<std::string>> &result);
217     double GetBigIntFieldType(const std::string &bigintStr);
218     void DealWithUnitUsage(bool isFormatRange, double& firstNumber, double& secondNumber);
219     bool DealWithUnitConvert(double& finalNumber, std::string& finalUnit);
220     void ResolveLocaleTags(const std::vector<std::string> &localeTags, std::map<std::string, std::string> &configs);
221     void CreateNumberFormatWithDefaultLocale(const std::string &systemLocale,
222         std::map<std::string, std::string> &configs);
223     bool IsWellFormedUnitIdentifier(icu::MeasureUnit &icuUnit, icu::MeasureUnit &icuPerUnit);
224     bool ToMeasureUnit(const std::string &sanctionedUnit, icu::MeasureUnit &measureUnit);
225     void SetPerUnit(icu::number::UnlocalizedNumberFormatter &formatter);
226 };
227 } // namespace I18n
228 } // namespace Global
229 } // namespace OHOS
230 #endif