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