• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2017 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_FORMATIMPL_H__
8 #define __NUMBER_FORMATIMPL_H__
9 
10 #include "number_types.h"
11 #include "number_stringbuilder.h"
12 #include "number_patternstring.h"
13 #include "number_utils.h"
14 #include "number_patternmodifier.h"
15 #include "number_longnames.h"
16 #include "number_compact.h"
17 #include "number_microprops.h"
18 
19 U_NAMESPACE_BEGIN namespace number {
20 namespace impl {
21 
22 /**
23  * This is the "brain" of the number formatting pipeline. It ties all the pieces together, taking in a MacroProps and a
24  * DecimalQuantity and outputting a properly formatted number string.
25  */
26 class NumberFormatterImpl : public UMemory {
27   public:
28     /**
29      * Builds a "safe" MicroPropsGenerator, which is thread-safe and can be used repeatedly.
30      * The caller owns the returned NumberFormatterImpl.
31      */
32     NumberFormatterImpl(const MacroProps &macros, UErrorCode &status);
33 
34     /**
35      * Builds and evaluates an "unsafe" MicroPropsGenerator, which is cheaper but can be used only once.
36      */
37     static int32_t
38     formatStatic(const MacroProps &macros, DecimalQuantity &inValue, NumberStringBuilder &outString,
39                  UErrorCode &status);
40 
41     /**
42      * Prints only the prefix and suffix; used for DecimalFormat getters.
43      *
44      * @return The index into the output at which the prefix ends and the suffix starts; in other words,
45      *         the prefix length.
46      */
47     static int32_t getPrefixSuffixStatic(const MacroProps& macros, int8_t signum,
48                                          StandardPlural::Form plural, NumberStringBuilder& outString,
49                                          UErrorCode& status);
50 
51     /**
52      * Evaluates the "safe" MicroPropsGenerator created by "fromMacros".
53      */
54     int32_t format(DecimalQuantity& inValue, NumberStringBuilder& outString, UErrorCode& status) const;
55 
56     /**
57      * Like format(), but saves the result into an output MicroProps without additional processing.
58      */
59     void preProcess(DecimalQuantity& inValue, MicroProps& microsOut, UErrorCode& status) const;
60 
61     /**
62      * Like getPrefixSuffixStatic() but uses the safe compiled object.
63      */
64     int32_t getPrefixSuffix(int8_t signum, StandardPlural::Form plural, NumberStringBuilder& outString,
65                             UErrorCode& status) const;
66 
67     /**
68      * Synthesizes the output string from a MicroProps and DecimalQuantity.
69      * This method formats only the main number, not affixes.
70      */
71     static int32_t writeNumber(const MicroProps& micros, DecimalQuantity& quantity,
72                                NumberStringBuilder& string, int32_t index, UErrorCode& status);
73 
74     /**
75      * Adds the affixes.  Intended to be called immediately after formatNumber.
76      */
77     static int32_t writeAffixes(const MicroProps& micros, NumberStringBuilder& string, int32_t start,
78                                 int32_t end, UErrorCode& status);
79 
80   private:
81     // Head of the MicroPropsGenerator linked list:
82     const MicroPropsGenerator *fMicroPropsGenerator = nullptr;
83 
84     // Tail of the list:
85     MicroProps fMicros;
86 
87     // Other fields possibly used by the number formatting pipeline:
88     // TODO: Convert more of these LocalPointers to value objects to reduce the number of news?
89     LocalPointer<const DecimalFormatSymbols> fSymbols;
90     LocalPointer<const PluralRules> fRules;
91     LocalPointer<const ParsedPatternInfo> fPatternInfo;
92     LocalPointer<const ScientificHandler> fScientificHandler;
93     LocalPointer<MutablePatternModifier> fPatternModifier;
94     LocalPointer<const ImmutablePatternModifier> fImmutablePatternModifier;
95     LocalPointer<const LongNameHandler> fLongNameHandler;
96     LocalPointer<const CompactHandler> fCompactHandler;
97 
98     // Value objects possibly used by the number formatting pipeline:
99     struct Warehouse {
100         CurrencySymbols fCurrencySymbols;
101     } fWarehouse;
102 
103 
104     NumberFormatterImpl(const MacroProps &macros, bool safe, UErrorCode &status);
105 
106     MicroProps& preProcessUnsafe(DecimalQuantity &inValue, UErrorCode &status);
107 
108     int32_t getPrefixSuffixUnsafe(int8_t signum, StandardPlural::Form plural,
109                                   NumberStringBuilder& outString, UErrorCode& status);
110 
111     /**
112      * If rulesPtr is non-null, return it.  Otherwise, return a PluralRules owned by this object for the
113      * specified locale, creating it if necessary.
114      */
115     const PluralRules *
116     resolvePluralRules(const PluralRules *rulesPtr, const Locale &locale, UErrorCode &status);
117 
118     /**
119      * Synthesizes the MacroProps into a MicroPropsGenerator. All information, including the locale, is encoded into the
120      * MicroPropsGenerator, except for the quantity itself, which is left abstract and must be provided to the returned
121      * MicroPropsGenerator instance.
122      *
123      * @see MicroPropsGenerator
124      * @param macros
125      *            The {@link MacroProps} to consume. This method does not mutate the MacroProps instance.
126      * @param safe
127      *            If true, the returned MicroPropsGenerator will be thread-safe. If false, the returned value will
128      *            <em>not</em> be thread-safe, intended for a single "one-shot" use only. Building the thread-safe
129      *            object is more expensive.
130      */
131     const MicroPropsGenerator *
132     macrosToMicroGenerator(const MacroProps &macros, bool safe, UErrorCode &status);
133 
134     static int32_t
135     writeIntegerDigits(const MicroProps &micros, DecimalQuantity &quantity, NumberStringBuilder &string,
136                        int32_t index, UErrorCode &status);
137 
138     static int32_t
139     writeFractionDigits(const MicroProps &micros, DecimalQuantity &quantity, NumberStringBuilder &string,
140                         int32_t index, UErrorCode &status);
141 };
142 
143 }  // namespace impl
144 }  // namespace number
145 U_NAMESPACE_END
146 
147 
148 #endif //__NUMBER_FORMATIMPL_H__
149 
150 #endif /* #if !UCONFIG_NO_FORMATTING */
151