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