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