1 /*
2 *******************************************************************************
3 * Copyright (C) 2015, International Business Machines
4 * Corporation and others.  All Rights Reserved.
5 *******************************************************************************
6 * digitformatter.h
7 *
8 * created on: 2015jan06
9 * created by: Travis Keep
10 */
11 
12 #ifndef __DIGITFORMATTER_H__
13 #define __DIGITFORMATTER_H__
14 
15 #include "unicode/uobject.h"
16 
17 #if !UCONFIG_NO_FORMATTING
18 
19 #include "unicode/utypes.h"
20 #include "unicode/unistr.h"
21 #include "digitaffix.h"
22 
23 U_NAMESPACE_BEGIN
24 
25 class DecimalFormatSymbols;
26 class DigitList;
27 class DigitGrouping;
28 class DigitInterval;
29 class UnicodeString;
30 class FieldPositionHandler;
31 class IntDigitCountRange;
32 class VisibleDigits;
33 class VisibleDigitsWithExponent;
34 
35 /**
36  * Various options for formatting in fixed point.
37  */
38 class U_I18N_API DigitFormatterOptions : public UMemory {
39     public:
DigitFormatterOptions()40     DigitFormatterOptions() : fAlwaysShowDecimal(FALSE) { }
41 
42     /**
43      * Returns TRUE if this object equals rhs.
44      */
equals(const DigitFormatterOptions & rhs)45     UBool equals(const DigitFormatterOptions &rhs) const {
46         return (
47             fAlwaysShowDecimal == rhs.fAlwaysShowDecimal);
48     }
49 
50     /**
51      * Returns TRUE if these options allow for fast formatting of
52      * integers.
53      */
isFastFormattable()54     UBool isFastFormattable() const {
55         return (fAlwaysShowDecimal == FALSE);
56     }
57 
58     /**
59      * If TRUE, show the decimal separator even when there are no fraction
60      * digits. default is FALSE.
61      */
62     UBool fAlwaysShowDecimal;
63 };
64 
65 /**
66  * Various options for formatting an integer.
67  */
68 class U_I18N_API DigitFormatterIntOptions : public UMemory {
69     public:
DigitFormatterIntOptions()70     DigitFormatterIntOptions() : fAlwaysShowSign(FALSE) { }
71 
72     /**
73      * Returns TRUE if this object equals rhs.
74      */
equals(const DigitFormatterIntOptions & rhs)75     UBool equals(const DigitFormatterIntOptions &rhs) const {
76         return (fAlwaysShowSign == rhs.fAlwaysShowSign);
77     }
78 
79     /**
80      * If TRUE, always prefix the integer with its sign even if the number is
81      * positive. Default is FALSE.
82      */
83     UBool fAlwaysShowSign;
84 };
85 
86 /**
87  * Options for formatting in scientific notation.
88  */
89 class U_I18N_API SciFormatterOptions : public UMemory {
90     public:
91 
92     /**
93      * Returns TRUE if this object equals rhs.
94      */
equals(const SciFormatterOptions & rhs)95     UBool equals(const SciFormatterOptions &rhs) const {
96         return (fMantissa.equals(rhs.fMantissa) &&
97                 fExponent.equals(rhs.fExponent));
98     }
99 
100     /**
101      * Options for formatting the mantissa.
102      */
103     DigitFormatterOptions fMantissa;
104 
105     /**
106      * Options for formatting the exponent.
107      */
108     DigitFormatterIntOptions fExponent;
109 };
110 
111 
112 /**
113  * Does fixed point formatting.
114  *
115  * This class only does fixed point formatting. It does no rounding before
116  * formatting.
117  */
118 class U_I18N_API DigitFormatter : public UMemory {
119 public:
120 
121 /**
122  * Decimal separator is period (.), Plus sign is plus (+),
123  * minus sign is minus (-), grouping separator is comma (,), digits are 0-9.
124  */
125 DigitFormatter();
126 
127 /**
128  * Let symbols determine the digits, decimal separator,
129  * plus and mius sign, grouping separator, and possibly other settings.
130  */
131 DigitFormatter(const DecimalFormatSymbols &symbols);
132 
133 /**
134  * Change what this instance uses for digits, decimal separator,
135  * plus and mius sign, grouping separator, and possibly other settings
136  * according to symbols.
137  */
138 void setDecimalFormatSymbols(const DecimalFormatSymbols &symbols);
139 
140 /**
141  * Change what this instance uses for digits, decimal separator,
142  * plus and mius sign, grouping separator, and possibly other settings
143  * according to symbols in the context of monetary amounts.
144  */
145 void setDecimalFormatSymbolsForMonetary(const DecimalFormatSymbols &symbols);
146 
147 /**
148  * Fixed point formatting.
149  *
150  * @param positiveDigits the value to format
151  *  Negative sign can be present, but it won't show.
152  * @param grouping controls how digit grouping is done
153  * @param options formatting options
154  * @param handler records field positions
155  * @param appendTo formatted value appended here.
156  * @return appendTo
157  */
158 UnicodeString &format(
159         const VisibleDigits &positiveDigits,
160         const DigitGrouping &grouping,
161         const DigitFormatterOptions &options,
162         FieldPositionHandler &handler,
163         UnicodeString &appendTo) const;
164 
165 /**
166  * formats in scientifc notation.
167  * @param positiveDigits the value to format.
168  *  Negative sign can be present, but it won't show.
169  * @param options formatting options
170  * @param handler records field positions.
171  * @param appendTo formatted value appended here.
172  */
173 UnicodeString &format(
174         const VisibleDigitsWithExponent &positiveDigits,
175         const SciFormatterOptions &options,
176         FieldPositionHandler &handler,
177         UnicodeString &appendTo) const;
178 
179 /**
180  * Fixed point formatting of integers.
181  * Always performed with no grouping and no decimal point.
182  *
183  * @param positiveValue the value to format must be positive.
184  * @param range specifies minimum and maximum number of digits.
185  * @param handler records field positions
186  * @param appendTo formatted value appended here.
187  * @return appendTo
188  */
189 UnicodeString &formatPositiveInt32(
190         int32_t positiveValue,
191         const IntDigitCountRange &range,
192         FieldPositionHandler &handler,
193         UnicodeString &appendTo) const;
194 
195 /**
196  * Counts how many code points are needed for fixed formatting.
197  *   If digits is negative, the negative sign is not included in the count.
198  */
199 int32_t countChar32(
200         const VisibleDigits &digits,
201         const DigitGrouping &grouping,
202         const DigitFormatterOptions &options) const;
203 
204 /**
205  * Counts how many code points are needed for scientific formatting.
206  *   If digits is negative, the negative sign is not included in the count.
207  */
208 int32_t countChar32(
209         const VisibleDigitsWithExponent &digits,
210         const SciFormatterOptions &options) const;
211 
212 /**
213  * Returns TRUE if this object equals rhs.
214  */
215 UBool equals(const DigitFormatter &rhs) const;
216 
217 private:
218 UChar32 fLocalizedDigits[10];
219 UnicodeString fGroupingSeparator;
220 UnicodeString fDecimal;
221 UnicodeString fNegativeSign;
222 UnicodeString fPositiveSign;
223 DigitAffix fInfinity;
224 DigitAffix fNan;
225 UBool fIsStandardDigits;
226 UnicodeString fExponent;
227 UBool isStandardDigits() const;
228 
229 UnicodeString &formatDigits(
230         const uint8_t *digits,
231         int32_t count,
232         const IntDigitCountRange &range,
233         int32_t intField,
234         FieldPositionHandler &handler,
235         UnicodeString &appendTo) const;
236 
237 void setOtherDecimalFormatSymbols(const DecimalFormatSymbols &symbols);
238 
239 int32_t countChar32(
240         const VisibleDigits &exponent,
241         const DigitInterval &mantissaInterval,
242         const SciFormatterOptions &options) const;
243 
formatNaN(FieldPositionHandler & handler,UnicodeString & appendTo)244 UnicodeString &formatNaN(
245         FieldPositionHandler &handler,
246         UnicodeString &appendTo) const {
247     return fNan.format(handler, appendTo);
248 }
249 
countChar32ForNaN()250 int32_t countChar32ForNaN() const {
251     return fNan.toString().countChar32();
252 }
253 
formatInfinity(FieldPositionHandler & handler,UnicodeString & appendTo)254 UnicodeString &formatInfinity(
255         FieldPositionHandler &handler,
256         UnicodeString &appendTo) const {
257     return fInfinity.format(handler, appendTo);
258 }
259 
countChar32ForInfinity()260 int32_t countChar32ForInfinity() const {
261     return fInfinity.toString().countChar32();
262 }
263 
264 UnicodeString &formatExponent(
265         const VisibleDigits &digits,
266         const DigitFormatterIntOptions &options,
267         int32_t signField,
268         int32_t intField,
269         FieldPositionHandler &handler,
270         UnicodeString &appendTo) const;
271 
272 int32_t countChar32(
273         const DigitGrouping &grouping,
274         const DigitInterval &interval,
275         const DigitFormatterOptions &options) const;
276 
277 int32_t countChar32ForExponent(
278         const VisibleDigits &exponent,
279         const DigitFormatterIntOptions &options) const;
280 
281 };
282 
283 
284 U_NAMESPACE_END
285 #endif /* #if !UCONFIG_NO_FORMATTING */
286 #endif  // __DIGITFORMATTER_H__
287