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
18U_NAMESPACE_BEGIN
19namespace number {
20namespace impl {
21
22
23class PropertiesAffixPatternProvider : public AffixPatternProvider, public UMemory {
24 public:
25 bool isBogus() const {
26 return fBogus;
27 }
28
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
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
74class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMemory {
75 public:
76 bool isBogus() const {
77 return fBogus;
78 }
79
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 */
117struct 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*/
128struct DecimalFormatFields : public UMemory {
129
130 DecimalFormatFields() {}
131
132 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 */
174class 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
210U_NAMESPACE_END
211
212#endif //__NUMBER_MAPPER_H__
213#endif /* #if !UCONFIG_NO_FORMATTING */
214