• 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 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 
67     const UnicodeString& getStringInternal(int32_t flags) const;
68 
69     bool fBogus{true};
70 };
71 
72 
73 class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory {
74   public:
isBogus()75     bool isBogus() const {
76         return fBogus;
77     }
78 
setToBogus()79     void setToBogus() {
80         fBogus = true;
81     }
82 
83     void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties,
84                UErrorCode& status);
85 
86     // AffixPatternProvider Methods:
87 
88     char16_t charAt(int32_t flags, int32_t i) const U_OVERRIDE;
89 
90     int32_t length(int32_t flags) const U_OVERRIDE;
91 
92     UnicodeString getString(int32_t flags) const U_OVERRIDE;
93 
94     bool hasCurrencySign() const U_OVERRIDE;
95 
96     bool positiveHasPlusSign() const U_OVERRIDE;
97 
98     bool hasNegativeSubpattern() const U_OVERRIDE;
99 
100     bool negativeHasMinusSign() const U_OVERRIDE;
101 
102     bool containsSymbolType(AffixPatternType, UErrorCode&) const U_OVERRIDE;
103 
104     bool hasBody() const U_OVERRIDE;
105 
106   private:
107     PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT];
108 
109     bool fBogus{true};
110 };
111 
112 
113 /**
114  * A struct for ownership of a few objects needed for formatting.
115  */
116 struct DecimalFormatWarehouse {
117     PropertiesAffixPatternProvider propertiesAPP;
118     CurrencyPluralInfoAffixProvider currencyPluralInfoAPP;
119     CurrencySymbols currencySymbols;
120 };
121 
122 
123 /**
124 * Internal fields for DecimalFormat.
125 * TODO: Make some of these fields by value instead of by LocalPointer?
126 */
127 struct DecimalFormatFields : public UMemory {
128     /** The property bag corresponding to user-specified settings and settings from the pattern string. */
129     LocalPointer<DecimalFormatProperties> properties;
130 
131     /** The symbols for the current locale. */
132     LocalPointer<const DecimalFormatSymbols> symbols;
133 
134     /**
135     * The pre-computed formatter object. Setters cause this to be re-computed atomically. The {@link
136     * #format} method uses the formatter directly without needing to synchronize.
137     */
138     LocalPointer<const LocalizedNumberFormatter> formatter;
139 
140     /** The lazy-computed parser for .parse() */
141     std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicParser = {};
142 
143     /** The lazy-computed parser for .parseCurrency() */
144     std::atomic<::icu::numparse::impl::NumberParserImpl*> atomicCurrencyParser = {};
145 
146     /** Small object ownership warehouse for the formatter and parser */
147     DecimalFormatWarehouse warehouse;
148 
149     /** The effective properties as exported from the formatter object. Used by some getters. */
150     LocalPointer<DecimalFormatProperties> exportedProperties;
151 
152     // Data for fastpath
153     bool canUseFastFormat = false;
154     struct FastFormatData {
155         char16_t cpZero;
156         char16_t cpGroupingSeparator;
157         char16_t cpMinusSign;
158         int8_t minInt;
159         int8_t maxInt;
160     } fastData;
161 };
162 
163 
164 /**
165  * Utilities for converting between a DecimalFormatProperties and a MacroProps.
166  */
167 class NumberPropertyMapper {
168   public:
169     /** Convenience method to create a NumberFormatter directly from Properties. */
170     static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
171                                              const DecimalFormatSymbols& symbols,
172                                              DecimalFormatWarehouse& warehouse, UErrorCode& status);
173 
174     /** Convenience method to create a NumberFormatter directly from Properties. */
175     static UnlocalizedNumberFormatter create(const DecimalFormatProperties& properties,
176                                              const DecimalFormatSymbols& symbols,
177                                              DecimalFormatWarehouse& warehouse,
178                                              DecimalFormatProperties& exportedProperties,
179                                              UErrorCode& status);
180 
181     /**
182      * Creates a new {@link MacroProps} object based on the content of a {@link DecimalFormatProperties}
183      * object. In other words, maps Properties to MacroProps. This function is used by the
184      * JDK-compatibility API to call into the ICU 60 fluent number formatting pipeline.
185      *
186      * @param properties
187      *            The property bag to be mapped.
188      * @param symbols
189      *            The symbols associated with the property bag.
190      * @param exportedProperties
191      *            A property bag in which to store validated properties. Used by some DecimalFormat
192      *            getters.
193      * @return A new MacroProps containing all of the information in the Properties.
194      */
195     static MacroProps oldToNew(const DecimalFormatProperties& properties,
196                                const DecimalFormatSymbols& symbols, DecimalFormatWarehouse& warehouse,
197                                DecimalFormatProperties* exportedProperties, UErrorCode& status);
198 };
199 
200 
201 } // namespace impl
202 } // namespace numparse
203 U_NAMESPACE_END
204 
205 #endif //__NUMBER_MAPPER_H__
206 #endif /* #if !UCONFIG_NO_FORMATTING */
207