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 ¶m); 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