Imported Upstream version 58.1
[platform/upstream/icu.git] / source / i18n / valueformatter.cpp
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
29 ValueFormatter::~ValueFormatter() {}
30
31 VisibleDigitsWithExponent &
32 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 &
53 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
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
84 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 &
106 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 &
123 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 &
149 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
177 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
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
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 */