xref: /aosp_15_r20/external/icu/libicu/cts_headers/number_patternstring.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1*0e209d39SAndroid Build Coastguard Worker // © 2017 and later: Unicode, Inc. and others.
2*0e209d39SAndroid Build Coastguard Worker // License & terms of use: http://www.unicode.org/copyright.html
3*0e209d39SAndroid Build Coastguard Worker 
4*0e209d39SAndroid Build Coastguard Worker #include "unicode/utypes.h"
5*0e209d39SAndroid Build Coastguard Worker 
6*0e209d39SAndroid Build Coastguard Worker #if !UCONFIG_NO_FORMATTING
7*0e209d39SAndroid Build Coastguard Worker #ifndef __NUMBER_PATTERNSTRING_H__
8*0e209d39SAndroid Build Coastguard Worker #define __NUMBER_PATTERNSTRING_H__
9*0e209d39SAndroid Build Coastguard Worker 
10*0e209d39SAndroid Build Coastguard Worker 
11*0e209d39SAndroid Build Coastguard Worker #include <cstdint>
12*0e209d39SAndroid Build Coastguard Worker #include "unicode/unum.h"
13*0e209d39SAndroid Build Coastguard Worker #include "unicode/unistr.h"
14*0e209d39SAndroid Build Coastguard Worker #include "number_types.h"
15*0e209d39SAndroid Build Coastguard Worker #include "number_decimalquantity.h"
16*0e209d39SAndroid Build Coastguard Worker #include "number_decimfmtprops.h"
17*0e209d39SAndroid Build Coastguard Worker #include "number_affixutils.h"
18*0e209d39SAndroid Build Coastguard Worker 
19*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_BEGIN
20*0e209d39SAndroid Build Coastguard Worker namespace number::impl {
21*0e209d39SAndroid Build Coastguard Worker 
22*0e209d39SAndroid Build Coastguard Worker // Forward declaration
23*0e209d39SAndroid Build Coastguard Worker class PatternParser;
24*0e209d39SAndroid Build Coastguard Worker 
25*0e209d39SAndroid Build Coastguard Worker // Note: the order of fields in this enum matters for parsing.
26*0e209d39SAndroid Build Coastguard Worker enum PatternSignType {
27*0e209d39SAndroid Build Coastguard Worker     /** Render using normal positive subpattern rules */
28*0e209d39SAndroid Build Coastguard Worker     PATTERN_SIGN_TYPE_POS,
29*0e209d39SAndroid Build Coastguard Worker     /** Render using rules to force the display of a plus sign */
30*0e209d39SAndroid Build Coastguard Worker     PATTERN_SIGN_TYPE_POS_SIGN,
31*0e209d39SAndroid Build Coastguard Worker     /** Render using negative subpattern rules */
32*0e209d39SAndroid Build Coastguard Worker     PATTERN_SIGN_TYPE_NEG,
33*0e209d39SAndroid Build Coastguard Worker     /** Count for looping over the possibilities */
34*0e209d39SAndroid Build Coastguard Worker     PATTERN_SIGN_TYPE_COUNT
35*0e209d39SAndroid Build Coastguard Worker };
36*0e209d39SAndroid Build Coastguard Worker 
37*0e209d39SAndroid Build Coastguard Worker // Exported as U_I18N_API because it is a public member field of exported ParsedSubpatternInfo
38*0e209d39SAndroid Build Coastguard Worker struct U_I18N_API Endpoints {
39*0e209d39SAndroid Build Coastguard Worker     int32_t start = 0;
40*0e209d39SAndroid Build Coastguard Worker     int32_t end = 0;
41*0e209d39SAndroid Build Coastguard Worker };
42*0e209d39SAndroid Build Coastguard Worker 
43*0e209d39SAndroid Build Coastguard Worker // Exported as U_I18N_API because it is a public member field of exported ParsedPatternInfo
44*0e209d39SAndroid Build Coastguard Worker struct U_I18N_API ParsedSubpatternInfo {
45*0e209d39SAndroid Build Coastguard Worker     uint64_t groupingSizes = 0x0000ffffffff0000L;
46*0e209d39SAndroid Build Coastguard Worker     int32_t integerLeadingHashSigns = 0;
47*0e209d39SAndroid Build Coastguard Worker     int32_t integerTrailingHashSigns = 0;
48*0e209d39SAndroid Build Coastguard Worker     int32_t integerNumerals = 0;
49*0e209d39SAndroid Build Coastguard Worker     int32_t integerAtSigns = 0;
50*0e209d39SAndroid Build Coastguard Worker     int32_t integerTotal = 0; // for convenience
51*0e209d39SAndroid Build Coastguard Worker     int32_t fractionNumerals = 0;
52*0e209d39SAndroid Build Coastguard Worker     int32_t fractionHashSigns = 0;
53*0e209d39SAndroid Build Coastguard Worker     int32_t fractionTotal = 0; // for convenience
54*0e209d39SAndroid Build Coastguard Worker     bool hasDecimal = false;
55*0e209d39SAndroid Build Coastguard Worker     int32_t widthExceptAffixes = 0;
56*0e209d39SAndroid Build Coastguard Worker     // Note: NullableValue causes issues here with std::move.
57*0e209d39SAndroid Build Coastguard Worker     bool hasPadding = false;
58*0e209d39SAndroid Build Coastguard Worker     UNumberFormatPadPosition paddingLocation = UNUM_PAD_BEFORE_PREFIX;
59*0e209d39SAndroid Build Coastguard Worker     DecimalQuantity rounding;
60*0e209d39SAndroid Build Coastguard Worker     bool exponentHasPlusSign = false;
61*0e209d39SAndroid Build Coastguard Worker     int32_t exponentZeros = 0;
62*0e209d39SAndroid Build Coastguard Worker     bool hasPercentSign = false;
63*0e209d39SAndroid Build Coastguard Worker     bool hasPerMilleSign = false;
64*0e209d39SAndroid Build Coastguard Worker     bool hasCurrencySign = false;
65*0e209d39SAndroid Build Coastguard Worker     bool hasCurrencyDecimal = false;
66*0e209d39SAndroid Build Coastguard Worker     bool hasMinusSign = false;
67*0e209d39SAndroid Build Coastguard Worker     bool hasPlusSign = false;
68*0e209d39SAndroid Build Coastguard Worker 
69*0e209d39SAndroid Build Coastguard Worker     Endpoints prefixEndpoints;
70*0e209d39SAndroid Build Coastguard Worker     Endpoints suffixEndpoints;
71*0e209d39SAndroid Build Coastguard Worker     Endpoints paddingEndpoints;
72*0e209d39SAndroid Build Coastguard Worker };
73*0e209d39SAndroid Build Coastguard Worker 
74*0e209d39SAndroid Build Coastguard Worker // Exported as U_I18N_API because it is needed for the unit test PatternStringTest
75*0e209d39SAndroid Build Coastguard Worker struct U_I18N_API ParsedPatternInfo : public AffixPatternProvider, public UMemory {
76*0e209d39SAndroid Build Coastguard Worker     UnicodeString pattern;
77*0e209d39SAndroid Build Coastguard Worker     ParsedSubpatternInfo positive;
78*0e209d39SAndroid Build Coastguard Worker     ParsedSubpatternInfo negative;
79*0e209d39SAndroid Build Coastguard Worker 
ParsedPatternInfoParsedPatternInfo80*0e209d39SAndroid Build Coastguard Worker     ParsedPatternInfo()
81*0e209d39SAndroid Build Coastguard Worker             : state(this->pattern), currentSubpattern(nullptr) {}
82*0e209d39SAndroid Build Coastguard Worker 
83*0e209d39SAndroid Build Coastguard Worker     ~ParsedPatternInfo() override = default;
84*0e209d39SAndroid Build Coastguard Worker 
85*0e209d39SAndroid Build Coastguard Worker     // Need to declare this explicitly because of the destructor
86*0e209d39SAndroid Build Coastguard Worker     ParsedPatternInfo& operator=(ParsedPatternInfo&& src) noexcept = default;
87*0e209d39SAndroid Build Coastguard Worker 
88*0e209d39SAndroid Build Coastguard Worker     static int32_t getLengthFromEndpoints(const Endpoints& endpoints);
89*0e209d39SAndroid Build Coastguard Worker 
90*0e209d39SAndroid Build Coastguard Worker     char16_t charAt(int32_t flags, int32_t index) const override;
91*0e209d39SAndroid Build Coastguard Worker 
92*0e209d39SAndroid Build Coastguard Worker     int32_t length(int32_t flags) const override;
93*0e209d39SAndroid Build Coastguard Worker 
94*0e209d39SAndroid Build Coastguard Worker     UnicodeString getString(int32_t flags) const override;
95*0e209d39SAndroid Build Coastguard Worker 
96*0e209d39SAndroid Build Coastguard Worker     bool positiveHasPlusSign() const override;
97*0e209d39SAndroid Build Coastguard Worker 
98*0e209d39SAndroid Build Coastguard Worker     bool hasNegativeSubpattern() const override;
99*0e209d39SAndroid Build Coastguard Worker 
100*0e209d39SAndroid Build Coastguard Worker     bool negativeHasMinusSign() const override;
101*0e209d39SAndroid Build Coastguard Worker 
102*0e209d39SAndroid Build Coastguard Worker     bool hasCurrencySign() const override;
103*0e209d39SAndroid Build Coastguard Worker 
104*0e209d39SAndroid Build Coastguard Worker     bool containsSymbolType(AffixPatternType type, UErrorCode& status) const override;
105*0e209d39SAndroid Build Coastguard Worker 
106*0e209d39SAndroid Build Coastguard Worker     bool hasBody() const override;
107*0e209d39SAndroid Build Coastguard Worker 
108*0e209d39SAndroid Build Coastguard Worker     bool currencyAsDecimal() const override;
109*0e209d39SAndroid Build Coastguard Worker 
110*0e209d39SAndroid Build Coastguard Worker   private:
111*0e209d39SAndroid Build Coastguard Worker     struct U_I18N_API ParserState {
112*0e209d39SAndroid Build Coastguard Worker         const UnicodeString& pattern; // reference to the parent
113*0e209d39SAndroid Build Coastguard Worker         int32_t offset = 0;
114*0e209d39SAndroid Build Coastguard Worker 
ParserStateParsedPatternInfo::ParserState115*0e209d39SAndroid Build Coastguard Worker         explicit ParserState(const UnicodeString& _pattern)
116*0e209d39SAndroid Build Coastguard Worker                 : pattern(_pattern) {}
117*0e209d39SAndroid Build Coastguard Worker 
118*0e209d39SAndroid Build Coastguard Worker         ParserState& operator=(ParserState&& src) noexcept {
119*0e209d39SAndroid Build Coastguard Worker             // Leave pattern reference alone; it will continue to point to the same place in memory,
120*0e209d39SAndroid Build Coastguard Worker             // which gets overwritten by ParsedPatternInfo's implicit move assignment.
121*0e209d39SAndroid Build Coastguard Worker             offset = src.offset;
122*0e209d39SAndroid Build Coastguard Worker             return *this;
123*0e209d39SAndroid Build Coastguard Worker         }
124*0e209d39SAndroid Build Coastguard Worker 
125*0e209d39SAndroid Build Coastguard Worker         /** Returns the next code point, or -1 if string is too short. */
126*0e209d39SAndroid Build Coastguard Worker         UChar32 peek();
127*0e209d39SAndroid Build Coastguard Worker 
128*0e209d39SAndroid Build Coastguard Worker         /** Returns the code point after the next code point, or -1 if string is too short. */
129*0e209d39SAndroid Build Coastguard Worker         UChar32 peek2();
130*0e209d39SAndroid Build Coastguard Worker 
131*0e209d39SAndroid Build Coastguard Worker         /** Returns the next code point and then steps forward. */
132*0e209d39SAndroid Build Coastguard Worker         UChar32 next();
133*0e209d39SAndroid Build Coastguard Worker 
134*0e209d39SAndroid Build Coastguard Worker         // TODO: We don't currently do anything with the message string.
135*0e209d39SAndroid Build Coastguard Worker         // This method is here as a shell for Java compatibility.
toParseExceptionParsedPatternInfo::ParserState136*0e209d39SAndroid Build Coastguard Worker         inline void toParseException(const char16_t* message) { (void) message; }
137*0e209d39SAndroid Build Coastguard Worker     } state;
138*0e209d39SAndroid Build Coastguard Worker 
139*0e209d39SAndroid Build Coastguard Worker     // NOTE: In Java, these are written as pure functions.
140*0e209d39SAndroid Build Coastguard Worker     // In C++, they're written as methods.
141*0e209d39SAndroid Build Coastguard Worker     // The behavior is the same.
142*0e209d39SAndroid Build Coastguard Worker 
143*0e209d39SAndroid Build Coastguard Worker     // Mutable transient pointer:
144*0e209d39SAndroid Build Coastguard Worker     ParsedSubpatternInfo* currentSubpattern;
145*0e209d39SAndroid Build Coastguard Worker 
146*0e209d39SAndroid Build Coastguard Worker     // In Java, "negative == null" tells us whether or not we had a negative subpattern.
147*0e209d39SAndroid Build Coastguard Worker     // In C++, we need to remember in another boolean.
148*0e209d39SAndroid Build Coastguard Worker     bool fHasNegativeSubpattern = false;
149*0e209d39SAndroid Build Coastguard Worker 
150*0e209d39SAndroid Build Coastguard Worker     const Endpoints& getEndpoints(int32_t flags) const;
151*0e209d39SAndroid Build Coastguard Worker 
152*0e209d39SAndroid Build Coastguard Worker     /** Run the recursive descent parser. */
153*0e209d39SAndroid Build Coastguard Worker     void consumePattern(const UnicodeString& patternString, UErrorCode& status);
154*0e209d39SAndroid Build Coastguard Worker 
155*0e209d39SAndroid Build Coastguard Worker     void consumeSubpattern(UErrorCode& status);
156*0e209d39SAndroid Build Coastguard Worker 
157*0e209d39SAndroid Build Coastguard Worker     void consumePadding(PadPosition paddingLocation, UErrorCode& status);
158*0e209d39SAndroid Build Coastguard Worker 
159*0e209d39SAndroid Build Coastguard Worker     void consumeAffix(Endpoints& endpoints, UErrorCode& status);
160*0e209d39SAndroid Build Coastguard Worker 
161*0e209d39SAndroid Build Coastguard Worker     void consumeLiteral(UErrorCode& status);
162*0e209d39SAndroid Build Coastguard Worker 
163*0e209d39SAndroid Build Coastguard Worker     void consumeFormat(UErrorCode& status);
164*0e209d39SAndroid Build Coastguard Worker 
165*0e209d39SAndroid Build Coastguard Worker     void consumeIntegerFormat(UErrorCode& status);
166*0e209d39SAndroid Build Coastguard Worker 
167*0e209d39SAndroid Build Coastguard Worker     void consumeFractionFormat(UErrorCode& status);
168*0e209d39SAndroid Build Coastguard Worker 
169*0e209d39SAndroid Build Coastguard Worker     void consumeExponent(UErrorCode& status);
170*0e209d39SAndroid Build Coastguard Worker 
171*0e209d39SAndroid Build Coastguard Worker     friend class PatternParser;
172*0e209d39SAndroid Build Coastguard Worker };
173*0e209d39SAndroid Build Coastguard Worker 
174*0e209d39SAndroid Build Coastguard Worker enum IgnoreRounding {
175*0e209d39SAndroid Build Coastguard Worker     IGNORE_ROUNDING_NEVER = 0, IGNORE_ROUNDING_IF_CURRENCY = 1, IGNORE_ROUNDING_ALWAYS = 2
176*0e209d39SAndroid Build Coastguard Worker };
177*0e209d39SAndroid Build Coastguard Worker 
178*0e209d39SAndroid Build Coastguard Worker class U_I18N_API PatternParser {
179*0e209d39SAndroid Build Coastguard Worker   public:
180*0e209d39SAndroid Build Coastguard Worker     /**
181*0e209d39SAndroid Build Coastguard Worker      * Runs the recursive descent parser on the given pattern string, returning a data structure with raw information
182*0e209d39SAndroid Build Coastguard Worker      * about the pattern string.
183*0e209d39SAndroid Build Coastguard Worker      *
184*0e209d39SAndroid Build Coastguard Worker      * <p>
185*0e209d39SAndroid Build Coastguard Worker      * To obtain a more useful form of the data, consider using {@link #parseToProperties} instead.
186*0e209d39SAndroid Build Coastguard Worker      *
187*0e209d39SAndroid Build Coastguard Worker      * TODO: Change argument type to const char16_t* instead of UnicodeString?
188*0e209d39SAndroid Build Coastguard Worker      *
189*0e209d39SAndroid Build Coastguard Worker      * @param patternString
190*0e209d39SAndroid Build Coastguard Worker      *            The LDML decimal format pattern (Excel-style pattern) to parse.
191*0e209d39SAndroid Build Coastguard Worker      * @return The results of the parse.
192*0e209d39SAndroid Build Coastguard Worker      */
193*0e209d39SAndroid Build Coastguard Worker     static void parseToPatternInfo(const UnicodeString& patternString, ParsedPatternInfo& patternInfo,
194*0e209d39SAndroid Build Coastguard Worker                                    UErrorCode& status);
195*0e209d39SAndroid Build Coastguard Worker 
196*0e209d39SAndroid Build Coastguard Worker     /**
197*0e209d39SAndroid Build Coastguard Worker      * Parses a pattern string into a new property bag.
198*0e209d39SAndroid Build Coastguard Worker      *
199*0e209d39SAndroid Build Coastguard Worker      * @param pattern
200*0e209d39SAndroid Build Coastguard Worker      *            The pattern string, like "#,##0.00"
201*0e209d39SAndroid Build Coastguard Worker      * @param ignoreRounding
202*0e209d39SAndroid Build Coastguard Worker      *            Whether to leave out rounding information (minFrac, maxFrac, and rounding increment) when parsing the
203*0e209d39SAndroid Build Coastguard Worker      *            pattern. This may be desirable if a custom rounding mode, such as CurrencyUsage, is to be used
204*0e209d39SAndroid Build Coastguard Worker      *            instead.
205*0e209d39SAndroid Build Coastguard Worker      * @return A property bag object.
206*0e209d39SAndroid Build Coastguard Worker      * @throws IllegalArgumentException
207*0e209d39SAndroid Build Coastguard Worker      *             If there is a syntax error in the pattern string.
208*0e209d39SAndroid Build Coastguard Worker      */
209*0e209d39SAndroid Build Coastguard Worker     static DecimalFormatProperties parseToProperties(const UnicodeString& pattern,
210*0e209d39SAndroid Build Coastguard Worker                                                      IgnoreRounding ignoreRounding, UErrorCode& status);
211*0e209d39SAndroid Build Coastguard Worker 
212*0e209d39SAndroid Build Coastguard Worker     static DecimalFormatProperties parseToProperties(const UnicodeString& pattern, UErrorCode& status);
213*0e209d39SAndroid Build Coastguard Worker 
214*0e209d39SAndroid Build Coastguard Worker     /**
215*0e209d39SAndroid Build Coastguard Worker      * Parses a pattern string into an existing property bag. All properties that can be encoded into a pattern string
216*0e209d39SAndroid Build Coastguard Worker      * will be overwritten with either their default value or with the value coming from the pattern string. Properties
217*0e209d39SAndroid Build Coastguard Worker      * that cannot be encoded into a pattern string, such as rounding mode, are not modified.
218*0e209d39SAndroid Build Coastguard Worker      *
219*0e209d39SAndroid Build Coastguard Worker      * @param pattern
220*0e209d39SAndroid Build Coastguard Worker      *            The pattern string, like "#,##0.00"
221*0e209d39SAndroid Build Coastguard Worker      * @param properties
222*0e209d39SAndroid Build Coastguard Worker      *            The property bag object to overwrite.
223*0e209d39SAndroid Build Coastguard Worker      * @param ignoreRounding
224*0e209d39SAndroid Build Coastguard Worker      *            See {@link #parseToProperties(String pattern, int ignoreRounding)}.
225*0e209d39SAndroid Build Coastguard Worker      * @throws IllegalArgumentException
226*0e209d39SAndroid Build Coastguard Worker      *             If there was a syntax error in the pattern string.
227*0e209d39SAndroid Build Coastguard Worker      */
228*0e209d39SAndroid Build Coastguard Worker     static void parseToExistingProperties(const UnicodeString& pattern,
229*0e209d39SAndroid Build Coastguard Worker                                           DecimalFormatProperties& properties,
230*0e209d39SAndroid Build Coastguard Worker                                           IgnoreRounding ignoreRounding, UErrorCode& status);
231*0e209d39SAndroid Build Coastguard Worker 
232*0e209d39SAndroid Build Coastguard Worker   private:
233*0e209d39SAndroid Build Coastguard Worker     static void parseToExistingPropertiesImpl(const UnicodeString& pattern,
234*0e209d39SAndroid Build Coastguard Worker                                               DecimalFormatProperties& properties,
235*0e209d39SAndroid Build Coastguard Worker                                               IgnoreRounding ignoreRounding, UErrorCode& status);
236*0e209d39SAndroid Build Coastguard Worker 
237*0e209d39SAndroid Build Coastguard Worker     /** Finalizes the temporary data stored in the ParsedPatternInfo to the Properties. */
238*0e209d39SAndroid Build Coastguard Worker     static void patternInfoToProperties(DecimalFormatProperties& properties,
239*0e209d39SAndroid Build Coastguard Worker                                         ParsedPatternInfo& patternInfo, IgnoreRounding _ignoreRounding,
240*0e209d39SAndroid Build Coastguard Worker                                         UErrorCode& status);
241*0e209d39SAndroid Build Coastguard Worker };
242*0e209d39SAndroid Build Coastguard Worker 
243*0e209d39SAndroid Build Coastguard Worker class U_I18N_API PatternStringUtils {
244*0e209d39SAndroid Build Coastguard Worker   public:
245*0e209d39SAndroid Build Coastguard Worker     /**
246*0e209d39SAndroid Build Coastguard Worker      * Determine whether a given roundingIncrement should be ignored for formatting
247*0e209d39SAndroid Build Coastguard Worker      * based on the current maxFrac value (maximum fraction digits). For example a
248*0e209d39SAndroid Build Coastguard Worker      * roundingIncrement of 0.01 should be ignored if maxFrac is 1, but not if maxFrac
249*0e209d39SAndroid Build Coastguard Worker      * is 2 or more. Note that roundingIncrements are rounded up in significance, so
250*0e209d39SAndroid Build Coastguard Worker      * a roundingIncrement of 0.006 is treated like 0.01 for this determination, i.e.
251*0e209d39SAndroid Build Coastguard Worker      * it should not be ignored if maxFrac is 2 or more (but a roundingIncrement of
252*0e209d39SAndroid Build Coastguard Worker      * 0.005 is treated like 0.001 for significance).
253*0e209d39SAndroid Build Coastguard Worker      *
254*0e209d39SAndroid Build Coastguard Worker      * This test is needed for both NumberPropertyMapper::oldToNew and
255*0e209d39SAndroid Build Coastguard Worker      * PatternStringUtils::propertiesToPatternString. In Java it cannot be
256*0e209d39SAndroid Build Coastguard Worker      * exported by NumberPropertyMapper (package private) so it is in
257*0e209d39SAndroid Build Coastguard Worker      * PatternStringUtils, do the same in C.
258*0e209d39SAndroid Build Coastguard Worker      *
259*0e209d39SAndroid Build Coastguard Worker      * @param roundIncr
260*0e209d39SAndroid Build Coastguard Worker      *            The roundingIncrement to be checked. Must be non-zero.
261*0e209d39SAndroid Build Coastguard Worker      * @param maxFrac
262*0e209d39SAndroid Build Coastguard Worker      *            The current maximum fraction digits value.
263*0e209d39SAndroid Build Coastguard Worker      * @return true if roundIncr should be ignored for formatting.
264*0e209d39SAndroid Build Coastguard Worker      */
265*0e209d39SAndroid Build Coastguard Worker      static bool ignoreRoundingIncrement(double roundIncr, int32_t maxFrac);
266*0e209d39SAndroid Build Coastguard Worker 
267*0e209d39SAndroid Build Coastguard Worker     /**
268*0e209d39SAndroid Build Coastguard Worker      * Creates a pattern string from a property bag.
269*0e209d39SAndroid Build Coastguard Worker      *
270*0e209d39SAndroid Build Coastguard Worker      * <p>
271*0e209d39SAndroid Build Coastguard Worker      * Since pattern strings support only a subset of the functionality available in a property bag, a new property bag
272*0e209d39SAndroid Build Coastguard Worker      * created from the string returned by this function may not be the same as the original property bag.
273*0e209d39SAndroid Build Coastguard Worker      *
274*0e209d39SAndroid Build Coastguard Worker      * @param properties
275*0e209d39SAndroid Build Coastguard Worker      *            The property bag to serialize.
276*0e209d39SAndroid Build Coastguard Worker      * @return A pattern string approximately serializing the property bag.
277*0e209d39SAndroid Build Coastguard Worker      */
278*0e209d39SAndroid Build Coastguard Worker     static UnicodeString propertiesToPatternString(const DecimalFormatProperties& properties,
279*0e209d39SAndroid Build Coastguard Worker                                                    UErrorCode& status);
280*0e209d39SAndroid Build Coastguard Worker 
281*0e209d39SAndroid Build Coastguard Worker 
282*0e209d39SAndroid Build Coastguard Worker     /**
283*0e209d39SAndroid Build Coastguard Worker      * Converts a pattern between standard notation and localized notation. Localized notation means that instead of
284*0e209d39SAndroid Build Coastguard Worker      * using generic placeholders in the pattern, you use the corresponding locale-specific characters instead. For
285*0e209d39SAndroid Build Coastguard Worker      * example, in locale <em>fr-FR</em>, the period in the pattern "0.000" means "decimal" in standard notation (as it
286*0e209d39SAndroid Build Coastguard Worker      * does in every other locale), but it means "grouping" in localized notation.
287*0e209d39SAndroid Build Coastguard Worker      *
288*0e209d39SAndroid Build Coastguard Worker      * <p>
289*0e209d39SAndroid Build Coastguard Worker      * A greedy string-substitution strategy is used to substitute locale symbols. If two symbols are ambiguous or have
290*0e209d39SAndroid Build Coastguard Worker      * the same prefix, the result is not well-defined.
291*0e209d39SAndroid Build Coastguard Worker      *
292*0e209d39SAndroid Build Coastguard Worker      * <p>
293*0e209d39SAndroid Build Coastguard Worker      * Locale symbols are not allowed to contain the ASCII quote character.
294*0e209d39SAndroid Build Coastguard Worker      *
295*0e209d39SAndroid Build Coastguard Worker      * <p>
296*0e209d39SAndroid Build Coastguard Worker      * This method is provided for backwards compatibility and should not be used in any new code.
297*0e209d39SAndroid Build Coastguard Worker      *
298*0e209d39SAndroid Build Coastguard Worker      * TODO(C++): This method is not yet implemented.
299*0e209d39SAndroid Build Coastguard Worker      *
300*0e209d39SAndroid Build Coastguard Worker      * @param input
301*0e209d39SAndroid Build Coastguard Worker      *            The pattern to convert.
302*0e209d39SAndroid Build Coastguard Worker      * @param symbols
303*0e209d39SAndroid Build Coastguard Worker      *            The symbols corresponding to the localized pattern.
304*0e209d39SAndroid Build Coastguard Worker      * @param toLocalized
305*0e209d39SAndroid Build Coastguard Worker      *            true to convert from standard to localized notation; false to convert from localized to standard
306*0e209d39SAndroid Build Coastguard Worker      *            notation.
307*0e209d39SAndroid Build Coastguard Worker      * @return The pattern expressed in the other notation.
308*0e209d39SAndroid Build Coastguard Worker      */
309*0e209d39SAndroid Build Coastguard Worker     static UnicodeString convertLocalized(const UnicodeString& input, const DecimalFormatSymbols& symbols,
310*0e209d39SAndroid Build Coastguard Worker                                           bool toLocalized, UErrorCode& status);
311*0e209d39SAndroid Build Coastguard Worker 
312*0e209d39SAndroid Build Coastguard Worker     /**
313*0e209d39SAndroid Build Coastguard Worker      * This method contains the heart of the logic for rendering LDML affix strings. It handles
314*0e209d39SAndroid Build Coastguard Worker      * sign-always-shown resolution, whether to use the positive or negative subpattern, permille
315*0e209d39SAndroid Build Coastguard Worker      * substitution, and plural forms for CurrencyPluralInfo.
316*0e209d39SAndroid Build Coastguard Worker      */
317*0e209d39SAndroid Build Coastguard Worker     static void patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix,
318*0e209d39SAndroid Build Coastguard Worker                                            PatternSignType patternSignType,
319*0e209d39SAndroid Build Coastguard Worker                                            bool approximately,
320*0e209d39SAndroid Build Coastguard Worker                                            StandardPlural::Form plural,
321*0e209d39SAndroid Build Coastguard Worker                                            bool perMilleReplacesPercent,
322*0e209d39SAndroid Build Coastguard Worker                                            bool dropCurrencySymbols,
323*0e209d39SAndroid Build Coastguard Worker                                            UnicodeString& output);
324*0e209d39SAndroid Build Coastguard Worker 
325*0e209d39SAndroid Build Coastguard Worker     static PatternSignType resolveSignDisplay(UNumberSignDisplay signDisplay, Signum signum);
326*0e209d39SAndroid Build Coastguard Worker 
327*0e209d39SAndroid Build Coastguard Worker   private:
328*0e209d39SAndroid Build Coastguard Worker     /** @return The number of chars inserted. */
329*0e209d39SAndroid Build Coastguard Worker     static int escapePaddingString(UnicodeString input, UnicodeString& output, int startIndex,
330*0e209d39SAndroid Build Coastguard Worker                                    UErrorCode& status);
331*0e209d39SAndroid Build Coastguard Worker };
332*0e209d39SAndroid Build Coastguard Worker 
333*0e209d39SAndroid Build Coastguard Worker } // namespace number::impl
334*0e209d39SAndroid Build Coastguard Worker U_NAMESPACE_END
335*0e209d39SAndroid Build Coastguard Worker 
336*0e209d39SAndroid Build Coastguard Worker 
337*0e209d39SAndroid Build Coastguard Worker #endif //__NUMBER_PATTERNSTRING_H__
338*0e209d39SAndroid Build Coastguard Worker 
339*0e209d39SAndroid Build Coastguard Worker #endif /* #if !UCONFIG_NO_FORMATTING */
340