• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015, International Business Machines
3  * Corporation and others.  All Rights Reserved.
4  *
5  * file name: decimfmtimpl.cpp
6  */
7 
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 #include <math.h>
13 #include "unicode/numfmt.h"
14 #include "unicode/plurrule.h"
15 #include "unicode/ustring.h"
16 #include "decimalformatpattern.h"
17 #include "decimalformatpatternimpl.h"
18 #include "decimfmtimpl.h"
19 #include "fphdlimp.h"
20 #include "plurrule_impl.h"
21 #include "valueformatter.h"
22 #include "visibledigits.h"
23 
24 U_NAMESPACE_BEGIN
25 
26 static const int32_t kMaxScientificIntegerDigits = 8;
27 
28 static const int32_t kFormattingPosPrefix = (1 << 0);
29 static const int32_t kFormattingNegPrefix = (1 << 1);
30 static const int32_t kFormattingPosSuffix = (1 << 2);
31 static const int32_t kFormattingNegSuffix = (1 << 3);
32 static const int32_t kFormattingSymbols = (1 << 4);
33 static const int32_t kFormattingCurrency = (1 << 5);
34 static const int32_t kFormattingUsesCurrency = (1 << 6);
35 static const int32_t kFormattingPluralRules = (1 << 7);
36 static const int32_t kFormattingAffixParser = (1 << 8);
37 static const int32_t kFormattingCurrencyAffixInfo = (1 << 9);
38 static const int32_t kFormattingAll = (1 << 10) - 1;
39 static const int32_t kFormattingAffixes =
40         kFormattingPosPrefix | kFormattingPosSuffix |
41         kFormattingNegPrefix | kFormattingNegSuffix;
42 static const int32_t kFormattingAffixParserWithCurrency =
43         kFormattingAffixParser | kFormattingCurrencyAffixInfo;
44 
DecimalFormatImpl(NumberFormat * super,const Locale & locale,const UnicodeString & pattern,UErrorCode & status)45 DecimalFormatImpl::DecimalFormatImpl(
46         NumberFormat *super,
47         const Locale &locale,
48         const UnicodeString &pattern,
49         UErrorCode &status)
50         : fSuper(super),
51           fScale(0),
52           fRoundingMode(DecimalFormat::kRoundHalfEven),
53           fSymbols(NULL),
54           fCurrencyUsage(UCURR_USAGE_STANDARD),
55           fRules(NULL),
56           fMonetary(FALSE) {
57     if (U_FAILURE(status)) {
58         return;
59     }
60     fSymbols = new DecimalFormatSymbols(
61             locale, status);
62     if (fSymbols == NULL) {
63         status = U_MEMORY_ALLOCATION_ERROR;
64         return;
65     }
66     UParseError parseError;
67     applyPattern(pattern, FALSE, parseError, status);
68     updateAll(status);
69 }
70 
DecimalFormatImpl(NumberFormat * super,const UnicodeString & pattern,DecimalFormatSymbols * symbolsToAdopt,UParseError & parseError,UErrorCode & status)71 DecimalFormatImpl::DecimalFormatImpl(
72         NumberFormat *super,
73         const UnicodeString &pattern,
74         DecimalFormatSymbols *symbolsToAdopt,
75         UParseError &parseError,
76         UErrorCode &status)
77         : fSuper(super),
78           fScale(0),
79           fRoundingMode(DecimalFormat::kRoundHalfEven),
80           fSymbols(symbolsToAdopt),
81           fCurrencyUsage(UCURR_USAGE_STANDARD),
82           fRules(NULL),
83           fMonetary(FALSE) {
84     applyPattern(pattern, FALSE, parseError, status);
85     updateAll(status);
86 }
87 
DecimalFormatImpl(NumberFormat * super,const DecimalFormatImpl & other,UErrorCode & status)88 DecimalFormatImpl::DecimalFormatImpl(
89     NumberFormat *super, const DecimalFormatImpl &other, UErrorCode &status) :
90           fSuper(super),
91           fMultiplier(other.fMultiplier),
92           fScale(other.fScale),
93           fRoundingMode(other.fRoundingMode),
94           fMinSigDigits(other.fMinSigDigits),
95           fMaxSigDigits(other.fMaxSigDigits),
96           fUseScientific(other.fUseScientific),
97           fUseSigDigits(other.fUseSigDigits),
98           fGrouping(other.fGrouping),
99           fPositivePrefixPattern(other.fPositivePrefixPattern),
100           fNegativePrefixPattern(other.fNegativePrefixPattern),
101           fPositiveSuffixPattern(other.fPositiveSuffixPattern),
102           fNegativeSuffixPattern(other.fNegativeSuffixPattern),
103           fSymbols(other.fSymbols),
104           fCurrencyUsage(other.fCurrencyUsage),
105           fRules(NULL),
106           fMonetary(other.fMonetary),
107           fAffixParser(other.fAffixParser),
108           fCurrencyAffixInfo(other.fCurrencyAffixInfo),
109           fEffPrecision(other.fEffPrecision),
110           fEffGrouping(other.fEffGrouping),
111           fOptions(other.fOptions),
112           fFormatter(other.fFormatter),
113           fAffixes(other.fAffixes) {
114     fSymbols = new DecimalFormatSymbols(*fSymbols);
115     if (fSymbols == NULL && U_SUCCESS(status)) {
116         status = U_MEMORY_ALLOCATION_ERROR;
117     }
118     if (other.fRules != NULL) {
119         fRules = new PluralRules(*other.fRules);
120         if (fRules == NULL && U_SUCCESS(status)) {
121             status = U_MEMORY_ALLOCATION_ERROR;
122         }
123     }
124 }
125 
126 
127 DecimalFormatImpl &
assign(const DecimalFormatImpl & other,UErrorCode & status)128 DecimalFormatImpl::assign(const DecimalFormatImpl &other, UErrorCode &status) {
129     if (U_FAILURE(status) || this == &other) {
130         return (*this);
131     }
132     UObject::operator=(other);
133     fMultiplier = other.fMultiplier;
134     fScale = other.fScale;
135     fRoundingMode = other.fRoundingMode;
136     fMinSigDigits = other.fMinSigDigits;
137     fMaxSigDigits = other.fMaxSigDigits;
138     fUseScientific = other.fUseScientific;
139     fUseSigDigits = other.fUseSigDigits;
140     fGrouping = other.fGrouping;
141     fPositivePrefixPattern = other.fPositivePrefixPattern;
142     fNegativePrefixPattern = other.fNegativePrefixPattern;
143     fPositiveSuffixPattern = other.fPositiveSuffixPattern;
144     fNegativeSuffixPattern = other.fNegativeSuffixPattern;
145     fCurrencyUsage = other.fCurrencyUsage;
146     fMonetary = other.fMonetary;
147     fAffixParser = other.fAffixParser;
148     fCurrencyAffixInfo = other.fCurrencyAffixInfo;
149     fEffPrecision = other.fEffPrecision;
150     fEffGrouping = other.fEffGrouping;
151     fOptions = other.fOptions;
152     fFormatter = other.fFormatter;
153     fAffixes = other.fAffixes;
154     *fSymbols = *other.fSymbols;
155     if (fRules != NULL && other.fRules != NULL) {
156         *fRules = *other.fRules;
157     } else {
158         delete fRules;
159         fRules = other.fRules;
160         if (fRules != NULL) {
161             fRules = new PluralRules(*fRules);
162             if (fRules == NULL) {
163                 status = U_MEMORY_ALLOCATION_ERROR;
164                 return *this;
165             }
166         }
167     }
168     return *this;
169 }
170 
171 UBool
operator ==(const DecimalFormatImpl & other) const172 DecimalFormatImpl::operator==(const DecimalFormatImpl &other) const {
173     if (this == &other) {
174         return TRUE;
175     }
176     return (fMultiplier == other.fMultiplier)
177             && (fScale == other.fScale)
178             && (fRoundingMode == other.fRoundingMode)
179             && (fMinSigDigits == other.fMinSigDigits)
180             && (fMaxSigDigits == other.fMaxSigDigits)
181             && (fUseScientific == other.fUseScientific)
182             && (fUseSigDigits == other.fUseSigDigits)
183             && fGrouping.equals(other.fGrouping)
184             && fPositivePrefixPattern.equals(other.fPositivePrefixPattern)
185             && fNegativePrefixPattern.equals(other.fNegativePrefixPattern)
186             && fPositiveSuffixPattern.equals(other.fPositiveSuffixPattern)
187             && fNegativeSuffixPattern.equals(other.fNegativeSuffixPattern)
188             && fCurrencyUsage == other.fCurrencyUsage
189             && fAffixParser.equals(other.fAffixParser)
190             && fCurrencyAffixInfo.equals(other.fCurrencyAffixInfo)
191             && fEffPrecision.equals(other.fEffPrecision)
192             && fEffGrouping.equals(other.fEffGrouping)
193             && fOptions.equals(other.fOptions)
194             && fFormatter.equals(other.fFormatter)
195             && fAffixes.equals(other.fAffixes)
196             && (*fSymbols == *other.fSymbols)
197             && ((fRules == other.fRules) || (
198                     (fRules != NULL) && (other.fRules != NULL)
199                     && (*fRules == *other.fRules)))
200             && (fMonetary == other.fMonetary);
201 }
202 
~DecimalFormatImpl()203 DecimalFormatImpl::~DecimalFormatImpl() {
204     delete fSymbols;
205     delete fRules;
206 }
207 
208 ValueFormatter &
prepareValueFormatter(ValueFormatter & vf) const209 DecimalFormatImpl::prepareValueFormatter(ValueFormatter &vf) const {
210     if (fUseScientific) {
211         vf.prepareScientificFormatting(
212                 fFormatter, fEffPrecision, fOptions);
213         return vf;
214     }
215     vf.prepareFixedDecimalFormatting(
216             fFormatter, fEffGrouping, fEffPrecision.fMantissa, fOptions.fMantissa);
217     return vf;
218 }
219 
220 int32_t
getPatternScale() const221 DecimalFormatImpl::getPatternScale() const {
222     UBool usesPercent = fPositivePrefixPattern.usesPercent() ||
223             fPositiveSuffixPattern.usesPercent() ||
224             fNegativePrefixPattern.usesPercent() ||
225             fNegativeSuffixPattern.usesPercent();
226     if (usesPercent) {
227         return 2;
228     }
229     UBool usesPermill = fPositivePrefixPattern.usesPermill() ||
230             fPositiveSuffixPattern.usesPermill() ||
231             fNegativePrefixPattern.usesPermill() ||
232             fNegativeSuffixPattern.usesPermill();
233     if (usesPermill) {
234         return 3;
235     }
236     return 0;
237 }
238 
239 void
setMultiplierScale(int32_t scale)240 DecimalFormatImpl::setMultiplierScale(int32_t scale) {
241     if (scale == 0) {
242         // Needed to preserve equality. fMultiplier == 0 means
243         // multiplier is 1.
244         fMultiplier.set(0);
245     } else {
246         fMultiplier.set(1);
247         fMultiplier.shiftDecimalRight(scale);
248     }
249 }
250 
251 UnicodeString &
format(int32_t number,UnicodeString & appendTo,FieldPosition & pos,UErrorCode & status) const252 DecimalFormatImpl::format(
253         int32_t number,
254         UnicodeString &appendTo,
255         FieldPosition &pos,
256         UErrorCode &status) const {
257     FieldPositionOnlyHandler handler(pos);
258     return formatInt32(number, appendTo, handler, status);
259 }
260 
261 UnicodeString &
format(int32_t number,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const262 DecimalFormatImpl::format(
263         int32_t number,
264         UnicodeString &appendTo,
265         FieldPositionIterator *posIter,
266         UErrorCode &status) const {
267     FieldPositionIteratorHandler handler(posIter, status);
268     return formatInt32(number, appendTo, handler, status);
269 }
270 
271 template<class T>
maybeFormatWithDigitList(T number,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const272 UBool DecimalFormatImpl::maybeFormatWithDigitList(
273         T number,
274         UnicodeString &appendTo,
275         FieldPositionHandler &handler,
276         UErrorCode &status) const {
277     if (!fMultiplier.isZero()) {
278         DigitList digits;
279         digits.set(number);
280         digits.mult(fMultiplier, status);
281         digits.shiftDecimalRight(fScale);
282         formatAdjustedDigitList(digits, appendTo, handler, status);
283         return TRUE;
284     }
285     if (fScale != 0) {
286         DigitList digits;
287         digits.set(number);
288         digits.shiftDecimalRight(fScale);
289         formatAdjustedDigitList(digits, appendTo, handler, status);
290         return TRUE;
291     }
292     return FALSE;
293 }
294 
295 template<class T>
maybeInitVisibleDigitsFromDigitList(T number,VisibleDigitsWithExponent & visibleDigits,UErrorCode & status) const296 UBool DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList(
297         T number,
298         VisibleDigitsWithExponent &visibleDigits,
299         UErrorCode &status) const {
300     if (!fMultiplier.isZero()) {
301         DigitList digits;
302         digits.set(number);
303         digits.mult(fMultiplier, status);
304         digits.shiftDecimalRight(fScale);
305         initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
306         return TRUE;
307     }
308     if (fScale != 0) {
309         DigitList digits;
310         digits.set(number);
311         digits.shiftDecimalRight(fScale);
312         initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
313         return TRUE;
314     }
315     return FALSE;
316 }
317 
318 UnicodeString &
formatInt32(int32_t number,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const319 DecimalFormatImpl::formatInt32(
320         int32_t number,
321         UnicodeString &appendTo,
322         FieldPositionHandler &handler,
323         UErrorCode &status) const {
324     if (maybeFormatWithDigitList(number, appendTo, handler, status)) {
325         return appendTo;
326     }
327     ValueFormatter vf;
328     return fAffixes.formatInt32(
329             number,
330             prepareValueFormatter(vf),
331             handler,
332             fRules,
333             appendTo,
334             status);
335 }
336 
337 UnicodeString &
formatInt64(int64_t number,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const338 DecimalFormatImpl::formatInt64(
339         int64_t number,
340         UnicodeString &appendTo,
341         FieldPositionHandler &handler,
342         UErrorCode &status) const {
343     if (number >= INT32_MIN && number <= INT32_MAX) {
344         return formatInt32((int32_t) number, appendTo, handler, status);
345     }
346     VisibleDigitsWithExponent digits;
347     initVisibleDigitsWithExponent(number, digits, status);
348     return formatVisibleDigitsWithExponent(
349             digits, appendTo, handler, status);
350 }
351 
352 UnicodeString &
formatDouble(double number,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const353 DecimalFormatImpl::formatDouble(
354         double number,
355         UnicodeString &appendTo,
356         FieldPositionHandler &handler,
357         UErrorCode &status) const {
358     VisibleDigitsWithExponent digits;
359     initVisibleDigitsWithExponent(number, digits, status);
360     return formatVisibleDigitsWithExponent(
361             digits, appendTo, handler, status);
362 }
363 
364 UnicodeString &
format(double number,UnicodeString & appendTo,FieldPosition & pos,UErrorCode & status) const365 DecimalFormatImpl::format(
366         double number,
367         UnicodeString &appendTo,
368         FieldPosition &pos,
369         UErrorCode &status) const {
370     FieldPositionOnlyHandler handler(pos);
371     return formatDouble(number, appendTo, handler, status);
372 }
373 
374 UnicodeString &
format(const DigitList & number,UnicodeString & appendTo,FieldPosition & pos,UErrorCode & status) const375 DecimalFormatImpl::format(
376         const DigitList &number,
377         UnicodeString &appendTo,
378         FieldPosition &pos,
379         UErrorCode &status) const {
380     DigitList dl(number);
381     FieldPositionOnlyHandler handler(pos);
382     return formatDigitList(dl, appendTo, handler, status);
383 }
384 
385 UnicodeString &
format(int64_t number,UnicodeString & appendTo,FieldPosition & pos,UErrorCode & status) const386 DecimalFormatImpl::format(
387         int64_t number,
388         UnicodeString &appendTo,
389         FieldPosition &pos,
390         UErrorCode &status) const {
391     FieldPositionOnlyHandler handler(pos);
392     return formatInt64(number, appendTo, handler, status);
393 }
394 
395 UnicodeString &
format(int64_t number,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const396 DecimalFormatImpl::format(
397         int64_t number,
398         UnicodeString &appendTo,
399         FieldPositionIterator *posIter,
400         UErrorCode &status) const {
401     FieldPositionIteratorHandler handler(posIter, status);
402     return formatInt64(number, appendTo, handler, status);
403 }
404 
405 UnicodeString &
format(double number,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const406 DecimalFormatImpl::format(
407         double number,
408         UnicodeString &appendTo,
409         FieldPositionIterator *posIter,
410         UErrorCode &status) const {
411     FieldPositionIteratorHandler handler(posIter, status);
412     return formatDouble(number, appendTo, handler, status);
413 }
414 
415 UnicodeString &
format(const DigitList & number,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const416 DecimalFormatImpl::format(
417         const DigitList &number,
418         UnicodeString &appendTo,
419         FieldPositionIterator *posIter,
420         UErrorCode &status) const {
421     DigitList dl(number);
422     FieldPositionIteratorHandler handler(posIter, status);
423     return formatDigitList(dl, appendTo, handler, status);
424 }
425 
426 UnicodeString &
format(const StringPiece & number,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const427 DecimalFormatImpl::format(
428         const StringPiece &number,
429         UnicodeString &appendTo,
430         FieldPositionIterator *posIter,
431         UErrorCode &status) const {
432     DigitList dl;
433     dl.set(number, status);
434     FieldPositionIteratorHandler handler(posIter, status);
435     return formatDigitList(dl, appendTo, handler, status);
436 }
437 
438 UnicodeString &
format(const VisibleDigitsWithExponent & digits,UnicodeString & appendTo,FieldPosition & pos,UErrorCode & status) const439 DecimalFormatImpl::format(
440         const VisibleDigitsWithExponent &digits,
441         UnicodeString &appendTo,
442         FieldPosition &pos,
443         UErrorCode &status) const {
444     FieldPositionOnlyHandler handler(pos);
445     return formatVisibleDigitsWithExponent(
446             digits, appendTo, handler, status);
447 }
448 
449 UnicodeString &
format(const VisibleDigitsWithExponent & digits,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const450 DecimalFormatImpl::format(
451         const VisibleDigitsWithExponent &digits,
452         UnicodeString &appendTo,
453         FieldPositionIterator *posIter,
454         UErrorCode &status) const {
455     FieldPositionIteratorHandler handler(posIter, status);
456     return formatVisibleDigitsWithExponent(
457             digits, appendTo, handler, status);
458 }
459 
460 DigitList &
adjustDigitList(DigitList & number,UErrorCode & status) const461 DecimalFormatImpl::adjustDigitList(
462         DigitList &number, UErrorCode &status) const {
463     number.setRoundingMode(fRoundingMode);
464     if (!fMultiplier.isZero()) {
465         number.mult(fMultiplier, status);
466     }
467     if (fScale != 0) {
468         number.shiftDecimalRight(fScale);
469     }
470     number.reduce();
471     return number;
472 }
473 
474 UnicodeString &
formatDigitList(DigitList & number,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const475 DecimalFormatImpl::formatDigitList(
476         DigitList &number,
477         UnicodeString &appendTo,
478         FieldPositionHandler &handler,
479         UErrorCode &status) const {
480     VisibleDigitsWithExponent digits;
481     initVisibleDigitsWithExponent(number, digits, status);
482     return formatVisibleDigitsWithExponent(
483             digits, appendTo, handler, status);
484 }
485 
486 UnicodeString &
formatAdjustedDigitList(DigitList & number,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const487 DecimalFormatImpl::formatAdjustedDigitList(
488         DigitList &number,
489         UnicodeString &appendTo,
490         FieldPositionHandler &handler,
491         UErrorCode &status) const {
492     ValueFormatter vf;
493     return fAffixes.format(
494             number,
495             prepareValueFormatter(vf),
496             handler,
497             fRules,
498             appendTo,
499             status);
500 }
501 
502 UnicodeString &
formatVisibleDigitsWithExponent(const VisibleDigitsWithExponent & digits,UnicodeString & appendTo,FieldPositionHandler & handler,UErrorCode & status) const503 DecimalFormatImpl::formatVisibleDigitsWithExponent(
504         const VisibleDigitsWithExponent &digits,
505         UnicodeString &appendTo,
506         FieldPositionHandler &handler,
507         UErrorCode &status) const {
508     ValueFormatter vf;
509     return fAffixes.format(
510             digits,
511             prepareValueFormatter(vf),
512             handler,
513             fRules,
514             appendTo,
515             status);
516 }
517 
initFixedDecimal(const VisibleDigits & digits,FixedDecimal & result)518 static FixedDecimal &initFixedDecimal(
519         const VisibleDigits &digits, FixedDecimal &result) {
520     result.source = 0.0;
521     result.isNegative = digits.isNegative();
522     result.isNanOrInfinity = digits.isNaNOrInfinity();
523     digits.getFixedDecimal(
524             result.source, result.intValue, result.decimalDigits,
525             result.decimalDigitsWithoutTrailingZeros,
526             result.visibleDecimalDigitCount, result.hasIntegerValue);
527     return result;
528 }
529 
530 FixedDecimal &
getFixedDecimal(double number,FixedDecimal & result,UErrorCode & status) const531 DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const {
532     if (U_FAILURE(status)) {
533         return result;
534     }
535     VisibleDigits digits;
536     fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
537     return initFixedDecimal(digits, result);
538 }
539 
540 FixedDecimal &
getFixedDecimal(DigitList & number,FixedDecimal & result,UErrorCode & status) const541 DecimalFormatImpl::getFixedDecimal(
542         DigitList &number, FixedDecimal &result, UErrorCode &status) const {
543     if (U_FAILURE(status)) {
544         return result;
545     }
546     VisibleDigits digits;
547     fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
548     return initFixedDecimal(digits, result);
549 }
550 
551 VisibleDigitsWithExponent &
initVisibleDigitsWithExponent(int64_t number,VisibleDigitsWithExponent & digits,UErrorCode & status) const552 DecimalFormatImpl::initVisibleDigitsWithExponent(
553         int64_t number,
554         VisibleDigitsWithExponent &digits,
555         UErrorCode &status) const {
556     if (maybeInitVisibleDigitsFromDigitList(
557             number, digits, status)) {
558         return digits;
559     }
560     if (fUseScientific) {
561         fEffPrecision.initVisibleDigitsWithExponent(
562                 number, digits, status);
563     } else {
564         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
565                 number, digits, status);
566     }
567     return digits;
568 }
569 
570 VisibleDigitsWithExponent &
initVisibleDigitsWithExponent(double number,VisibleDigitsWithExponent & digits,UErrorCode & status) const571 DecimalFormatImpl::initVisibleDigitsWithExponent(
572         double number,
573         VisibleDigitsWithExponent &digits,
574         UErrorCode &status) const {
575     if (maybeInitVisibleDigitsFromDigitList(
576             number, digits, status)) {
577         return digits;
578     }
579     if (fUseScientific) {
580         fEffPrecision.initVisibleDigitsWithExponent(
581                 number, digits, status);
582     } else {
583         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
584                 number, digits, status);
585     }
586     return digits;
587 }
588 
589 VisibleDigitsWithExponent &
initVisibleDigitsWithExponent(DigitList & number,VisibleDigitsWithExponent & digits,UErrorCode & status) const590 DecimalFormatImpl::initVisibleDigitsWithExponent(
591         DigitList &number,
592         VisibleDigitsWithExponent &digits,
593         UErrorCode &status) const {
594     adjustDigitList(number, status);
595     return initVisibleDigitsFromAdjusted(number, digits, status);
596 }
597 
598 VisibleDigitsWithExponent &
initVisibleDigitsFromAdjusted(DigitList & number,VisibleDigitsWithExponent & digits,UErrorCode & status) const599 DecimalFormatImpl::initVisibleDigitsFromAdjusted(
600         DigitList &number,
601         VisibleDigitsWithExponent &digits,
602         UErrorCode &status) const {
603     if (fUseScientific) {
604         fEffPrecision.initVisibleDigitsWithExponent(
605                 number, digits, status);
606     } else {
607         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
608                 number, digits, status);
609     }
610     return digits;
611 }
612 
613 DigitList &
round(DigitList & number,UErrorCode & status) const614 DecimalFormatImpl::round(
615         DigitList &number, UErrorCode &status) const {
616     if (number.isNaN() || number.isInfinite()) {
617         return number;
618     }
619     adjustDigitList(number, status);
620     ValueFormatter vf;
621     prepareValueFormatter(vf);
622     return vf.round(number, status);
623 }
624 
625 void
setMinimumSignificantDigits(int32_t newValue)626 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) {
627     fMinSigDigits = newValue;
628     fUseSigDigits = TRUE; // ticket 9936
629     updatePrecision();
630 }
631 
632 void
setMaximumSignificantDigits(int32_t newValue)633 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) {
634     fMaxSigDigits = newValue;
635     fUseSigDigits = TRUE; // ticket 9936
636     updatePrecision();
637 }
638 
639 void
setMinMaxSignificantDigits(int32_t min,int32_t max)640 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) {
641     fMinSigDigits = min;
642     fMaxSigDigits = max;
643     fUseSigDigits = TRUE; // ticket 9936
644     updatePrecision();
645 }
646 
647 void
setScientificNotation(UBool newValue)648 DecimalFormatImpl::setScientificNotation(UBool newValue) {
649     fUseScientific = newValue;
650     updatePrecision();
651 }
652 
653 void
setSignificantDigitsUsed(UBool newValue)654 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) {
655     fUseSigDigits = newValue;
656     updatePrecision();
657 }
658 
659 void
setGroupingSize(int32_t newValue)660 DecimalFormatImpl::setGroupingSize(int32_t newValue) {
661     fGrouping.fGrouping = newValue;
662     updateGrouping();
663 }
664 
665 void
setSecondaryGroupingSize(int32_t newValue)666 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) {
667     fGrouping.fGrouping2 = newValue;
668     updateGrouping();
669 }
670 
671 void
setMinimumGroupingDigits(int32_t newValue)672 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) {
673     fGrouping.fMinGrouping = newValue;
674     updateGrouping();
675 }
676 
677 void
setCurrencyUsage(UCurrencyUsage currencyUsage,UErrorCode & status)678 DecimalFormatImpl::setCurrencyUsage(
679         UCurrencyUsage currencyUsage, UErrorCode &status) {
680     fCurrencyUsage = currencyUsage;
681     updateFormatting(kFormattingCurrency, status);
682 }
683 
684 void
setRoundingIncrement(double d)685 DecimalFormatImpl::setRoundingIncrement(double d) {
686     if (d > 0.0) {
687         fEffPrecision.fMantissa.fRoundingIncrement.set(d);
688     } else {
689         fEffPrecision.fMantissa.fRoundingIncrement.set(0.0);
690     }
691 }
692 
693 double
getRoundingIncrement() const694 DecimalFormatImpl::getRoundingIncrement() const {
695     return fEffPrecision.fMantissa.fRoundingIncrement.getDouble();
696 }
697 
698 int32_t
getMultiplier() const699 DecimalFormatImpl::getMultiplier() const {
700     if (fMultiplier.isZero()) {
701         return 1;
702     }
703     return (int32_t) fMultiplier.getDouble();
704 }
705 
706 void
setMultiplier(int32_t m)707 DecimalFormatImpl::setMultiplier(int32_t m) {
708     if (m == 0 || m == 1) {
709         fMultiplier.set(0);
710     } else {
711         fMultiplier.set(m);
712     }
713 }
714 
715 void
setPositivePrefix(const UnicodeString & str)716 DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) {
717     fPositivePrefixPattern.remove();
718     fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
719     UErrorCode status = U_ZERO_ERROR;
720     updateFormatting(kFormattingPosPrefix, status);
721 }
722 
723 void
setPositiveSuffix(const UnicodeString & str)724 DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) {
725     fPositiveSuffixPattern.remove();
726     fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
727     UErrorCode status = U_ZERO_ERROR;
728     updateFormatting(kFormattingPosSuffix, status);
729 }
730 
731 void
setNegativePrefix(const UnicodeString & str)732 DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) {
733     fNegativePrefixPattern.remove();
734     fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
735     UErrorCode status = U_ZERO_ERROR;
736     updateFormatting(kFormattingNegPrefix, status);
737 }
738 
739 void
setNegativeSuffix(const UnicodeString & str)740 DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) {
741     fNegativeSuffixPattern.remove();
742     fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
743     UErrorCode status = U_ZERO_ERROR;
744     updateFormatting(kFormattingNegSuffix, status);
745 }
746 
747 UnicodeString &
getPositivePrefix(UnicodeString & result) const748 DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const {
749     result = fAffixes.fPositivePrefix.getOtherVariant().toString();
750     return result;
751 }
752 
753 UnicodeString &
getPositiveSuffix(UnicodeString & result) const754 DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const {
755     result = fAffixes.fPositiveSuffix.getOtherVariant().toString();
756     return result;
757 }
758 
759 UnicodeString &
getNegativePrefix(UnicodeString & result) const760 DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const {
761     result = fAffixes.fNegativePrefix.getOtherVariant().toString();
762     return result;
763 }
764 
765 UnicodeString &
getNegativeSuffix(UnicodeString & result) const766 DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const {
767     result = fAffixes.fNegativeSuffix.getOtherVariant().toString();
768     return result;
769 }
770 
771 void
adoptDecimalFormatSymbols(DecimalFormatSymbols * symbolsToAdopt)772 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) {
773     if (symbolsToAdopt == NULL) {
774         return;
775     }
776     delete fSymbols;
777     fSymbols = symbolsToAdopt;
778     UErrorCode status = U_ZERO_ERROR;
779     updateFormatting(kFormattingSymbols, status);
780 }
781 
782 void
applyPatternFavorCurrencyPrecision(const UnicodeString & pattern,UErrorCode & status)783 DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
784         const UnicodeString &pattern, UErrorCode &status) {
785     UParseError perror;
786     applyPattern(pattern, FALSE, perror, status);
787     updateForApplyPatternFavorCurrencyPrecision(status);
788 }
789 
790 void
applyPattern(const UnicodeString & pattern,UErrorCode & status)791 DecimalFormatImpl::applyPattern(
792         const UnicodeString &pattern, UErrorCode &status) {
793     UParseError perror;
794     applyPattern(pattern, FALSE, perror, status);
795     updateForApplyPattern(status);
796 }
797 
798 void
applyPattern(const UnicodeString & pattern,UParseError & perror,UErrorCode & status)799 DecimalFormatImpl::applyPattern(
800         const UnicodeString &pattern,
801         UParseError &perror, UErrorCode &status) {
802     applyPattern(pattern, FALSE, perror, status);
803     updateForApplyPattern(status);
804 }
805 
806 void
applyLocalizedPattern(const UnicodeString & pattern,UErrorCode & status)807 DecimalFormatImpl::applyLocalizedPattern(
808         const UnicodeString &pattern, UErrorCode &status) {
809     UParseError perror;
810     applyPattern(pattern, TRUE, perror, status);
811     updateForApplyPattern(status);
812 }
813 
814 void
applyLocalizedPattern(const UnicodeString & pattern,UParseError & perror,UErrorCode & status)815 DecimalFormatImpl::applyLocalizedPattern(
816         const UnicodeString &pattern,
817         UParseError &perror,  UErrorCode &status) {
818     applyPattern(pattern, TRUE, perror, status);
819     updateForApplyPattern(status);
820 }
821 
822 void
applyPattern(const UnicodeString & pattern,UBool localized,UParseError & perror,UErrorCode & status)823 DecimalFormatImpl::applyPattern(
824         const UnicodeString &pattern,
825         UBool localized, UParseError &perror, UErrorCode &status) {
826     if (U_FAILURE(status)) {
827         return;
828     }
829     DecimalFormatPatternParser patternParser;
830     if (localized) {
831         patternParser.useSymbols(*fSymbols);
832     }
833     DecimalFormatPattern out;
834     patternParser.applyPatternWithoutExpandAffix(
835             pattern, out, perror, status);
836     if (U_FAILURE(status)) {
837         return;
838     }
839     fUseScientific = out.fUseExponentialNotation;
840     fUseSigDigits = out.fUseSignificantDigits;
841     fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits);
842     fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits);
843     fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits);
844     fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits);
845     fMinSigDigits = out.fMinimumSignificantDigits;
846     fMaxSigDigits = out.fMaximumSignificantDigits;
847     fEffPrecision.fMinExponentDigits = out.fMinExponentDigits;
848     fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown;
849     fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed);
850     fGrouping.fGrouping = out.fGroupingSize;
851     fGrouping.fGrouping2 = out.fGroupingSize2;
852     fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown;
853     if (out.fRoundingIncrementUsed) {
854         fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement;
855     } else {
856         fEffPrecision.fMantissa.fRoundingIncrement.clear();
857     }
858     fAffixes.fPadChar = out.fPad;
859     fNegativePrefixPattern = out.fNegPrefixAffix;
860     fNegativeSuffixPattern = out.fNegSuffixAffix;
861     fPositivePrefixPattern = out.fPosPrefixAffix;
862     fPositiveSuffixPattern = out.fPosSuffixAffix;
863 
864     // Work around. Pattern parsing code and DecimalFormat code don't agree
865     // on the definition of field width, so we have to translate from
866     // pattern field width to decimal format field width here.
867     fAffixes.fWidth = out.fFormatWidth == 0 ? 0 :
868             out.fFormatWidth + fPositivePrefixPattern.countChar32()
869             + fPositiveSuffixPattern.countChar32();
870     switch (out.fPadPosition) {
871     case DecimalFormatPattern::kPadBeforePrefix:
872         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix;
873         break;
874     case DecimalFormatPattern::kPadAfterPrefix:
875         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix;
876         break;
877     case DecimalFormatPattern::kPadBeforeSuffix:
878         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix;
879         break;
880     case DecimalFormatPattern::kPadAfterSuffix:
881         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
882         break;
883     default:
884         break;
885     }
886 }
887 
888 void
updatePrecision()889 DecimalFormatImpl::updatePrecision() {
890     if (fUseScientific) {
891         updatePrecisionForScientific();
892     } else {
893         updatePrecisionForFixed();
894     }
895 }
896 
updatePrecisionForScientificMinMax(const DigitInterval & min,const DigitInterval & max,DigitInterval & resultMin,DigitInterval & resultMax,SignificantDigitInterval & resultSignificant)897 static void updatePrecisionForScientificMinMax(
898         const DigitInterval &min,
899         const DigitInterval &max,
900         DigitInterval &resultMin,
901         DigitInterval &resultMax,
902         SignificantDigitInterval &resultSignificant) {
903     resultMin.setIntDigitCount(0);
904     resultMin.setFracDigitCount(0);
905     resultSignificant.clear();
906     resultMax.clear();
907 
908     int32_t maxIntDigitCount = max.getIntDigitCount();
909     int32_t minIntDigitCount = min.getIntDigitCount();
910     int32_t maxFracDigitCount = max.getFracDigitCount();
911     int32_t minFracDigitCount = min.getFracDigitCount();
912 
913 
914     // Not in spec: maxIntDigitCount > 8 assume
915     // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
916     // no provision for unsetting maxIntDigitCount which would be useful for
917     // scientific notation. The best we can do is assume that if
918     // maxIntDigitCount is the default of 2000000000 or is "big enough" then
919     // user did not intend to explicitly set it. The 8 was derived emperically
920     // by extensive testing of legacy code.
921     if (maxIntDigitCount > 8) {
922         maxIntDigitCount = minIntDigitCount;
923     }
924 
925     // Per the spec, exponent grouping happens if maxIntDigitCount is more
926     // than 1 and more than minIntDigitCount.
927     UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount;
928     if (bExponentGrouping) {
929         resultMax.setIntDigitCount(maxIntDigitCount);
930 
931         // For exponent grouping minIntDigits is always treated as 1 even
932         // if it wasn't set to 1!
933         resultMin.setIntDigitCount(1);
934     } else {
935         // Fixed digit count left of decimal. minIntDigitCount doesn't have
936         // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
937         // maxIntDigitCount == 1.
938         int32_t fixedIntDigitCount = maxIntDigitCount;
939 
940         // If fixedIntDigitCount is 0 but
941         // min or max fraction count is 0 too then use 1. This way we can get
942         // unlimited precision for X.XXXEX
943         if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) {
944             fixedIntDigitCount = 1;
945         }
946         resultMax.setIntDigitCount(fixedIntDigitCount);
947         resultMin.setIntDigitCount(fixedIntDigitCount);
948     }
949     // Spec says this is how we compute significant digits. 0 means
950     // unlimited significant digits.
951     int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount;
952     if (maxSigDigits > 0) {
953         int32_t minSigDigits = minIntDigitCount + minFracDigitCount;
954         resultSignificant.setMin(minSigDigits);
955         resultSignificant.setMax(maxSigDigits);
956     }
957 }
958 
959 void
updatePrecisionForScientific()960 DecimalFormatImpl::updatePrecisionForScientific() {
961     FixedPrecision *result = &fEffPrecision.fMantissa;
962     if (fUseSigDigits) {
963         result->fMax.setFracDigitCount(-1);
964         result->fMax.setIntDigitCount(1);
965         result->fMin.setFracDigitCount(0);
966         result->fMin.setIntDigitCount(1);
967         result->fSignificant.clear();
968         extractSigDigits(result->fSignificant);
969         return;
970     }
971     DigitInterval max;
972     DigitInterval min;
973     extractMinMaxDigits(min, max);
974     updatePrecisionForScientificMinMax(
975             min, max,
976             result->fMin, result->fMax, result->fSignificant);
977 }
978 
979 void
updatePrecisionForFixed()980 DecimalFormatImpl::updatePrecisionForFixed() {
981     FixedPrecision *result = &fEffPrecision.fMantissa;
982     if (!fUseSigDigits) {
983         extractMinMaxDigits(result->fMin, result->fMax);
984         result->fSignificant.clear();
985     } else {
986         extractSigDigits(result->fSignificant);
987         result->fMin.setIntDigitCount(1);
988         result->fMin.setFracDigitCount(0);
989         result->fMax.clear();
990     }
991 }
992 
993 void
extractMinMaxDigits(DigitInterval & min,DigitInterval & max) const994  DecimalFormatImpl::extractMinMaxDigits(
995         DigitInterval &min, DigitInterval &max) const {
996     min.setIntDigitCount(fSuper->getMinimumIntegerDigits());
997     max.setIntDigitCount(fSuper->getMaximumIntegerDigits());
998     min.setFracDigitCount(fSuper->getMinimumFractionDigits());
999     max.setFracDigitCount(fSuper->getMaximumFractionDigits());
1000 }
1001 
1002 void
extractSigDigits(SignificantDigitInterval & sig) const1003  DecimalFormatImpl::extractSigDigits(
1004         SignificantDigitInterval &sig) const {
1005     sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits);
1006     sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits);
1007 }
1008 
1009 void
updateGrouping()1010 DecimalFormatImpl::updateGrouping() {
1011     if (fSuper->isGroupingUsed()) {
1012         fEffGrouping = fGrouping;
1013     } else {
1014         fEffGrouping.clear();
1015     }
1016 }
1017 
1018 void
updateCurrency(UErrorCode & status)1019 DecimalFormatImpl::updateCurrency(UErrorCode &status) {
1020     updateFormatting(kFormattingCurrency, TRUE, status);
1021 }
1022 
1023 void
updateFormatting(int32_t changedFormattingFields,UErrorCode & status)1024 DecimalFormatImpl::updateFormatting(
1025         int32_t changedFormattingFields,
1026         UErrorCode &status) {
1027     updateFormatting(changedFormattingFields, TRUE, status);
1028 }
1029 
1030 void
updateFormatting(int32_t changedFormattingFields,UBool updatePrecisionBasedOnCurrency,UErrorCode & status)1031 DecimalFormatImpl::updateFormatting(
1032         int32_t changedFormattingFields,
1033         UBool updatePrecisionBasedOnCurrency,
1034         UErrorCode &status) {
1035     if (U_FAILURE(status)) {
1036         return;
1037     }
1038     // Each function updates one field. Order matters. For instance,
1039     // updatePluralRules comes before updateCurrencyAffixInfo because the
1040     // fRules field is needed to update the fCurrencyAffixInfo field.
1041     updateFormattingUsesCurrency(changedFormattingFields);
1042     updateFormattingFixedPointFormatter(changedFormattingFields);
1043     updateFormattingAffixParser(changedFormattingFields);
1044     updateFormattingPluralRules(changedFormattingFields, status);
1045     updateFormattingCurrencyAffixInfo(
1046             changedFormattingFields,
1047             updatePrecisionBasedOnCurrency,
1048             status);
1049     updateFormattingLocalizedPositivePrefix(
1050             changedFormattingFields, status);
1051     updateFormattingLocalizedPositiveSuffix(
1052             changedFormattingFields, status);
1053     updateFormattingLocalizedNegativePrefix(
1054             changedFormattingFields, status);
1055     updateFormattingLocalizedNegativeSuffix(
1056             changedFormattingFields, status);
1057 }
1058 
1059 void
updateFormattingUsesCurrency(int32_t & changedFormattingFields)1060 DecimalFormatImpl::updateFormattingUsesCurrency(
1061         int32_t &changedFormattingFields) {
1062     if ((changedFormattingFields & kFormattingAffixes) == 0) {
1063         // If no affixes changed, don't need to do any work
1064         return;
1065     }
1066     UBool newUsesCurrency =
1067             fPositivePrefixPattern.usesCurrency() ||
1068             fPositiveSuffixPattern.usesCurrency() ||
1069             fNegativePrefixPattern.usesCurrency() ||
1070             fNegativeSuffixPattern.usesCurrency();
1071     if (fMonetary != newUsesCurrency) {
1072         fMonetary = newUsesCurrency;
1073         changedFormattingFields |= kFormattingUsesCurrency;
1074     }
1075 }
1076 
1077 void
updateFormattingPluralRules(int32_t & changedFormattingFields,UErrorCode & status)1078 DecimalFormatImpl::updateFormattingPluralRules(
1079         int32_t &changedFormattingFields, UErrorCode &status) {
1080     if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
1081         // No work to do if both fSymbols and fMonetary
1082         // fields are unchanged
1083         return;
1084     }
1085     if (U_FAILURE(status)) {
1086         return;
1087     }
1088     PluralRules *newRules = NULL;
1089     if (fMonetary) {
1090         newRules = PluralRules::forLocale(fSymbols->getLocale(), status);
1091         if (U_FAILURE(status)) {
1092             return;
1093         }
1094     }
1095     // Its ok to say a field has changed when it really hasn't but not
1096     // the other way around. Here we assume the field changed unless it
1097     // was NULL before and is still NULL now
1098     if (fRules != newRules) {
1099         delete fRules;
1100         fRules = newRules;
1101         changedFormattingFields |= kFormattingPluralRules;
1102     }
1103 }
1104 
1105 void
updateFormattingCurrencyAffixInfo(int32_t & changedFormattingFields,UBool updatePrecisionBasedOnCurrency,UErrorCode & status)1106 DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
1107         int32_t &changedFormattingFields,
1108         UBool updatePrecisionBasedOnCurrency,
1109         UErrorCode &status) {
1110     if ((changedFormattingFields & (
1111             kFormattingSymbols | kFormattingCurrency |
1112             kFormattingUsesCurrency | kFormattingPluralRules)) == 0) {
1113         // If all these fields are unchanged, no work to do.
1114         return;
1115     }
1116     if (U_FAILURE(status)) {
1117         return;
1118     }
1119     if (!fMonetary) {
1120         if (fCurrencyAffixInfo.isDefault()) {
1121             // In this case don't have to do any work
1122             return;
1123         }
1124         fCurrencyAffixInfo.set(NULL, NULL, NULL, status);
1125         if (U_FAILURE(status)) {
1126             return;
1127         }
1128         changedFormattingFields |= kFormattingCurrencyAffixInfo;
1129     } else {
1130         const UChar *currency = fSuper->getCurrency();
1131         UChar localeCurr[4];
1132         if (currency[0] == 0) {
1133             ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status);
1134             if (U_SUCCESS(status)) {
1135                 currency = localeCurr;
1136                 fSuper->NumberFormat::setCurrency(currency, status);
1137             } else {
1138                 currency = NULL;
1139                 status = U_ZERO_ERROR;
1140             }
1141         }
1142         fCurrencyAffixInfo.set(
1143                 fSymbols->getLocale().getName(), fRules, currency, status);
1144         if (U_FAILURE(status)) {
1145             return;
1146         }
1147         UBool customCurrencySymbol = FALSE;
1148         // If DecimalFormatSymbols has custom currency symbol, prefer
1149         // that over what we just read from the resource bundles
1150         if (fSymbols->isCustomCurrencySymbol()) {
1151             fCurrencyAffixInfo.setSymbol(
1152                     fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
1153             customCurrencySymbol = TRUE;
1154         }
1155         if (fSymbols->isCustomIntlCurrencySymbol()) {
1156             fCurrencyAffixInfo.setISO(
1157                     fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1158             customCurrencySymbol = TRUE;
1159         }
1160         changedFormattingFields |= kFormattingCurrencyAffixInfo;
1161         if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) {
1162             FixedPrecision precision;
1163             CurrencyAffixInfo::adjustPrecision(
1164                     currency, fCurrencyUsage, precision, status);
1165             if (U_FAILURE(status)) {
1166                 return;
1167             }
1168             fSuper->NumberFormat::setMinimumFractionDigits(
1169                     precision.fMin.getFracDigitCount());
1170             fSuper->NumberFormat::setMaximumFractionDigits(
1171                     precision.fMax.getFracDigitCount());
1172             updatePrecision();
1173             fEffPrecision.fMantissa.fRoundingIncrement =
1174                     precision.fRoundingIncrement;
1175         }
1176 
1177     }
1178 }
1179 
1180 void
updateFormattingFixedPointFormatter(int32_t & changedFormattingFields)1181 DecimalFormatImpl::updateFormattingFixedPointFormatter(
1182         int32_t &changedFormattingFields) {
1183     if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
1184         // No work to do if fSymbols is unchanged
1185         return;
1186     }
1187     if (fMonetary) {
1188         fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols);
1189     } else {
1190         fFormatter.setDecimalFormatSymbols(*fSymbols);
1191     }
1192 }
1193 
1194 void
updateFormattingAffixParser(int32_t & changedFormattingFields)1195 DecimalFormatImpl::updateFormattingAffixParser(
1196         int32_t &changedFormattingFields) {
1197     if ((changedFormattingFields & kFormattingSymbols) == 0) {
1198         // No work to do if fSymbols is unchanged
1199         return;
1200     }
1201     fAffixParser.setDecimalFormatSymbols(*fSymbols);
1202     changedFormattingFields |= kFormattingAffixParser;
1203 }
1204 
1205 void
updateFormattingLocalizedPositivePrefix(int32_t & changedFormattingFields,UErrorCode & status)1206 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
1207         int32_t &changedFormattingFields, UErrorCode &status) {
1208     if (U_FAILURE(status)) {
1209         return;
1210     }
1211     if ((changedFormattingFields & (
1212             kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) {
1213         // No work to do
1214         return;
1215     }
1216     fAffixes.fPositivePrefix.remove();
1217     fAffixParser.parse(
1218             fPositivePrefixPattern,
1219             fCurrencyAffixInfo,
1220             fAffixes.fPositivePrefix,
1221             status);
1222 }
1223 
1224 void
updateFormattingLocalizedPositiveSuffix(int32_t & changedFormattingFields,UErrorCode & status)1225 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
1226         int32_t &changedFormattingFields, UErrorCode &status) {
1227     if (U_FAILURE(status)) {
1228         return;
1229     }
1230     if ((changedFormattingFields & (
1231             kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) {
1232         // No work to do
1233         return;
1234     }
1235     fAffixes.fPositiveSuffix.remove();
1236     fAffixParser.parse(
1237             fPositiveSuffixPattern,
1238             fCurrencyAffixInfo,
1239             fAffixes.fPositiveSuffix,
1240             status);
1241 }
1242 
1243 void
updateFormattingLocalizedNegativePrefix(int32_t & changedFormattingFields,UErrorCode & status)1244 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
1245         int32_t &changedFormattingFields, UErrorCode &status) {
1246     if (U_FAILURE(status)) {
1247         return;
1248     }
1249     if ((changedFormattingFields & (
1250             kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) {
1251         // No work to do
1252         return;
1253     }
1254     fAffixes.fNegativePrefix.remove();
1255     fAffixParser.parse(
1256             fNegativePrefixPattern,
1257             fCurrencyAffixInfo,
1258             fAffixes.fNegativePrefix,
1259             status);
1260 }
1261 
1262 void
updateFormattingLocalizedNegativeSuffix(int32_t & changedFormattingFields,UErrorCode & status)1263 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
1264         int32_t &changedFormattingFields, UErrorCode &status) {
1265     if (U_FAILURE(status)) {
1266         return;
1267     }
1268     if ((changedFormattingFields & (
1269             kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) {
1270         // No work to do
1271         return;
1272     }
1273     fAffixes.fNegativeSuffix.remove();
1274     fAffixParser.parse(
1275             fNegativeSuffixPattern,
1276             fCurrencyAffixInfo,
1277             fAffixes.fNegativeSuffix,
1278             status);
1279 }
1280 
1281 void
updateForApplyPatternFavorCurrencyPrecision(UErrorCode & status)1282 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
1283         UErrorCode &status) {
1284     updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status);
1285 }
1286 
1287 void
updateForApplyPattern(UErrorCode & status)1288 DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) {
1289     updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status);
1290 }
1291 
1292 void
updateAll(UErrorCode & status)1293 DecimalFormatImpl::updateAll(UErrorCode &status) {
1294     updateAll(kFormattingAll, TRUE, status);
1295 }
1296 
1297 void
updateAll(int32_t formattingFlags,UBool updatePrecisionBasedOnCurrency,UErrorCode & status)1298 DecimalFormatImpl::updateAll(
1299         int32_t formattingFlags,
1300         UBool updatePrecisionBasedOnCurrency,
1301         UErrorCode &status) {
1302     if (U_FAILURE(status)) {
1303         return;
1304     }
1305     updatePrecision();
1306     updateGrouping();
1307     updateFormatting(
1308             formattingFlags, updatePrecisionBasedOnCurrency, status);
1309     setMultiplierScale(getPatternScale());
1310 }
1311 
1312 
1313 static int32_t
getMinimumLengthToDescribeGrouping(const DigitGrouping & grouping)1314 getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) {
1315     if (grouping.fGrouping <= 0) {
1316         return 0;
1317     }
1318     if (grouping.fGrouping2 <= 0) {
1319         return grouping.fGrouping + 1;
1320     }
1321     return grouping.fGrouping + grouping.fGrouping2 + 1;
1322 }
1323 
1324 /**
1325  * Given a grouping policy, calculates how many digits are needed left of
1326  * the decimal point to achieve a desired length left of the
1327  * decimal point.
1328  * @param grouping the grouping policy
1329  * @param desiredLength number of characters needed left of decimal point
1330  * @param minLeftDigits at least this many digits is returned
1331  * @param leftDigits the number of digits needed stored here
1332  *  which is >= minLeftDigits.
1333  * @return true if a perfect fit or false if having leftDigits would exceed
1334  *   desiredLength
1335  */
1336 static UBool
getLeftDigitsForLeftLength(const DigitGrouping & grouping,int32_t desiredLength,int32_t minLeftDigits,int32_t & leftDigits)1337 getLeftDigitsForLeftLength(
1338         const DigitGrouping &grouping,
1339         int32_t desiredLength,
1340         int32_t minLeftDigits,
1341         int32_t &leftDigits) {
1342     leftDigits = minLeftDigits;
1343     int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits);
1344     while (lengthSoFar < desiredLength) {
1345         lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1;
1346         ++leftDigits;
1347     }
1348     return (lengthSoFar == desiredLength);
1349 }
1350 
1351 int32_t
computeExponentPatternLength() const1352 DecimalFormatImpl::computeExponentPatternLength() const {
1353     if (fUseScientific) {
1354         return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits;
1355     }
1356     return 0;
1357 }
1358 
1359 int32_t
countFractionDigitAndDecimalPatternLength(int32_t fracDigitCount) const1360 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
1361         int32_t fracDigitCount) const {
1362     if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) {
1363         return 0;
1364     }
1365     return fracDigitCount + 1;
1366 }
1367 
1368 UnicodeString&
toNumberPattern(UBool hasPadding,int32_t minimumLength,UnicodeString & result) const1369 DecimalFormatImpl::toNumberPattern(
1370         UBool hasPadding, int32_t minimumLength, UnicodeString& result) const {
1371     // Get a grouping policy like the one in this object that does not
1372     // have minimum grouping since toPattern doesn't support it.
1373     DigitGrouping grouping(fEffGrouping);
1374     grouping.fMinGrouping = 0;
1375 
1376     // Only for fixed digits, these are the digits that get 0's.
1377     DigitInterval minInterval;
1378 
1379     // Only for fixed digits, these are the digits that get #'s.
1380     DigitInterval maxInterval;
1381 
1382     // Only for significant digits
1383     int32_t sigMin;
1384     int32_t sigMax;
1385 
1386     // These are all the digits to be displayed. For significant digits,
1387     // this interval always starts at the 1's place an extends left.
1388     DigitInterval fullInterval;
1389 
1390     // Digit range of rounding increment. If rounding increment is .025.
1391     // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
1392     int32_t roundingIncrementLowerExp = 0;
1393     int32_t roundingIncrementUpperExp = 0;
1394 
1395     if (fUseSigDigits) {
1396         SignificantDigitInterval sigInterval;
1397         extractSigDigits(sigInterval);
1398         sigMax = sigInterval.getMax();
1399         sigMin = sigInterval.getMin();
1400         fullInterval.setFracDigitCount(0);
1401         fullInterval.setIntDigitCount(sigMax);
1402     } else {
1403         extractMinMaxDigits(minInterval, maxInterval);
1404         if (fUseScientific) {
1405            if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) {
1406                maxInterval.setIntDigitCount(1);
1407                minInterval.shrinkToFitWithin(maxInterval);
1408            }
1409         } else if (hasPadding) {
1410             // Make max int digits match min int digits for now, we
1411             // compute necessary padding later.
1412             maxInterval.setIntDigitCount(minInterval.getIntDigitCount());
1413         } else {
1414             // For some reason toPattern adds at least one leading '#'
1415             maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1);
1416         }
1417         if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) {
1418             roundingIncrementLowerExp =
1419                     fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent();
1420             roundingIncrementUpperExp =
1421                     fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent();
1422             // We have to include the rounding increment in what we display
1423             maxInterval.expandToContainDigit(roundingIncrementLowerExp);
1424             maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1);
1425         }
1426         fullInterval = maxInterval;
1427     }
1428     // We have to include enough digits to show grouping strategy
1429     int32_t minLengthToDescribeGrouping =
1430            getMinimumLengthToDescribeGrouping(grouping);
1431     if (minLengthToDescribeGrouping > 0) {
1432         fullInterval.expandToContainDigit(
1433                 getMinimumLengthToDescribeGrouping(grouping) - 1);
1434     }
1435 
1436     // If we have a minimum length, we have to add digits to the left to
1437     // depict padding.
1438     if (hasPadding) {
1439         // For non scientific notation,
1440         //  minimumLengthForMantissa = minimumLength
1441         int32_t minimumLengthForMantissa =
1442                 minimumLength - computeExponentPatternLength();
1443         int32_t mininumLengthForMantissaIntPart =
1444                 minimumLengthForMantissa
1445                 - countFractionDigitAndDecimalPatternLength(
1446                         fullInterval.getFracDigitCount());
1447         // Because of grouping, we may need fewer than expected digits to
1448         // achieve the length we need.
1449         int32_t digitsNeeded;
1450         if (getLeftDigitsForLeftLength(
1451                 grouping,
1452                 mininumLengthForMantissaIntPart,
1453                 fullInterval.getIntDigitCount(),
1454                 digitsNeeded)) {
1455 
1456             // In this case, we achieved the exact length that we want.
1457             fullInterval.setIntDigitCount(digitsNeeded);
1458         } else if (digitsNeeded > fullInterval.getIntDigitCount()) {
1459 
1460             // Having digitsNeeded digits goes over desired length which
1461             // means that to have desired length would mean starting on a
1462             // grouping sepearator e.g ,###,### so add a '#' and use one
1463             // less digit. This trick gives ####,### but that is the best
1464             // we can do.
1465             result.append(kPatternDigit);
1466             fullInterval.setIntDigitCount(digitsNeeded - 1);
1467         }
1468     }
1469     int32_t maxDigitPos = fullInterval.getMostSignificantExclusive();
1470     int32_t minDigitPos = fullInterval.getLeastSignificantInclusive();
1471     for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) {
1472         if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) {
1473             result.append(kPatternDecimalSeparator);
1474         }
1475         if (fUseSigDigits) {
1476             // Use digit symbol
1477             if (i >= sigMax || i < sigMax - sigMin) {
1478                 result.append(kPatternDigit);
1479             } else {
1480                 result.append(kPatternSignificantDigit);
1481             }
1482         } else {
1483             if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) {
1484                 result.append(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit);
1485             } else if (minInterval.contains(i)) {
1486                 result.append(kPatternZeroDigit);
1487             } else {
1488                 result.append(kPatternDigit);
1489             }
1490         }
1491         if (grouping.isSeparatorAt(i + 1, i)) {
1492             result.append(kPatternGroupingSeparator);
1493         }
1494         if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) {
1495             result.append(kPatternDecimalSeparator);
1496         }
1497     }
1498     if (fUseScientific) {
1499         result.append(kPatternExponent);
1500         if (fOptions.fExponent.fAlwaysShowSign) {
1501             result.append(kPatternPlus);
1502         }
1503         for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) {
1504             result.append(kPatternZeroDigit);
1505         }
1506     }
1507     return result;
1508 }
1509 
1510 UnicodeString&
toPattern(UnicodeString & result) const1511 DecimalFormatImpl::toPattern(UnicodeString& result) const {
1512     result.remove();
1513     UnicodeString padSpec;
1514     if (fAffixes.fWidth > 0) {
1515         padSpec.append(kPatternPadEscape);
1516         padSpec.append(fAffixes.fPadChar);
1517     }
1518     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
1519         result.append(padSpec);
1520     }
1521     fPositivePrefixPattern.toUserString(result);
1522     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
1523         result.append(padSpec);
1524     }
1525     toNumberPattern(
1526             fAffixes.fWidth > 0,
1527             fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(),
1528             result);
1529     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
1530         result.append(padSpec);
1531     }
1532     fPositiveSuffixPattern.toUserString(result);
1533     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
1534         result.append(padSpec);
1535     }
1536     AffixPattern withNegative;
1537     withNegative.add(AffixPattern::kNegative);
1538     withNegative.append(fPositivePrefixPattern);
1539     if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) ||
1540             !withNegative.equals(fNegativePrefixPattern)) {
1541         result.append(kPatternSeparator);
1542         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
1543             result.append(padSpec);
1544         }
1545         fNegativePrefixPattern.toUserString(result);
1546         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
1547             result.append(padSpec);
1548         }
1549         toNumberPattern(
1550                 fAffixes.fWidth > 0,
1551                 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(),
1552                 result);
1553         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
1554             result.append(padSpec);
1555         }
1556         fNegativeSuffixPattern.toUserString(result);
1557         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
1558             result.append(padSpec);
1559         }
1560     }
1561     return result;
1562 }
1563 
1564 int32_t
getOldFormatWidth() const1565 DecimalFormatImpl::getOldFormatWidth() const {
1566     if (fAffixes.fWidth == 0) {
1567         return 0;
1568     }
1569     return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32();
1570 }
1571 
1572 const UnicodeString &
getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const1573 DecimalFormatImpl::getConstSymbol(
1574         DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
1575    return fSymbols->getConstSymbol(symbol);
1576 }
1577 
1578 UBool
isParseFastpath() const1579 DecimalFormatImpl::isParseFastpath() const {
1580     AffixPattern negative;
1581     negative.add(AffixPattern::kNegative);
1582 
1583     return fAffixes.fWidth == 0 &&
1584     fPositivePrefixPattern.countChar32() == 0 &&
1585     fNegativePrefixPattern.equals(negative) &&
1586     fPositiveSuffixPattern.countChar32() == 0 &&
1587     fNegativeSuffixPattern.countChar32() == 0;
1588 }
1589 
1590 
1591 U_NAMESPACE_END
1592 
1593 #endif /* #if !UCONFIG_NO_FORMATTING */
1594 
1595