1 /*
2 *******************************************************************************
3 * Copyright (C) 2015, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 *******************************************************************************
6 */
7 
8 #include "unicode/plurrule.h"
9 #include "unicode/unistr.h"
10 #include "unicode/utypes.h"
11 
12 #if !UCONFIG_NO_FORMATTING
13 
14 #include "digitformatter.h"
15 #include "digitgrouping.h"
16 #include "digitinterval.h"
17 #include "digitlst.h"
18 #include "precision.h"
19 #include "plurrule_impl.h"
20 #include "smallintformatter.h"
21 #include "uassert.h"
22 #include "valueformatter.h"
23 #include "visibledigits.h"
24 
25 U_NAMESPACE_BEGIN
26 
~ValueFormatter()27 ValueFormatter::~ValueFormatter() {}
28 
29 VisibleDigitsWithExponent &
toVisibleDigitsWithExponent(int64_t value,VisibleDigitsWithExponent & digits,UErrorCode & status) const30 ValueFormatter::toVisibleDigitsWithExponent(
31         int64_t value,
32         VisibleDigitsWithExponent &digits,
33         UErrorCode &status) const {
34     switch (fType) {
35     case kFixedDecimal:
36         return fFixedPrecision->initVisibleDigitsWithExponent(
37                 value, digits, status);
38         break;
39     case kScientificNotation:
40         return fScientificPrecision->initVisibleDigitsWithExponent(
41                 value, digits, status);
42         break;
43     default:
44         U_ASSERT(FALSE);
45         break;
46     }
47     return digits;
48 }
49 
50 VisibleDigitsWithExponent &
toVisibleDigitsWithExponent(DigitList & value,VisibleDigitsWithExponent & digits,UErrorCode & status) const51 ValueFormatter::toVisibleDigitsWithExponent(
52         DigitList &value,
53         VisibleDigitsWithExponent &digits,
54         UErrorCode &status) const {
55     switch (fType) {
56     case kFixedDecimal:
57         return fFixedPrecision->initVisibleDigitsWithExponent(
58                 value, digits, status);
59         break;
60     case kScientificNotation:
61         return fScientificPrecision->initVisibleDigitsWithExponent(
62                 value, digits, status);
63         break;
64     default:
65         U_ASSERT(FALSE);
66         break;
67     }
68     return digits;
69 }
70 
isNoGrouping(const DigitGrouping & grouping,int32_t value,const FixedPrecision & precision)71 static UBool isNoGrouping(
72         const DigitGrouping &grouping,
73         int32_t value,
74         const FixedPrecision &precision) {
75     IntDigitCountRange range(
76             precision.fMin.getIntDigitCount(),
77             precision.fMax.getIntDigitCount());
78     return grouping.isNoGrouping(value, range);
79 }
80 
81 UBool
isFastFormattable(int32_t value) const82 ValueFormatter::isFastFormattable(int32_t value) const {
83     switch (fType) {
84     case kFixedDecimal:
85         {
86             if (value == INT32_MIN) {
87                 return FALSE;
88             }
89             if (value < 0) {
90                 value = -value;
91             }
92             return fFixedPrecision->isFastFormattable() && fFixedOptions->isFastFormattable() && isNoGrouping(*fGrouping, value, *fFixedPrecision);
93         }
94     case kScientificNotation:
95         return FALSE;
96     default:
97         U_ASSERT(FALSE);
98         break;
99     }
100     return FALSE;
101 }
102 
103 DigitList &
round(DigitList & value,UErrorCode & status) const104 ValueFormatter::round(DigitList &value, UErrorCode &status) const {
105     if (value.isNaN() || value.isInfinite()) {
106         return value;
107     }
108     switch (fType) {
109     case kFixedDecimal:
110         return fFixedPrecision->round(value, 0, status);
111     case kScientificNotation:
112         return fScientificPrecision->round(value, status);
113     default:
114         U_ASSERT(FALSE);
115         break;
116     }
117     return value;
118 }
119 
120 UnicodeString &
formatInt32(int32_t value,FieldPositionHandler & handler,UnicodeString & appendTo) const121 ValueFormatter::formatInt32(
122         int32_t value,
123         FieldPositionHandler &handler,
124         UnicodeString &appendTo) const {
125     switch (fType) {
126     case kFixedDecimal:
127         {
128             IntDigitCountRange range(
129                     fFixedPrecision->fMin.getIntDigitCount(),
130                     fFixedPrecision->fMax.getIntDigitCount());
131             return fDigitFormatter->formatPositiveInt32(
132                     value,
133                     range,
134                     handler,
135                     appendTo);
136         }
137         break;
138     case kScientificNotation:
139     default:
140         U_ASSERT(FALSE);
141         break;
142     }
143     return appendTo;
144 }
145 
146 UnicodeString &
format(const VisibleDigitsWithExponent & value,FieldPositionHandler & handler,UnicodeString & appendTo) const147 ValueFormatter::format(
148         const VisibleDigitsWithExponent &value,
149         FieldPositionHandler &handler,
150         UnicodeString &appendTo) const {
151     switch (fType) {
152     case kFixedDecimal:
153         return fDigitFormatter->format(
154                 value.getMantissa(),
155                 *fGrouping,
156                 *fFixedOptions,
157                 handler,
158                 appendTo);
159         break;
160     case kScientificNotation:
161         return fDigitFormatter->format(
162                 value,
163                 *fScientificOptions,
164                 handler,
165                 appendTo);
166         break;
167     default:
168         U_ASSERT(FALSE);
169         break;
170     }
171     return appendTo;
172 }
173 
174 int32_t
countChar32(const VisibleDigitsWithExponent & value) const175 ValueFormatter::countChar32(const VisibleDigitsWithExponent &value) const {
176     switch (fType) {
177     case kFixedDecimal:
178         return fDigitFormatter->countChar32(
179                 value.getMantissa(),
180                 *fGrouping,
181                 *fFixedOptions);
182         break;
183     case kScientificNotation:
184         return fDigitFormatter->countChar32(
185                 value,
186                 *fScientificOptions);
187         break;
188     default:
189         U_ASSERT(FALSE);
190         break;
191     }
192     return 0;
193 }
194 
195 void
prepareFixedDecimalFormatting(const DigitFormatter & formatter,const DigitGrouping & grouping,const FixedPrecision & precision,const DigitFormatterOptions & options)196 ValueFormatter::prepareFixedDecimalFormatting(
197         const DigitFormatter &formatter,
198         const DigitGrouping &grouping,
199         const FixedPrecision &precision,
200         const DigitFormatterOptions &options) {
201     fType = kFixedDecimal;
202     fDigitFormatter = &formatter;
203     fGrouping = &grouping;
204     fFixedPrecision = &precision;
205     fFixedOptions = &options;
206 }
207 
208 void
prepareScientificFormatting(const DigitFormatter & formatter,const ScientificPrecision & precision,const SciFormatterOptions & options)209 ValueFormatter::prepareScientificFormatting(
210         const DigitFormatter &formatter,
211         const ScientificPrecision &precision,
212         const SciFormatterOptions &options) {
213     fType = kScientificNotation;
214     fDigitFormatter = &formatter;
215     fScientificPrecision = &precision;
216     fScientificOptions = &options;
217 }
218 
219 U_NAMESPACE_END
220 
221 #endif /* !UCONFIG_NO_FORMATTING */
222