1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #include "unicode/utypes.h" 5 6 #if !UCONFIG_NO_FORMATTING 7 #ifndef __NUMBER_MAPPER_H__ 8 #define __NUMBER_MAPPER_H__ 9 10 #include <atomic> 11 #include "number_types.h" 12 #include "unicode/currpinf.h" 13 #include "standardplural.h" 14 #include "number_patternstring.h" 15 #include "number_currencysymbols.h" 16 #include "numparse_impl.h" 17 18 U_NAMESPACE_BEGIN 19 namespace number { 20 namespace impl { 21 22 23 class PropertiesAffixPatternProvider : public AffixPatternProvider, public UMemory { 24 public: isBogus()25 bool isBogus() const { 26 return fBogus; 27 } 28 setToBogus()29 void setToBogus() { 30 fBogus = true; 31 } 32 33 void setTo(const DecimalFormatProperties& properties, UErrorCode& status); 34 35 PropertiesAffixPatternProvider() = default; // puts instance in valid but undefined state 36 PropertiesAffixPatternProvider(const DecimalFormatProperties & properties,UErrorCode & status)37 PropertiesAffixPatternProvider(const DecimalFormatProperties& properties, UErrorCode& status) { 38 setTo(properties, status); 39 } 40 41 // AffixPatternProvider Methods: 42 43 char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE; 44 45 int32_t length(int32_t flags) const U_OVERRIDE; 46 47 UnicodeString getString(int32_t flags) const U_OVERRIDE; 48 49 bool hasCurrencySign() const U_OVERRIDE; 50 51 bool positiveHasPlusSign() const U_OVERRIDE; 52 53 bool hasNegativeSubpattern() const U_OVERRIDE; 54 55 bool negativeHasMinusSign() const U_OVERRIDE; 56 57 bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE; 58 59 bool hasBody() const U_OVERRIDE; 60 61 private: 62 UnicodeString posPrefix; 63 UnicodeString posSuffix; 64 UnicodeString negPrefix; 65 UnicodeString negSuffix; 66 bool isCurrencyPattern; 67 68 const UnicodeString& getStringInternal(int32_t flags) const; 69 70 bool fBogus{true}; 71 }; 72 73 74 class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory { 75 public: isBogus()76 bool isBogus() const { 77 return fBogus; 78 } 79 setToBogus()80 void setToBogus() { 81 fBogus = true; 82 } 83 84 void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties, 85 UErrorCode& status); 86 87 // AffixPatternProvider Methods: 88 89 char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE; 90 91 int32_t length(int32_t flags) const U_OVERRIDE; 92 93 UnicodeString getString(int32_t flags) const U_OVERRIDE; 94 95 bool hasCurrencySign() const U_OVERRIDE; 96 97 bool positiveHasPlusSign() const U_OVERRIDE; 98 99 bool hasNegativeSubpattern() const U_OVERRIDE; 100 101 bool negativeHasMinusSign() const U_OVERRIDE; 102 103 bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE; 104 105 bool hasBody() const U_OVERRIDE; 106 107 private: 108 PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT]; 109 110 bool fBogus{true}; 111 }; 112 113 114 /** 115 * A struct for ownership of a few objects needed for formatting. 116 */ 117 struct DecimalFormatWarehouse { 118 PropertiesAffixPatternProvider propertiesAPP; 119 CurrencyPluralInfoAffixProvider currencyPluralInfoAPP; 120 CurrencySymbols currencySymbols; 121 }; 122 123 124 /** 125 * Internal fields for DecimalFormat. 126 * TODO: Make some of these fields by value instead of by LocalPointer? 127 */ 128 struct DecimalFormatFields : public UMemory { 129 DecimalFormatFieldsDecimalFormatFields130 DecimalFormatFields() {} 131 DecimalFormatFieldsDecimalFormatFields132 DecimalFormatFields(const DecimalFormatProperties& propsToCopy) 133 : properties(propsToCopy) {} 134 135 /** The property bag corresponding to user-specified settings and settings from the pattern string. */ 136 DecimalFormatProperties properties; 137 138 /** The symbols for the current locale. */ 139 LocalPointer<const DecimalFormatSymbols> symbols; 140 141 /** 142 * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link 143 * #format} method uses the formatter directly without needing to synchronize. 144 */ 145 LocalizedNumberFormatter formatter; 146 147 /** The lazy-computed parser for .parse() */ 148 std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {}; 149 150 /** The lazy-computed parser for .parseCurrency() */ 151 std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {}; 152 153 /** Small object ownership warehouse for the formatter and parser */ 154 DecimalFormatWarehouse warehouse; 155 156 /** The effective properties as exported from the formatter object. Used by some getters. */ 157 DecimalFormatProperties exportedProperties; 158 159 // Data for fastpath 160 bool canUseFastFormat = false; 161 struct FastFormatData { 162 char16_t cpZero; 163 char16_t cpGroupingSeparator; 164 char16_t cpMinusSign; 165 int8_t minInt; 166 int8_t maxInt; 167 } fastData; 168 }; 169 170 171 /** 172 * Utilities for converting between a DecimalFormatProperties and a MacroProps. 173 */ 174 class NumberPropertyMapper { 175 public: 176 /** Convenience method to create a NumberFormatter directly from Properties. */ 177 static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties, 178 const DecimalFormatSymbols& symbols, 179 DecimalFormatWarehouse& warehouse, UErrorCode& status); 180 181 /** Convenience method to create a NumberFormatter directly from Properties. */ 182 static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties, 183 const DecimalFormatSymbols& symbols, 184 DecimalFormatWarehouse& warehouse, 185 DecimalFormatProperties& exportedProperties, 186 UErrorCode& status); 187 188 /** 189 * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties} 190 * object. In other words, maps Properties to MacroProps. This function is used by the 191 * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline. 192 * 193 * @param properties 194 * The property bag to be mapped. 195 * @param symbols 196 * The symbols associated with the property bag. 197 * @param exportedProperties 198 * A property bag in which to store validated properties. Used by some DecimalFormat 199 * getters. 200 * @return A new MacroProps containing all of the information in the Properties. 201 */ 202 static MacroProps oldToNew(const DecimalFormatProperties& properties, 203 const DecimalFormatSymbols& symbols, DecimalFormatWarehouse& warehouse, 204 DecimalFormatProperties* exportedProperties, UErrorCode& status); 205 }; 206 207 208 } // namespace impl 209 } // namespace numparse 210 U_NAMESPACE_END 211 212 #endif //__NUMBER_MAPPER_H__ 213 #endif /* #if !UCONFIG_NO_FORMATTING */ 214