• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 AutoAffixPatternProvider;
24 class CurrencyPluralInfoAffixProvider;
25 
26 
27 class PropertiesAffixPatternProvider : public AffixPatternProvider, public UMemory {
28   public:
isBogus()29     bool isBogus() const {
30         return fBogus;
31     }
32 
setToBogus()33     void setToBogus() {
34         fBogus = true;
35     }
36 
37     void setTo(const DecimalFormatProperties& properties, UErrorCode& status);
38 
39     // AffixPatternProvider Methods:
40 
41     char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;
42 
43     int32_t length(int32_t flags) const U_OVERRIDE;
44 
45     UnicodeString getString(int32_t flags) const U_OVERRIDE;
46 
47     bool hasCurrencySign() const U_OVERRIDE;
48 
49     bool positiveHasPlusSign() const U_OVERRIDE;
50 
51     bool hasNegativeSubpattern() const U_OVERRIDE;
52 
53     bool negativeHasMinusSign() const U_OVERRIDE;
54 
55     bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;
56 
57     bool hasBody() const U_OVERRIDE;
58 
59   private:
60     UnicodeString posPrefix;
61     UnicodeString posSuffix;
62     UnicodeString negPrefix;
63     UnicodeString negSuffix;
64     bool isCurrencyPattern;
65 
66     PropertiesAffixPatternProvider() = default; // puts instance in valid but undefined state
67 
68     const UnicodeString& getStringInternal(int32_t flags) const;
69 
70     bool fBogus{true};
71 
72     friend class AutoAffixPatternProvider;
73     friend class CurrencyPluralInfoAffixProvider;
74 };
75 
76 
77 class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory {
78   public:
isBogus()79     bool isBogus() const {
80         return fBogus;
81     }
82 
setToBogus()83     void setToBogus() {
84         fBogus = true;
85     }
86 
87     void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties,
88                UErrorCode& status);
89 
90     // AffixPatternProvider Methods:
91 
92     char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;
93 
94     int32_t length(int32_t flags) const U_OVERRIDE;
95 
96     UnicodeString getString(int32_t flags) const U_OVERRIDE;
97 
98     bool hasCurrencySign() const U_OVERRIDE;
99 
100     bool positiveHasPlusSign() const U_OVERRIDE;
101 
102     bool hasNegativeSubpattern() const U_OVERRIDE;
103 
104     bool negativeHasMinusSign() const U_OVERRIDE;
105 
106     bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;
107 
108     bool hasBody() const U_OVERRIDE;
109 
110   private:
111     PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT];
112 
113     CurrencyPluralInfoAffixProvider() = default;
114 
115     bool fBogus{true};
116 
117     friend class AutoAffixPatternProvider;
118 };
119 
120 
121 class AutoAffixPatternProvider {
122   public:
123     inline AutoAffixPatternProvider() = default;
124 
AutoAffixPatternProvider(const DecimalFormatProperties & properties,UErrorCode & status)125     inline AutoAffixPatternProvider(const DecimalFormatProperties& properties, UErrorCode& status) {
126         setTo(properties, status);
127     }
128 
setTo(const DecimalFormatProperties & properties,UErrorCode & status)129     inline void setTo(const DecimalFormatProperties& properties, UErrorCode& status) {
130         if (properties.currencyPluralInfo.fPtr.isNull()) {
131             propertiesAPP.setTo(properties, status);
132             currencyPluralInfoAPP.setToBogus();
133         } else {
134             propertiesAPP.setToBogus();
135             currencyPluralInfoAPP.setTo(*properties.currencyPluralInfo.fPtr, properties, status);
136         }
137     }
138 
get()139     inline const AffixPatternProvider& get() const {
140       if (!currencyPluralInfoAPP.isBogus()) {
141         return currencyPluralInfoAPP;
142       } else {
143         return propertiesAPP;
144       }
145     }
146 
147   private:
148     PropertiesAffixPatternProvider propertiesAPP;
149     CurrencyPluralInfoAffixProvider currencyPluralInfoAPP;
150 };
151 
152 
153 /**
154  * A struct for ownership of a few objects needed for formatting.
155  */
156 struct DecimalFormatWarehouse {
157     AutoAffixPatternProvider affixProvider;
158 
159 };
160 
161 
162 /**
163 * Internal fields for DecimalFormat.
164 * TODO: Make some of these fields by value instead of by LocalPointer?
165 */
166 struct DecimalFormatFields : public UMemory {
167 
DecimalFormatFieldsDecimalFormatFields168     DecimalFormatFields() {}
169 
DecimalFormatFieldsDecimalFormatFields170     DecimalFormatFields(const DecimalFormatProperties& propsToCopy)
171         : properties(propsToCopy) {}
172 
173     /** The property bag corresponding to user-specified settings and settings from the pattern string. */
174     DecimalFormatProperties properties;
175 
176     /** The symbols for the current locale. */
177     LocalPointer<const DecimalFormatSymbols> symbols;
178 
179     /**
180     * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link
181     * #format} method uses the formatter directly without needing to synchronize.
182     */
183     LocalizedNumberFormatter formatter;
184 
185     /** The lazy-computed parser for .parse() */
186     std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};
187 
188     /** The lazy-computed parser for .parseCurrency() */
189     std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {};
190 
191     /** Small object ownership warehouse for the formatter and parser */
192     DecimalFormatWarehouse warehouse;
193 
194     /** The effective properties as exported from the formatter object. Used by some getters. */
195     DecimalFormatProperties exportedProperties;
196 
197     // Data for fastpath
198     bool canUseFastFormat = false;
199     struct FastFormatData {
200         char16_t cpZero;
201         char16_t cpGroupingSeparator;
202         char16_t cpMinusSign;
203         int8_t minInt;
204         int8_t maxInt;
205     } fastData;
206 };
207 
208 
209 /**
210  * Utilities for converting between a DecimalFormatProperties and a MacroProps.
211  */
212 class NumberPropertyMapper {
213   public:
214     /** Convenience method to create a NumberFormatter directly from Properties. */
215     static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
216                                              const DecimalFormatSymbols& symbols,
217                                              DecimalFormatWarehouse& warehouse, UErrorCode& status);
218 
219     /** Convenience method to create a NumberFormatter directly from Properties. */
220     static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
221                                              const DecimalFormatSymbols& symbols,
222                                              DecimalFormatWarehouse& warehouse,
223                                              DecimalFormatProperties& exportedProperties,
224                                              UErrorCode& status);
225 
226     /**
227      * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
228      * object. In other words, maps Properties to MacroProps. This function is used by the
229      * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
230      *
231      * @param properties
232      *            The property bag to be mapped.
233      * @param symbols
234      *            The symbols associated with the property bag.
235      * @param exportedProperties
236      *            A property bag in which to store validated properties. Used by some DecimalFormat
237      *            getters.
238      * @return A new MacroProps containing all of the information in the Properties.
239      */
240     static MacroProps oldToNew(const DecimalFormatProperties& properties,
241                                const DecimalFormatSymbols& symbols, DecimalFormatWarehouse& warehouse,
242                                DecimalFormatProperties* exportedProperties, UErrorCode& status);
243 };
244 
245 
246 } // namespace impl
247 } // namespace numparse
248 U_NAMESPACE_END
249 
250 #endif //__NUMBER_MAPPER_H__
251 #endif /* #if !UCONFIG_NO_FORMATTING */
252