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
26U_NAMESPACE_BEGIN
27
28static const int32_t kMaxScientificIntegerDigits = 8;
29
30static const int32_t kFormattingPosPrefix = (1 << 0);
31static const int32_t kFormattingNegPrefix = (1 << 1);
32static const int32_t kFormattingPosSuffix = (1 << 2);
33static const int32_t kFormattingNegSuffix = (1 << 3);
34static const int32_t kFormattingSymbols = (1 << 4);
35static const int32_t kFormattingCurrency = (1 << 5);
36static const int32_t kFormattingUsesCurrency = (1 << 6);
37static const int32_t kFormattingPluralRules = (1 << 7);
38static const int32_t kFormattingAffixParser = (1 << 8);
39static const int32_t kFormattingCurrencyAffixInfo = (1 << 9);
40static const int32_t kFormattingAll = (1 << 10) - 1;
41static const int32_t kFormattingAffixes =
42        kFormattingPosPrefix | kFormattingPosSuffix |
43        kFormattingNegPrefix | kFormattingNegSuffix;
44static const int32_t kFormattingAffixParserWithCurrency =
45        kFormattingAffixParser | kFormattingCurrencyAffixInfo;
46
47DecimalFormatImpl::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
73DecimalFormatImpl::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
90DecimalFormatImpl::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
129DecimalFormatImpl &
130DecimalFormatImpl::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
173UBool
174DecimalFormatImpl::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
205DecimalFormatImpl::~DecimalFormatImpl() {
206    delete fSymbols;
207    delete fRules;
208}
209
210ValueFormatter &
211DecimalFormatImpl::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
222int32_t
223DecimalFormatImpl::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
241void
242DecimalFormatImpl::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
253UnicodeString &
254DecimalFormatImpl::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
263UnicodeString &
264DecimalFormatImpl::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
273template<class T>
274UBool 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
297template<class T>
298UBool 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
320UnicodeString &
321DecimalFormatImpl::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
339UnicodeString &
340DecimalFormatImpl::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
354UnicodeString &
355DecimalFormatImpl::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
366UnicodeString &
367DecimalFormatImpl::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
376UnicodeString &
377DecimalFormatImpl::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
387UnicodeString &
388DecimalFormatImpl::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
397UnicodeString &
398DecimalFormatImpl::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
407UnicodeString &
408DecimalFormatImpl::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
417UnicodeString &
418DecimalFormatImpl::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
428UnicodeString &
429DecimalFormatImpl::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
440UnicodeString &
441DecimalFormatImpl::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
451UnicodeString &
452DecimalFormatImpl::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
462DigitList &
463DecimalFormatImpl::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
476UnicodeString &
477DecimalFormatImpl::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
488UnicodeString &
489DecimalFormatImpl::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
504UnicodeString &
505DecimalFormatImpl::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
520static 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
533FixedDecimal &
534DecimalFormatImpl::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
543FixedDecimal &
544DecimalFormatImpl::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
554VisibleDigitsWithExponent &
555DecimalFormatImpl::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
573VisibleDigitsWithExponent &
574DecimalFormatImpl::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
592VisibleDigitsWithExponent &
593DecimalFormatImpl::initVisibleDigitsWithExponent(
594        DigitList &number,
595        VisibleDigitsWithExponent &digits,
596        UErrorCode &status) const {
597    adjustDigitList(number, status);
598    return initVisibleDigitsFromAdjusted(number, digits, status);
599}
600
601VisibleDigitsWithExponent &
602DecimalFormatImpl::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
616DigitList &
617DecimalFormatImpl::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
628void
629DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) {
630    fMinSigDigits = newValue;
631    fUseSigDigits = TRUE; // ticket 9936
632    updatePrecision();
633}
634
635void
636DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) {
637    fMaxSigDigits = newValue;
638    fUseSigDigits = TRUE; // ticket 9936
639    updatePrecision();
640}
641
642void
643DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) {
644    fMinSigDigits = min;
645    fMaxSigDigits = max;
646    fUseSigDigits = TRUE; // ticket 9936
647    updatePrecision();
648}
649
650void
651DecimalFormatImpl::setScientificNotation(UBool newValue) {
652    fUseScientific = newValue;
653    updatePrecision();
654}
655
656void
657DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) {
658    fUseSigDigits = newValue;
659    updatePrecision();
660}
661
662void
663DecimalFormatImpl::setGroupingSize(int32_t newValue) {
664    fGrouping.fGrouping = newValue;
665    updateGrouping();
666}
667
668void
669DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) {
670    fGrouping.fGrouping2 = newValue;
671    updateGrouping();
672}
673
674void
675DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) {
676    fGrouping.fMinGrouping = newValue;
677    updateGrouping();
678}
679
680void
681DecimalFormatImpl::setCurrencyUsage(
682        UCurrencyUsage currencyUsage, UErrorCode &status) {
683    fCurrencyUsage = currencyUsage;
684    updateFormatting(kFormattingCurrency, status);
685}
686
687void
688DecimalFormatImpl::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
696double
697DecimalFormatImpl::getRoundingIncrement() const {
698    return fEffPrecision.fMantissa.fRoundingIncrement.getDouble();
699}
700
701int32_t
702DecimalFormatImpl::getMultiplier() const {
703    if (fMultiplier.isZero()) {
704        return 1;
705    }
706    return (int32_t) fMultiplier.getDouble();
707}
708
709void
710DecimalFormatImpl::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
718void
719DecimalFormatImpl::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
726void
727DecimalFormatImpl::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
734void
735DecimalFormatImpl::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
742void
743DecimalFormatImpl::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
750UnicodeString &
751DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const {
752    result = fAffixes.fPositivePrefix.getOtherVariant().toString();
753    return result;
754}
755
756UnicodeString &
757DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const {
758    result = fAffixes.fPositiveSuffix.getOtherVariant().toString();
759    return result;
760}
761
762UnicodeString &
763DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const {
764    result = fAffixes.fNegativePrefix.getOtherVariant().toString();
765    return result;
766}
767
768UnicodeString &
769DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const {
770    result = fAffixes.fNegativeSuffix.getOtherVariant().toString();
771    return result;
772}
773
774void
775DecimalFormatImpl::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
785void
786DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
787        const UnicodeString &pattern, UErrorCode &status) {
788    UParseError perror;
789    applyPattern(pattern, FALSE, perror, status);
790    updateForApplyPatternFavorCurrencyPrecision(status);
791}
792
793void
794DecimalFormatImpl::applyPattern(
795        const UnicodeString &pattern, UErrorCode &status) {
796    UParseError perror;
797    applyPattern(pattern, FALSE, perror, status);
798    updateForApplyPattern(status);
799}
800
801void
802DecimalFormatImpl::applyPattern(
803        const UnicodeString &pattern,
804        UParseError &perror, UErrorCode &status) {
805    applyPattern(pattern, FALSE, perror, status);
806    updateForApplyPattern(status);
807}
808
809void
810DecimalFormatImpl::applyLocalizedPattern(
811        const UnicodeString &pattern, UErrorCode &status) {
812    UParseError perror;
813    applyPattern(pattern, TRUE, perror, status);
814    updateForApplyPattern(status);
815}
816
817void
818DecimalFormatImpl::applyLocalizedPattern(
819        const UnicodeString &pattern,
820        UParseError &perror,  UErrorCode &status) {
821    applyPattern(pattern, TRUE, perror, status);
822    updateForApplyPattern(status);
823}
824
825void
826DecimalFormatImpl::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
891void
892DecimalFormatImpl::updatePrecision() {
893    if (fUseScientific) {
894        updatePrecisionForScientific();
895    } else {
896        updatePrecisionForFixed();
897    }
898}
899
900static 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
962void
963DecimalFormatImpl::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
982void
983DecimalFormatImpl::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
996void
997 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
1005void
1006 DecimalFormatImpl::extractSigDigits(
1007        SignificantDigitInterval &sig) const {
1008    sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits);
1009    sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits);
1010}
1011
1012void
1013DecimalFormatImpl::updateGrouping() {
1014    if (fSuper->isGroupingUsed()) {
1015        fEffGrouping = fGrouping;
1016    } else {
1017        fEffGrouping.clear();
1018    }
1019}
1020
1021void
1022DecimalFormatImpl::updateCurrency(UErrorCode &status) {
1023    updateFormatting(kFormattingCurrency, TRUE, status);
1024}
1025
1026void
1027DecimalFormatImpl::updateFormatting(
1028        int32_t changedFormattingFields,
1029        UErrorCode &status) {
1030    updateFormatting(changedFormattingFields, TRUE, status);
1031}
1032
1033void
1034DecimalFormatImpl::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
1062void
1063DecimalFormatImpl::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
1080void
1081DecimalFormatImpl::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
1108void
1109DecimalFormatImpl::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
1183void
1184DecimalFormatImpl::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
1197void
1198DecimalFormatImpl::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
1208void
1209DecimalFormatImpl::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
1227void
1228DecimalFormatImpl::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
1246void
1247DecimalFormatImpl::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
1265void
1266DecimalFormatImpl::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
1284void
1285DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
1286        UErrorCode &status) {
1287    updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status);
1288}
1289
1290void
1291DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) {
1292    updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status);
1293}
1294
1295void
1296DecimalFormatImpl::updateAll(UErrorCode &status) {
1297    updateAll(kFormattingAll, TRUE, status);
1298}
1299
1300void
1301DecimalFormatImpl::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
1316static int32_t
1317getMinimumLengthToDescribeGrouping(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 */
1339static UBool
1340getLeftDigitsForLeftLength(
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
1354int32_t
1355DecimalFormatImpl::computeExponentPatternLength() const {
1356    if (fUseScientific) {
1357        return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits;
1358    }
1359    return 0;
1360}
1361
1362int32_t
1363DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
1364        int32_t fracDigitCount) const {
1365    if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) {
1366        return 0;
1367    }
1368    return fracDigitCount + 1;
1369}
1370
1371UnicodeString&
1372DecimalFormatImpl::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
1513UnicodeString&
1514DecimalFormatImpl::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
1567int32_t
1568DecimalFormatImpl::getOldFormatWidth() const {
1569    if (fAffixes.fWidth == 0) {
1570        return 0;
1571    }
1572    return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32();
1573}
1574
1575const UnicodeString &
1576DecimalFormatImpl::getConstSymbol(
1577        DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
1578   return fSymbols->getConstSymbol(symbol);
1579}
1580
1581UBool
1582DecimalFormatImpl::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
1594U_NAMESPACE_END
1595
1596#endif /* #if !UCONFIG_NO_FORMATTING */
1597
1598