• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 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.isNanOrInfinity = digits.isNaNOrInfinity();
525     digits.getFixedDecimal(
526             result.source, result.intValue, result.decimalDigits,
527             result.decimalDigitsWithoutTrailingZeros,
528             result.visibleDecimalDigitCount, result.hasIntegerValue);
529     return result;
530 }
531 
532 FixedDecimal &
getFixedDecimal(double number,FixedDecimal & result,UErrorCode & status) const533 DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const {
534     if (U_FAILURE(status)) {
535         return result;
536     }
537     VisibleDigits digits;
538     fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
539     return initFixedDecimal(digits, result);
540 }
541 
542 FixedDecimal &
getFixedDecimal(DigitList & number,FixedDecimal & result,UErrorCode & status) const543 DecimalFormatImpl::getFixedDecimal(
544         DigitList &number, FixedDecimal &result, UErrorCode &status) const {
545     if (U_FAILURE(status)) {
546         return result;
547     }
548     VisibleDigits digits;
549     fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
550     return initFixedDecimal(digits, result);
551 }
552 
553 VisibleDigitsWithExponent &
initVisibleDigitsWithExponent(int64_t number,VisibleDigitsWithExponent & digits,UErrorCode & status) const554 DecimalFormatImpl::initVisibleDigitsWithExponent(
555         int64_t number,
556         VisibleDigitsWithExponent &digits,
557         UErrorCode &status) const {
558     if (maybeInitVisibleDigitsFromDigitList(
559             number, digits, status)) {
560         return digits;
561     }
562     if (fUseScientific) {
563         fEffPrecision.initVisibleDigitsWithExponent(
564                 number, digits, status);
565     } else {
566         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
567                 number, digits, status);
568     }
569     return digits;
570 }
571 
572 VisibleDigitsWithExponent &
initVisibleDigitsWithExponent(double number,VisibleDigitsWithExponent & digits,UErrorCode & status) const573 DecimalFormatImpl::initVisibleDigitsWithExponent(
574         double number,
575         VisibleDigitsWithExponent &digits,
576         UErrorCode &status) const {
577     if (maybeInitVisibleDigitsFromDigitList(
578             number, digits, status)) {
579         return digits;
580     }
581     if (fUseScientific) {
582         fEffPrecision.initVisibleDigitsWithExponent(
583                 number, digits, status);
584     } else {
585         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
586                 number, digits, status);
587     }
588     return digits;
589 }
590 
591 VisibleDigitsWithExponent &
initVisibleDigitsWithExponent(DigitList & number,VisibleDigitsWithExponent & digits,UErrorCode & status) const592 DecimalFormatImpl::initVisibleDigitsWithExponent(
593         DigitList &number,
594         VisibleDigitsWithExponent &digits,
595         UErrorCode &status) const {
596     adjustDigitList(number, status);
597     return initVisibleDigitsFromAdjusted(number, digits, status);
598 }
599 
600 VisibleDigitsWithExponent &
initVisibleDigitsFromAdjusted(DigitList & number,VisibleDigitsWithExponent & digits,UErrorCode & status) const601 DecimalFormatImpl::initVisibleDigitsFromAdjusted(
602         DigitList &number,
603         VisibleDigitsWithExponent &digits,
604         UErrorCode &status) const {
605     if (fUseScientific) {
606         fEffPrecision.initVisibleDigitsWithExponent(
607                 number, digits, status);
608     } else {
609         fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
610                 number, digits, status);
611     }
612     return digits;
613 }
614 
615 DigitList &
round(DigitList & number,UErrorCode & status) const616 DecimalFormatImpl::round(
617         DigitList &number, UErrorCode &status) const {
618     if (number.isNaN() || number.isInfinite()) {
619         return number;
620     }
621     adjustDigitList(number, status);
622     ValueFormatter vf;
623     prepareValueFormatter(vf);
624     return vf.round(number, status);
625 }
626 
627 void
setMinimumSignificantDigits(int32_t newValue)628 DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) {
629     fMinSigDigits = newValue;
630     fUseSigDigits = TRUE; // ticket 9936
631     updatePrecision();
632 }
633 
634 void
setMaximumSignificantDigits(int32_t newValue)635 DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) {
636     fMaxSigDigits = newValue;
637     fUseSigDigits = TRUE; // ticket 9936
638     updatePrecision();
639 }
640 
641 void
setMinMaxSignificantDigits(int32_t min,int32_t max)642 DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) {
643     fMinSigDigits = min;
644     fMaxSigDigits = max;
645     fUseSigDigits = TRUE; // ticket 9936
646     updatePrecision();
647 }
648 
649 void
setScientificNotation(UBool newValue)650 DecimalFormatImpl::setScientificNotation(UBool newValue) {
651     fUseScientific = newValue;
652     updatePrecision();
653 }
654 
655 void
setSignificantDigitsUsed(UBool newValue)656 DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) {
657     fUseSigDigits = newValue;
658     updatePrecision();
659 }
660 
661 void
setGroupingSize(int32_t newValue)662 DecimalFormatImpl::setGroupingSize(int32_t newValue) {
663     fGrouping.fGrouping = newValue;
664     updateGrouping();
665 }
666 
667 void
setSecondaryGroupingSize(int32_t newValue)668 DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) {
669     fGrouping.fGrouping2 = newValue;
670     updateGrouping();
671 }
672 
673 void
setMinimumGroupingDigits(int32_t newValue)674 DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) {
675     fGrouping.fMinGrouping = newValue;
676     updateGrouping();
677 }
678 
679 void
setCurrencyUsage(UCurrencyUsage currencyUsage,UErrorCode & status)680 DecimalFormatImpl::setCurrencyUsage(
681         UCurrencyUsage currencyUsage, UErrorCode &status) {
682     fCurrencyUsage = currencyUsage;
683     updateFormatting(kFormattingCurrency, status);
684 }
685 
686 void
setRoundingIncrement(double d)687 DecimalFormatImpl::setRoundingIncrement(double d) {
688     if (d > 0.0) {
689         fEffPrecision.fMantissa.fRoundingIncrement.set(d);
690     } else {
691         fEffPrecision.fMantissa.fRoundingIncrement.set(0.0);
692     }
693 }
694 
695 double
getRoundingIncrement() const696 DecimalFormatImpl::getRoundingIncrement() const {
697     return fEffPrecision.fMantissa.fRoundingIncrement.getDouble();
698 }
699 
700 int32_t
getMultiplier() const701 DecimalFormatImpl::getMultiplier() const {
702     if (fMultiplier.isZero()) {
703         return 1;
704     }
705     return (int32_t) fMultiplier.getDouble();
706 }
707 
708 void
setMultiplier(int32_t m)709 DecimalFormatImpl::setMultiplier(int32_t m) {
710     if (m == 0 || m == 1) {
711         fMultiplier.set((int32_t)0);
712     } else {
713         fMultiplier.set(m);
714     }
715 }
716 
717 void
setPositivePrefix(const UnicodeString & str)718 DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) {
719     fPositivePrefixPattern.remove();
720     fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
721     UErrorCode status = U_ZERO_ERROR;
722     updateFormatting(kFormattingPosPrefix, status);
723 }
724 
725 void
setPositiveSuffix(const UnicodeString & str)726 DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) {
727     fPositiveSuffixPattern.remove();
728     fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
729     UErrorCode status = U_ZERO_ERROR;
730     updateFormatting(kFormattingPosSuffix, status);
731 }
732 
733 void
setNegativePrefix(const UnicodeString & str)734 DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) {
735     fNegativePrefixPattern.remove();
736     fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
737     UErrorCode status = U_ZERO_ERROR;
738     updateFormatting(kFormattingNegPrefix, status);
739 }
740 
741 void
setNegativeSuffix(const UnicodeString & str)742 DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) {
743     fNegativeSuffixPattern.remove();
744     fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
745     UErrorCode status = U_ZERO_ERROR;
746     updateFormatting(kFormattingNegSuffix, status);
747 }
748 
749 UnicodeString &
getPositivePrefix(UnicodeString & result) const750 DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const {
751     result = fAffixes.fPositivePrefix.getOtherVariant().toString();
752     return result;
753 }
754 
755 UnicodeString &
getPositiveSuffix(UnicodeString & result) const756 DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const {
757     result = fAffixes.fPositiveSuffix.getOtherVariant().toString();
758     return result;
759 }
760 
761 UnicodeString &
getNegativePrefix(UnicodeString & result) const762 DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const {
763     result = fAffixes.fNegativePrefix.getOtherVariant().toString();
764     return result;
765 }
766 
767 UnicodeString &
getNegativeSuffix(UnicodeString & result) const768 DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const {
769     result = fAffixes.fNegativeSuffix.getOtherVariant().toString();
770     return result;
771 }
772 
773 void
adoptDecimalFormatSymbols(DecimalFormatSymbols * symbolsToAdopt)774 DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) {
775     if (symbolsToAdopt == NULL) {
776         return;
777     }
778     delete fSymbols;
779     fSymbols = symbolsToAdopt;
780     UErrorCode status = U_ZERO_ERROR;
781     updateFormatting(kFormattingSymbols, status);
782 }
783 
784 void
applyPatternFavorCurrencyPrecision(const UnicodeString & pattern,UErrorCode & status)785 DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
786         const UnicodeString &pattern, UErrorCode &status) {
787     UParseError perror;
788     applyPattern(pattern, FALSE, perror, status);
789     updateForApplyPatternFavorCurrencyPrecision(status);
790 }
791 
792 void
applyPattern(const UnicodeString & pattern,UErrorCode & status)793 DecimalFormatImpl::applyPattern(
794         const UnicodeString &pattern, UErrorCode &status) {
795     UParseError perror;
796     applyPattern(pattern, FALSE, perror, status);
797     updateForApplyPattern(status);
798 }
799 
800 void
applyPattern(const UnicodeString & pattern,UParseError & perror,UErrorCode & status)801 DecimalFormatImpl::applyPattern(
802         const UnicodeString &pattern,
803         UParseError &perror, UErrorCode &status) {
804     applyPattern(pattern, FALSE, perror, status);
805     updateForApplyPattern(status);
806 }
807 
808 void
applyLocalizedPattern(const UnicodeString & pattern,UErrorCode & status)809 DecimalFormatImpl::applyLocalizedPattern(
810         const UnicodeString &pattern, UErrorCode &status) {
811     UParseError perror;
812     applyPattern(pattern, TRUE, perror, status);
813     updateForApplyPattern(status);
814 }
815 
816 void
applyLocalizedPattern(const UnicodeString & pattern,UParseError & perror,UErrorCode & status)817 DecimalFormatImpl::applyLocalizedPattern(
818         const UnicodeString &pattern,
819         UParseError &perror,  UErrorCode &status) {
820     applyPattern(pattern, TRUE, perror, status);
821     updateForApplyPattern(status);
822 }
823 
824 void
applyPattern(const UnicodeString & pattern,UBool localized,UParseError & perror,UErrorCode & status)825 DecimalFormatImpl::applyPattern(
826         const UnicodeString &pattern,
827         UBool localized, UParseError &perror, UErrorCode &status) {
828     if (U_FAILURE(status)) {
829         return;
830     }
831     DecimalFormatPatternParser patternParser;
832     if (localized) {
833         patternParser.useSymbols(*fSymbols);
834     }
835     DecimalFormatPattern out;
836     patternParser.applyPatternWithoutExpandAffix(
837             pattern, out, perror, status);
838     if (U_FAILURE(status)) {
839         return;
840     }
841     fUseScientific = out.fUseExponentialNotation;
842     fUseSigDigits = out.fUseSignificantDigits;
843     fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits);
844     fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits);
845     fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits);
846     fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits);
847     fMinSigDigits = out.fMinimumSignificantDigits;
848     fMaxSigDigits = out.fMaximumSignificantDigits;
849     fEffPrecision.fMinExponentDigits = out.fMinExponentDigits;
850     fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown;
851     fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed);
852     fGrouping.fGrouping = out.fGroupingSize;
853     fGrouping.fGrouping2 = out.fGroupingSize2;
854     fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown;
855     if (out.fRoundingIncrementUsed) {
856         fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement;
857     } else {
858         fEffPrecision.fMantissa.fRoundingIncrement.clear();
859     }
860     fAffixes.fPadChar = out.fPad;
861     fNegativePrefixPattern = out.fNegPrefixAffix;
862     fNegativeSuffixPattern = out.fNegSuffixAffix;
863     fPositivePrefixPattern = out.fPosPrefixAffix;
864     fPositiveSuffixPattern = out.fPosSuffixAffix;
865 
866     // Work around. Pattern parsing code and DecimalFormat code don't agree
867     // on the definition of field width, so we have to translate from
868     // pattern field width to decimal format field width here.
869     fAffixes.fWidth = out.fFormatWidth == 0 ? 0 :
870             out.fFormatWidth + fPositivePrefixPattern.countChar32()
871             + fPositiveSuffixPattern.countChar32();
872     switch (out.fPadPosition) {
873     case DecimalFormatPattern::kPadBeforePrefix:
874         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix;
875         break;
876     case DecimalFormatPattern::kPadAfterPrefix:
877         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix;
878         break;
879     case DecimalFormatPattern::kPadBeforeSuffix:
880         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix;
881         break;
882     case DecimalFormatPattern::kPadAfterSuffix:
883         fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
884         break;
885     default:
886         break;
887     }
888 }
889 
890 void
updatePrecision()891 DecimalFormatImpl::updatePrecision() {
892     if (fUseScientific) {
893         updatePrecisionForScientific();
894     } else {
895         updatePrecisionForFixed();
896     }
897 }
898 
updatePrecisionForScientificMinMax(const DigitInterval & min,const DigitInterval & max,DigitInterval & resultMin,DigitInterval & resultMax,SignificantDigitInterval & resultSignificant)899 static void updatePrecisionForScientificMinMax(
900         const DigitInterval &min,
901         const DigitInterval &max,
902         DigitInterval &resultMin,
903         DigitInterval &resultMax,
904         SignificantDigitInterval &resultSignificant) {
905     resultMin.setIntDigitCount(0);
906     resultMin.setFracDigitCount(0);
907     resultSignificant.clear();
908     resultMax.clear();
909 
910     int32_t maxIntDigitCount = max.getIntDigitCount();
911     int32_t minIntDigitCount = min.getIntDigitCount();
912     int32_t maxFracDigitCount = max.getFracDigitCount();
913     int32_t minFracDigitCount = min.getFracDigitCount();
914 
915 
916     // Not in spec: maxIntDigitCount > 8 assume
917     // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
918     // no provision for unsetting maxIntDigitCount which would be useful for
919     // scientific notation. The best we can do is assume that if
920     // maxIntDigitCount is the default of 2000000000 or is "big enough" then
921     // user did not intend to explicitly set it. The 8 was derived emperically
922     // by extensive testing of legacy code.
923     if (maxIntDigitCount > 8) {
924         maxIntDigitCount = minIntDigitCount;
925     }
926 
927     // Per the spec, exponent grouping happens if maxIntDigitCount is more
928     // than 1 and more than minIntDigitCount.
929     UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount;
930     if (bExponentGrouping) {
931         resultMax.setIntDigitCount(maxIntDigitCount);
932 
933         // For exponent grouping minIntDigits is always treated as 1 even
934         // if it wasn't set to 1!
935         resultMin.setIntDigitCount(1);
936     } else {
937         // Fixed digit count left of decimal. minIntDigitCount doesn't have
938         // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
939         // maxIntDigitCount == 1.
940         int32_t fixedIntDigitCount = maxIntDigitCount;
941 
942         // If fixedIntDigitCount is 0 but
943         // min or max fraction count is 0 too then use 1. This way we can get
944         // unlimited precision for X.XXXEX
945         if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) {
946             fixedIntDigitCount = 1;
947         }
948         resultMax.setIntDigitCount(fixedIntDigitCount);
949         resultMin.setIntDigitCount(fixedIntDigitCount);
950     }
951     // Spec says this is how we compute significant digits. 0 means
952     // unlimited significant digits.
953     int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount;
954     if (maxSigDigits > 0) {
955         int32_t minSigDigits = minIntDigitCount + minFracDigitCount;
956         resultSignificant.setMin(minSigDigits);
957         resultSignificant.setMax(maxSigDigits);
958     }
959 }
960 
961 void
updatePrecisionForScientific()962 DecimalFormatImpl::updatePrecisionForScientific() {
963     FixedPrecision *result = &fEffPrecision.fMantissa;
964     if (fUseSigDigits) {
965         result->fMax.setFracDigitCount(-1);
966         result->fMax.setIntDigitCount(1);
967         result->fMin.setFracDigitCount(0);
968         result->fMin.setIntDigitCount(1);
969         result->fSignificant.clear();
970         extractSigDigits(result->fSignificant);
971         return;
972     }
973     DigitInterval max;
974     DigitInterval min;
975     extractMinMaxDigits(min, max);
976     updatePrecisionForScientificMinMax(
977             min, max,
978             result->fMin, result->fMax, result->fSignificant);
979 }
980 
981 void
updatePrecisionForFixed()982 DecimalFormatImpl::updatePrecisionForFixed() {
983     FixedPrecision *result = &fEffPrecision.fMantissa;
984     if (!fUseSigDigits) {
985         extractMinMaxDigits(result->fMin, result->fMax);
986         result->fSignificant.clear();
987     } else {
988         extractSigDigits(result->fSignificant);
989         result->fMin.setIntDigitCount(1);
990         result->fMin.setFracDigitCount(0);
991         result->fMax.clear();
992     }
993 }
994 
995 void
extractMinMaxDigits(DigitInterval & min,DigitInterval & max) const996  DecimalFormatImpl::extractMinMaxDigits(
997         DigitInterval &min, DigitInterval &max) const {
998     min.setIntDigitCount(fSuper->getMinimumIntegerDigits());
999     max.setIntDigitCount(fSuper->getMaximumIntegerDigits());
1000     min.setFracDigitCount(fSuper->getMinimumFractionDigits());
1001     max.setFracDigitCount(fSuper->getMaximumFractionDigits());
1002 }
1003 
1004 void
extractSigDigits(SignificantDigitInterval & sig) const1005  DecimalFormatImpl::extractSigDigits(
1006         SignificantDigitInterval &sig) const {
1007     sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits);
1008     sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits);
1009 }
1010 
1011 void
updateGrouping()1012 DecimalFormatImpl::updateGrouping() {
1013     if (fSuper->isGroupingUsed()) {
1014         fEffGrouping = fGrouping;
1015     } else {
1016         fEffGrouping.clear();
1017     }
1018 }
1019 
1020 void
updateCurrency(UErrorCode & status)1021 DecimalFormatImpl::updateCurrency(UErrorCode &status) {
1022     updateFormatting(kFormattingCurrency, TRUE, status);
1023 }
1024 
1025 void
updateFormatting(int32_t changedFormattingFields,UErrorCode & status)1026 DecimalFormatImpl::updateFormatting(
1027         int32_t changedFormattingFields,
1028         UErrorCode &status) {
1029     updateFormatting(changedFormattingFields, TRUE, status);
1030 }
1031 
1032 void
updateFormatting(int32_t changedFormattingFields,UBool updatePrecisionBasedOnCurrency,UErrorCode & status)1033 DecimalFormatImpl::updateFormatting(
1034         int32_t changedFormattingFields,
1035         UBool updatePrecisionBasedOnCurrency,
1036         UErrorCode &status) {
1037     if (U_FAILURE(status)) {
1038         return;
1039     }
1040     // Each function updates one field. Order matters. For instance,
1041     // updatePluralRules comes before updateCurrencyAffixInfo because the
1042     // fRules field is needed to update the fCurrencyAffixInfo field.
1043     updateFormattingUsesCurrency(changedFormattingFields);
1044     updateFormattingFixedPointFormatter(changedFormattingFields);
1045     updateFormattingAffixParser(changedFormattingFields);
1046     updateFormattingPluralRules(changedFormattingFields, status);
1047     updateFormattingCurrencyAffixInfo(
1048             changedFormattingFields,
1049             updatePrecisionBasedOnCurrency,
1050             status);
1051     updateFormattingLocalizedPositivePrefix(
1052             changedFormattingFields, status);
1053     updateFormattingLocalizedPositiveSuffix(
1054             changedFormattingFields, status);
1055     updateFormattingLocalizedNegativePrefix(
1056             changedFormattingFields, status);
1057     updateFormattingLocalizedNegativeSuffix(
1058             changedFormattingFields, status);
1059 }
1060 
1061 void
updateFormattingUsesCurrency(int32_t & changedFormattingFields)1062 DecimalFormatImpl::updateFormattingUsesCurrency(
1063         int32_t &changedFormattingFields) {
1064     if ((changedFormattingFields & kFormattingAffixes) == 0) {
1065         // If no affixes changed, don't need to do any work
1066         return;
1067     }
1068     UBool newUsesCurrency =
1069             fPositivePrefixPattern.usesCurrency() ||
1070             fPositiveSuffixPattern.usesCurrency() ||
1071             fNegativePrefixPattern.usesCurrency() ||
1072             fNegativeSuffixPattern.usesCurrency();
1073     if (fMonetary != newUsesCurrency) {
1074         fMonetary = newUsesCurrency;
1075         changedFormattingFields |= kFormattingUsesCurrency;
1076     }
1077 }
1078 
1079 void
updateFormattingPluralRules(int32_t & changedFormattingFields,UErrorCode & status)1080 DecimalFormatImpl::updateFormattingPluralRules(
1081         int32_t &changedFormattingFields, UErrorCode &status) {
1082     if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
1083         // No work to do if both fSymbols and fMonetary
1084         // fields are unchanged
1085         return;
1086     }
1087     if (U_FAILURE(status)) {
1088         return;
1089     }
1090     PluralRules *newRules = NULL;
1091     if (fMonetary) {
1092         newRules = PluralRules::forLocale(fSymbols->getLocale(), status);
1093         if (U_FAILURE(status)) {
1094             return;
1095         }
1096     }
1097     // Its ok to say a field has changed when it really hasn't but not
1098     // the other way around. Here we assume the field changed unless it
1099     // was NULL before and is still NULL now
1100     if (fRules != newRules) {
1101         delete fRules;
1102         fRules = newRules;
1103         changedFormattingFields |= kFormattingPluralRules;
1104     }
1105 }
1106 
1107 void
updateFormattingCurrencyAffixInfo(int32_t & changedFormattingFields,UBool updatePrecisionBasedOnCurrency,UErrorCode & status)1108 DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
1109         int32_t &changedFormattingFields,
1110         UBool updatePrecisionBasedOnCurrency,
1111         UErrorCode &status) {
1112     if ((changedFormattingFields & (
1113             kFormattingSymbols | kFormattingCurrency |
1114             kFormattingUsesCurrency | kFormattingPluralRules)) == 0) {
1115         // If all these fields are unchanged, no work to do.
1116         return;
1117     }
1118     if (U_FAILURE(status)) {
1119         return;
1120     }
1121     if (!fMonetary) {
1122         if (fCurrencyAffixInfo.isDefault()) {
1123             // In this case don't have to do any work
1124             return;
1125         }
1126         fCurrencyAffixInfo.set(NULL, NULL, NULL, status);
1127         if (U_FAILURE(status)) {
1128             return;
1129         }
1130         changedFormattingFields |= kFormattingCurrencyAffixInfo;
1131     } else {
1132         const UChar *currency = fSuper->getCurrency();
1133         UChar localeCurr[4];
1134         if (currency[0] == 0) {
1135             ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status);
1136             if (U_SUCCESS(status)) {
1137                 currency = localeCurr;
1138                 fSuper->NumberFormat::setCurrency(currency, status);
1139             } else {
1140                 currency = NULL;
1141                 status = U_ZERO_ERROR;
1142             }
1143         }
1144         fCurrencyAffixInfo.set(
1145                 fSymbols->getLocale().getName(), fRules, currency, status);
1146         if (U_FAILURE(status)) {
1147             return;
1148         }
1149         UBool customCurrencySymbol = FALSE;
1150         // If DecimalFormatSymbols has custom currency symbol, prefer
1151         // that over what we just read from the resource bundles
1152         if (fSymbols->isCustomCurrencySymbol()) {
1153             fCurrencyAffixInfo.setSymbol(
1154                     fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
1155             customCurrencySymbol = TRUE;
1156         }
1157         if (fSymbols->isCustomIntlCurrencySymbol()) {
1158             fCurrencyAffixInfo.setISO(
1159                     fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1160             customCurrencySymbol = TRUE;
1161         }
1162         changedFormattingFields |= kFormattingCurrencyAffixInfo;
1163         if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) {
1164             FixedPrecision precision;
1165             CurrencyAffixInfo::adjustPrecision(
1166                     currency, fCurrencyUsage, precision, status);
1167             if (U_FAILURE(status)) {
1168                 return;
1169             }
1170             fSuper->NumberFormat::setMinimumFractionDigits(
1171                     precision.fMin.getFracDigitCount());
1172             fSuper->NumberFormat::setMaximumFractionDigits(
1173                     precision.fMax.getFracDigitCount());
1174             updatePrecision();
1175             fEffPrecision.fMantissa.fRoundingIncrement =
1176                     precision.fRoundingIncrement;
1177         }
1178 
1179     }
1180 }
1181 
1182 void
updateFormattingFixedPointFormatter(int32_t & changedFormattingFields)1183 DecimalFormatImpl::updateFormattingFixedPointFormatter(
1184         int32_t &changedFormattingFields) {
1185     if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
1186         // No work to do if fSymbols is unchanged
1187         return;
1188     }
1189     if (fMonetary) {
1190         fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols);
1191     } else {
1192         fFormatter.setDecimalFormatSymbols(*fSymbols);
1193     }
1194 }
1195 
1196 void
updateFormattingAffixParser(int32_t & changedFormattingFields)1197 DecimalFormatImpl::updateFormattingAffixParser(
1198         int32_t &changedFormattingFields) {
1199     if ((changedFormattingFields & kFormattingSymbols) == 0) {
1200         // No work to do if fSymbols is unchanged
1201         return;
1202     }
1203     fAffixParser.setDecimalFormatSymbols(*fSymbols);
1204     changedFormattingFields |= kFormattingAffixParser;
1205 }
1206 
1207 void
updateFormattingLocalizedPositivePrefix(int32_t & changedFormattingFields,UErrorCode & status)1208 DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
1209         int32_t &changedFormattingFields, UErrorCode &status) {
1210     if (U_FAILURE(status)) {
1211         return;
1212     }
1213     if ((changedFormattingFields & (
1214             kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) {
1215         // No work to do
1216         return;
1217     }
1218     fAffixes.fPositivePrefix.remove();
1219     fAffixParser.parse(
1220             fPositivePrefixPattern,
1221             fCurrencyAffixInfo,
1222             fAffixes.fPositivePrefix,
1223             status);
1224 }
1225 
1226 void
updateFormattingLocalizedPositiveSuffix(int32_t & changedFormattingFields,UErrorCode & status)1227 DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
1228         int32_t &changedFormattingFields, UErrorCode &status) {
1229     if (U_FAILURE(status)) {
1230         return;
1231     }
1232     if ((changedFormattingFields & (
1233             kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) {
1234         // No work to do
1235         return;
1236     }
1237     fAffixes.fPositiveSuffix.remove();
1238     fAffixParser.parse(
1239             fPositiveSuffixPattern,
1240             fCurrencyAffixInfo,
1241             fAffixes.fPositiveSuffix,
1242             status);
1243 }
1244 
1245 void
updateFormattingLocalizedNegativePrefix(int32_t & changedFormattingFields,UErrorCode & status)1246 DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
1247         int32_t &changedFormattingFields, UErrorCode &status) {
1248     if (U_FAILURE(status)) {
1249         return;
1250     }
1251     if ((changedFormattingFields & (
1252             kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) {
1253         // No work to do
1254         return;
1255     }
1256     fAffixes.fNegativePrefix.remove();
1257     fAffixParser.parse(
1258             fNegativePrefixPattern,
1259             fCurrencyAffixInfo,
1260             fAffixes.fNegativePrefix,
1261             status);
1262 }
1263 
1264 void
updateFormattingLocalizedNegativeSuffix(int32_t & changedFormattingFields,UErrorCode & status)1265 DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
1266         int32_t &changedFormattingFields, UErrorCode &status) {
1267     if (U_FAILURE(status)) {
1268         return;
1269     }
1270     if ((changedFormattingFields & (
1271             kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) {
1272         // No work to do
1273         return;
1274     }
1275     fAffixes.fNegativeSuffix.remove();
1276     fAffixParser.parse(
1277             fNegativeSuffixPattern,
1278             fCurrencyAffixInfo,
1279             fAffixes.fNegativeSuffix,
1280             status);
1281 }
1282 
1283 void
updateForApplyPatternFavorCurrencyPrecision(UErrorCode & status)1284 DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
1285         UErrorCode &status) {
1286     updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status);
1287 }
1288 
1289 void
updateForApplyPattern(UErrorCode & status)1290 DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) {
1291     updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status);
1292 }
1293 
1294 void
updateAll(UErrorCode & status)1295 DecimalFormatImpl::updateAll(UErrorCode &status) {
1296     updateAll(kFormattingAll, TRUE, status);
1297 }
1298 
1299 void
updateAll(int32_t formattingFlags,UBool updatePrecisionBasedOnCurrency,UErrorCode & status)1300 DecimalFormatImpl::updateAll(
1301         int32_t formattingFlags,
1302         UBool updatePrecisionBasedOnCurrency,
1303         UErrorCode &status) {
1304     if (U_FAILURE(status)) {
1305         return;
1306     }
1307     updatePrecision();
1308     updateGrouping();
1309     updateFormatting(
1310             formattingFlags, updatePrecisionBasedOnCurrency, status);
1311     setMultiplierScale(getPatternScale());
1312 }
1313 
1314 
1315 static int32_t
getMinimumLengthToDescribeGrouping(const DigitGrouping & grouping)1316 getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) {
1317     if (grouping.fGrouping <= 0) {
1318         return 0;
1319     }
1320     if (grouping.fGrouping2 <= 0) {
1321         return grouping.fGrouping + 1;
1322     }
1323     return grouping.fGrouping + grouping.fGrouping2 + 1;
1324 }
1325 
1326 /**
1327  * Given a grouping policy, calculates how many digits are needed left of
1328  * the decimal point to achieve a desired length left of the
1329  * decimal point.
1330  * @param grouping the grouping policy
1331  * @param desiredLength number of characters needed left of decimal point
1332  * @param minLeftDigits at least this many digits is returned
1333  * @param leftDigits the number of digits needed stored here
1334  *  which is >= minLeftDigits.
1335  * @return true if a perfect fit or false if having leftDigits would exceed
1336  *   desiredLength
1337  */
1338 static UBool
getLeftDigitsForLeftLength(const DigitGrouping & grouping,int32_t desiredLength,int32_t minLeftDigits,int32_t & leftDigits)1339 getLeftDigitsForLeftLength(
1340         const DigitGrouping &grouping,
1341         int32_t desiredLength,
1342         int32_t minLeftDigits,
1343         int32_t &leftDigits) {
1344     leftDigits = minLeftDigits;
1345     int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits);
1346     while (lengthSoFar < desiredLength) {
1347         lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1;
1348         ++leftDigits;
1349     }
1350     return (lengthSoFar == desiredLength);
1351 }
1352 
1353 int32_t
computeExponentPatternLength() const1354 DecimalFormatImpl::computeExponentPatternLength() const {
1355     if (fUseScientific) {
1356         return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits;
1357     }
1358     return 0;
1359 }
1360 
1361 int32_t
countFractionDigitAndDecimalPatternLength(int32_t fracDigitCount) const1362 DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
1363         int32_t fracDigitCount) const {
1364     if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) {
1365         return 0;
1366     }
1367     return fracDigitCount + 1;
1368 }
1369 
1370 UnicodeString&
toNumberPattern(UBool hasPadding,int32_t minimumLength,UnicodeString & result) const1371 DecimalFormatImpl::toNumberPattern(
1372         UBool hasPadding, int32_t minimumLength, UnicodeString& result) const {
1373     // Get a grouping policy like the one in this object that does not
1374     // have minimum grouping since toPattern doesn't support it.
1375     DigitGrouping grouping(fEffGrouping);
1376     grouping.fMinGrouping = 0;
1377 
1378     // Only for fixed digits, these are the digits that get 0's.
1379     DigitInterval minInterval;
1380 
1381     // Only for fixed digits, these are the digits that get #'s.
1382     DigitInterval maxInterval;
1383 
1384     // Only for significant digits
1385     int32_t sigMin;
1386     int32_t sigMax;
1387 
1388     // These are all the digits to be displayed. For significant digits,
1389     // this interval always starts at the 1's place an extends left.
1390     DigitInterval fullInterval;
1391 
1392     // Digit range of rounding increment. If rounding increment is .025.
1393     // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
1394     int32_t roundingIncrementLowerExp = 0;
1395     int32_t roundingIncrementUpperExp = 0;
1396 
1397     if (fUseSigDigits) {
1398         SignificantDigitInterval sigInterval;
1399         extractSigDigits(sigInterval);
1400         sigMax = sigInterval.getMax();
1401         sigMin = sigInterval.getMin();
1402         fullInterval.setFracDigitCount(0);
1403         fullInterval.setIntDigitCount(sigMax);
1404     } else {
1405         extractMinMaxDigits(minInterval, maxInterval);
1406         if (fUseScientific) {
1407            if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) {
1408                maxInterval.setIntDigitCount(1);
1409                minInterval.shrinkToFitWithin(maxInterval);
1410            }
1411         } else if (hasPadding) {
1412             // Make max int digits match min int digits for now, we
1413             // compute necessary padding later.
1414             maxInterval.setIntDigitCount(minInterval.getIntDigitCount());
1415         } else {
1416             // For some reason toPattern adds at least one leading '#'
1417             maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1);
1418         }
1419         if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) {
1420             roundingIncrementLowerExp =
1421                     fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent();
1422             roundingIncrementUpperExp =
1423                     fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent();
1424             // We have to include the rounding increment in what we display
1425             maxInterval.expandToContainDigit(roundingIncrementLowerExp);
1426             maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1);
1427         }
1428         fullInterval = maxInterval;
1429     }
1430     // We have to include enough digits to show grouping strategy
1431     int32_t minLengthToDescribeGrouping =
1432            getMinimumLengthToDescribeGrouping(grouping);
1433     if (minLengthToDescribeGrouping > 0) {
1434         fullInterval.expandToContainDigit(
1435                 getMinimumLengthToDescribeGrouping(grouping) - 1);
1436     }
1437 
1438     // If we have a minimum length, we have to add digits to the left to
1439     // depict padding.
1440     if (hasPadding) {
1441         // For non scientific notation,
1442         //  minimumLengthForMantissa = minimumLength
1443         int32_t minimumLengthForMantissa =
1444                 minimumLength - computeExponentPatternLength();
1445         int32_t mininumLengthForMantissaIntPart =
1446                 minimumLengthForMantissa
1447                 - countFractionDigitAndDecimalPatternLength(
1448                         fullInterval.getFracDigitCount());
1449         // Because of grouping, we may need fewer than expected digits to
1450         // achieve the length we need.
1451         int32_t digitsNeeded;
1452         if (getLeftDigitsForLeftLength(
1453                 grouping,
1454                 mininumLengthForMantissaIntPart,
1455                 fullInterval.getIntDigitCount(),
1456                 digitsNeeded)) {
1457 
1458             // In this case, we achieved the exact length that we want.
1459             fullInterval.setIntDigitCount(digitsNeeded);
1460         } else if (digitsNeeded > fullInterval.getIntDigitCount()) {
1461 
1462             // Having digitsNeeded digits goes over desired length which
1463             // means that to have desired length would mean starting on a
1464             // grouping sepearator e.g ,###,### so add a '#' and use one
1465             // less digit. This trick gives ####,### but that is the best
1466             // we can do.
1467             result.append(kPatternDigit);
1468             fullInterval.setIntDigitCount(digitsNeeded - 1);
1469         }
1470     }
1471     int32_t maxDigitPos = fullInterval.getMostSignificantExclusive();
1472     int32_t minDigitPos = fullInterval.getLeastSignificantInclusive();
1473     for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) {
1474         if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) {
1475             result.append(kPatternDecimalSeparator);
1476         }
1477         if (fUseSigDigits) {
1478             // Use digit symbol
1479             if (i >= sigMax || i < sigMax - sigMin) {
1480                 result.append(kPatternDigit);
1481             } else {
1482                 result.append(kPatternSignificantDigit);
1483             }
1484         } else {
1485             if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) {
1486                 result.append((UChar)(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit));
1487             } else if (minInterval.contains(i)) {
1488                 result.append(kPatternZeroDigit);
1489             } else {
1490                 result.append(kPatternDigit);
1491             }
1492         }
1493         if (grouping.isSeparatorAt(i + 1, i)) {
1494             result.append(kPatternGroupingSeparator);
1495         }
1496         if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) {
1497             result.append(kPatternDecimalSeparator);
1498         }
1499     }
1500     if (fUseScientific) {
1501         result.append(kPatternExponent);
1502         if (fOptions.fExponent.fAlwaysShowSign) {
1503             result.append(kPatternPlus);
1504         }
1505         for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) {
1506             result.append(kPatternZeroDigit);
1507         }
1508     }
1509     return result;
1510 }
1511 
1512 UnicodeString&
toPattern(UnicodeString & result) const1513 DecimalFormatImpl::toPattern(UnicodeString& result) const {
1514     result.remove();
1515     UnicodeString padSpec;
1516     if (fAffixes.fWidth > 0) {
1517         padSpec.append(kPatternPadEscape);
1518         padSpec.append(fAffixes.fPadChar);
1519     }
1520     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
1521         result.append(padSpec);
1522     }
1523     fPositivePrefixPattern.toUserString(result);
1524     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
1525         result.append(padSpec);
1526     }
1527     toNumberPattern(
1528             fAffixes.fWidth > 0,
1529             fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(),
1530             result);
1531     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
1532         result.append(padSpec);
1533     }
1534     fPositiveSuffixPattern.toUserString(result);
1535     if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
1536         result.append(padSpec);
1537     }
1538     AffixPattern withNegative;
1539     withNegative.add(AffixPattern::kNegative);
1540     withNegative.append(fPositivePrefixPattern);
1541     if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) ||
1542             !withNegative.equals(fNegativePrefixPattern)) {
1543         result.append(kPatternSeparator);
1544         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
1545             result.append(padSpec);
1546         }
1547         fNegativePrefixPattern.toUserString(result);
1548         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
1549             result.append(padSpec);
1550         }
1551         toNumberPattern(
1552                 fAffixes.fWidth > 0,
1553                 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(),
1554                 result);
1555         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
1556             result.append(padSpec);
1557         }
1558         fNegativeSuffixPattern.toUserString(result);
1559         if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
1560             result.append(padSpec);
1561         }
1562     }
1563     return result;
1564 }
1565 
1566 int32_t
getOldFormatWidth() const1567 DecimalFormatImpl::getOldFormatWidth() const {
1568     if (fAffixes.fWidth == 0) {
1569         return 0;
1570     }
1571     return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32();
1572 }
1573 
1574 const UnicodeString &
getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const1575 DecimalFormatImpl::getConstSymbol(
1576         DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
1577    return fSymbols->getConstSymbol(symbol);
1578 }
1579 
1580 UBool
isParseFastpath() const1581 DecimalFormatImpl::isParseFastpath() const {
1582     AffixPattern negative;
1583     negative.add(AffixPattern::kNegative);
1584 
1585     return fAffixes.fWidth == 0 &&
1586     fPositivePrefixPattern.countChar32() == 0 &&
1587     fNegativePrefixPattern.equals(negative) &&
1588     fPositiveSuffixPattern.countChar32() == 0 &&
1589     fNegativeSuffixPattern.countChar32() == 0;
1590 }
1591 
1592 
1593 U_NAMESPACE_END
1594 
1595 #endif /* #if !UCONFIG_NO_FORMATTING */
1596 
1597