decimfmt.cpp revision b13da9df870a61b11249bf741347908dbea0edd8
1/*
2*******************************************************************************
3* Copyright (C) 1997-2007, International Business Machines Corporation and    *
4* others. All Rights Reserved.                                                *
5*******************************************************************************
6*
7* File DECIMFMT.CPP
8*
9* Modification History:
10*
11*   Date        Name        Description
12*   02/19/97    aliu        Converted from java.
13*   03/20/97    clhuang     Implemented with new APIs.
14*   03/31/97    aliu        Moved isLONG_MIN to DigitList, and fixed it.
15*   04/3/97     aliu        Rewrote parsing and formatting completely, and
16*                           cleaned up and debugged.  Actually works now.
17*                           Implemented NAN and INF handling, for both parsing
18*                           and formatting.  Extensive testing & debugging.
19*   04/10/97    aliu        Modified to compile on AIX.
20*   04/16/97    aliu        Rewrote to use DigitList, which has been resurrected.
21*                           Changed DigitCount to int per code review.
22*   07/09/97    helena      Made ParsePosition into a class.
23*   08/26/97    aliu        Extensive changes to applyPattern; completely
24*                           rewritten from the Java.
25*   09/09/97    aliu        Ported over support for exponential formats.
26*   07/20/98    stephen     JDK 1.2 sync up.
27*                             Various instances of '0' replaced with 'NULL'
28*                             Check for grouping size in subFormat()
29*                             Brought subParse() in line with Java 1.2
30*                             Added method appendAffix()
31*   08/24/1998  srl         Removed Mutex calls. This is not a thread safe class!
32*   02/22/99    stephen     Removed character literals for EBCDIC safety
33*   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
34*   06/28/99    stephen     Fixed bugs in toPattern().
35*   06/29/99    stephen     Fixed operator= to copy fFormatWidth, fPad,
36*                             fPadPosition
37********************************************************************************
38*/
39
40#include "unicode/utypes.h"
41
42#if !UCONFIG_NO_FORMATTING
43
44#include "unicode/decimfmt.h"
45#include "unicode/choicfmt.h"
46#include "unicode/ucurr.h"
47#include "unicode/ustring.h"
48#include "unicode/dcfmtsym.h"
49#include "unicode/ures.h"
50#include "unicode/uchar.h"
51#include "unicode/curramt.h"
52#include "ucurrimp.h"
53#include "util.h"
54#include "digitlst.h"
55#include "cmemory.h"
56#include "cstring.h"
57#include "umutex.h"
58#include "uassert.h"
59#include "putilimp.h"
60
61U_NAMESPACE_BEGIN
62
63//#define FMT_DEBUG
64
65#ifdef FMT_DEBUG
66#include <stdio.h>
67static void debugout(UnicodeString s) {
68    char buf[2000];
69    s.extract((int32_t) 0, s.length(), buf);
70    printf("%s", buf);
71}
72#define debug(x) printf("%s", x);
73#else
74#define debugout(x)
75#define debug(x)
76#endif
77
78// *****************************************************************************
79// class DecimalFormat
80// *****************************************************************************
81
82UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
83
84// Constants for characters used in programmatic (unlocalized) patterns.
85#define kPatternZeroDigit            ((UChar)0x0030) /*'0'*/
86#define kPatternSignificantDigit     ((UChar)0x0040) /*'@'*/
87#define kPatternGroupingSeparator    ((UChar)0x002C) /*','*/
88#define kPatternDecimalSeparator     ((UChar)0x002E) /*'.'*/
89#define kPatternPerMill              ((UChar)0x2030)
90#define kPatternPercent              ((UChar)0x0025) /*'%'*/
91#define kPatternDigit                ((UChar)0x0023) /*'#'*/
92#define kPatternSeparator            ((UChar)0x003B) /*';'*/
93#define kPatternExponent             ((UChar)0x0045) /*'E'*/
94#define kPatternPlus                 ((UChar)0x002B) /*'+'*/
95#define kPatternMinus                ((UChar)0x002D) /*'-'*/
96#define kPatternPadEscape            ((UChar)0x002A) /*'*'*/
97#define kQuote                       ((UChar)0x0027) /*'\''*/
98/**
99 * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
100 * is used in patterns and substitued with either the currency symbol,
101 * or if it is doubled, with the international currency symbol.  If the
102 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
103 * replaced with the monetary decimal separator.
104 */
105#define kCurrencySign                ((UChar)0x00A4)
106#define kDefaultPad                  ((UChar)0x0020) /* */
107
108const int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
109const int32_t DecimalFormat::kDoubleFractionDigits = 340;
110
111const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
112
113/**
114 * These are the tags we expect to see in normal resource bundle files associated
115 * with a locale.
116 */
117const char DecimalFormat::fgNumberPatterns[]="NumberPatterns";
118
119inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
120inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
121
122//------------------------------------------------------------------------------
123// Constructs a DecimalFormat instance in the default locale.
124
125DecimalFormat::DecimalFormat(UErrorCode& status)
126: NumberFormat(),
127  fPosPrefixPattern(0),
128  fPosSuffixPattern(0),
129  fNegPrefixPattern(0),
130  fNegSuffixPattern(0),
131  fCurrencyChoice(0),
132  fMultiplier(0),
133  fGroupingSize(0),
134  fGroupingSize2(0),
135  fSymbols(0),
136  fUseSignificantDigits(FALSE),
137  fMinSignificantDigits(1),
138  fMaxSignificantDigits(6),
139  fMinExponentDigits(0),
140  fRoundingIncrement(0),
141  fPad(0),
142  fFormatWidth(0)
143{
144    UParseError parseError;
145    construct(status, parseError);
146}
147
148//------------------------------------------------------------------------------
149// Constructs a DecimalFormat instance with the specified number format
150// pattern in the default locale.
151
152DecimalFormat::DecimalFormat(const UnicodeString& pattern,
153                             UErrorCode& status)
154: NumberFormat(),
155  fPosPrefixPattern(0),
156  fPosSuffixPattern(0),
157  fNegPrefixPattern(0),
158  fNegSuffixPattern(0),
159  fCurrencyChoice(0),
160  fMultiplier(0),
161  fGroupingSize(0),
162  fGroupingSize2(0),
163  fSymbols(0),
164  fUseSignificantDigits(FALSE),
165  fMinSignificantDigits(1),
166  fMaxSignificantDigits(6),
167  fMinExponentDigits(0),
168  fRoundingIncrement(0),
169  fPad(0),
170  fFormatWidth(0)
171{
172    UParseError parseError;
173    construct(status, parseError, &pattern);
174}
175
176//------------------------------------------------------------------------------
177// Constructs a DecimalFormat instance with the specified number format
178// pattern and the number format symbols in the default locale.  The
179// created instance owns the symbols.
180
181DecimalFormat::DecimalFormat(const UnicodeString& pattern,
182                             DecimalFormatSymbols* symbolsToAdopt,
183                             UErrorCode& status)
184: NumberFormat(),
185  fPosPrefixPattern(0),
186  fPosSuffixPattern(0),
187  fNegPrefixPattern(0),
188  fNegSuffixPattern(0),
189  fCurrencyChoice(0),
190  fMultiplier(0),
191  fGroupingSize(0),
192  fGroupingSize2(0),
193  fSymbols(0),
194  fUseSignificantDigits(FALSE),
195  fMinSignificantDigits(1),
196  fMaxSignificantDigits(6),
197  fMinExponentDigits(0),
198  fRoundingIncrement(0),
199  fPad(0),
200  fFormatWidth(0)
201{
202    UParseError parseError;
203    if (symbolsToAdopt == NULL)
204        status = U_ILLEGAL_ARGUMENT_ERROR;
205    construct(status, parseError, &pattern, symbolsToAdopt);
206}
207
208DecimalFormat::DecimalFormat(  const UnicodeString& pattern,
209                    DecimalFormatSymbols* symbolsToAdopt,
210                    UParseError& parseErr,
211                    UErrorCode& status)
212: NumberFormat(),
213  fPosPrefixPattern(0),
214  fPosSuffixPattern(0),
215  fNegPrefixPattern(0),
216  fNegSuffixPattern(0),
217  fCurrencyChoice(0),
218  fMultiplier(0),
219  fGroupingSize(0),
220  fGroupingSize2(0),
221  fSymbols(0),
222  fUseSignificantDigits(FALSE),
223  fMinSignificantDigits(1),
224  fMaxSignificantDigits(6),
225  fMinExponentDigits(0),
226  fRoundingIncrement(0),
227  fPad(0),
228  fFormatWidth(0)
229{
230    if (symbolsToAdopt == NULL)
231        status = U_ILLEGAL_ARGUMENT_ERROR;
232    construct(status,parseErr, &pattern, symbolsToAdopt);
233}
234//------------------------------------------------------------------------------
235// Constructs a DecimalFormat instance with the specified number format
236// pattern and the number format symbols in the default locale.  The
237// created instance owns the clone of the symbols.
238
239DecimalFormat::DecimalFormat(const UnicodeString& pattern,
240                             const DecimalFormatSymbols& symbols,
241                             UErrorCode& status)
242: NumberFormat(),
243  fPosPrefixPattern(0),
244  fPosSuffixPattern(0),
245  fNegPrefixPattern(0),
246  fNegSuffixPattern(0),
247  fCurrencyChoice(0),
248  fMultiplier(0),
249  fGroupingSize(0),
250  fGroupingSize2(0),
251  fSymbols(0),
252  fUseSignificantDigits(FALSE),
253  fMinSignificantDigits(1),
254  fMaxSignificantDigits(6),
255  fMinExponentDigits(0),
256  fRoundingIncrement(0),
257  fPad(0),
258  fFormatWidth(0)
259{
260    UParseError parseError;
261    construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
262}
263
264//------------------------------------------------------------------------------
265// Constructs a DecimalFormat instance with the specified number format
266// pattern and the number format symbols in the desired locale.  The
267// created instance owns the symbols.
268
269void
270DecimalFormat::construct(UErrorCode&             status,
271                         UParseError&           parseErr,
272                         const UnicodeString*   pattern,
273                         DecimalFormatSymbols*  symbolsToAdopt)
274{
275    fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!!
276//    fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!!
277    fRoundingIncrement = NULL;
278    fRoundingDouble = 0.0;
279    fRoundingMode = kRoundHalfEven;
280    fPad = kPatternPadEscape;
281    fPadPosition = kPadBeforePrefix;
282    if (U_FAILURE(status))
283        return;
284
285    fPosPrefixPattern = fPosSuffixPattern = NULL;
286    fNegPrefixPattern = fNegSuffixPattern = NULL;
287    fMultiplier = 1;
288    fGroupingSize = 3;
289    fGroupingSize2 = 0;
290    fDecimalSeparatorAlwaysShown = FALSE;
291    fIsCurrencyFormat = FALSE;
292    fUseExponentialNotation = FALSE;
293    fMinExponentDigits = 0;
294
295    if (fSymbols == NULL)
296    {
297        fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status);
298        /* test for NULL */
299        if (fSymbols == 0) {
300            status = U_MEMORY_ALLOCATION_ERROR;
301            return;
302        }
303    }
304
305    UnicodeString str;
306    // Uses the default locale's number format pattern if there isn't
307    // one specified.
308    if (pattern == NULL)
309    {
310        int32_t len = 0;
311        UResourceBundle *resource = ures_open(NULL, Locale::getDefault().getName(), &status);
312
313        resource = ures_getByKey(resource, fgNumberPatterns, resource, &status);
314        const UChar *resStr = ures_getStringByIndex(resource, (int32_t)0, &len, &status);
315        str.setTo(TRUE, resStr, len);
316        pattern = &str;
317        ures_close(resource);
318    }
319
320    if (U_FAILURE(status))
321    {
322        return;
323    }
324
325    if (pattern->indexOf((UChar)kCurrencySign) >= 0) {
326        // If it looks like we are going to use a currency pattern
327        // then do the time consuming lookup.
328        setCurrencyForSymbols();
329    } else {
330        setCurrency(NULL, status);
331    }
332
333    applyPattern(*pattern, FALSE /*not localized*/,parseErr, status);
334
335    // If it was a currency format, apply the appropriate rounding by
336    // resetting the currency. NOTE: this copies fCurrency on top of itself.
337    if (fIsCurrencyFormat) {
338        setCurrency(getCurrency(), status);
339    }
340}
341
342//------------------------------------------------------------------------------
343
344DecimalFormat::~DecimalFormat()
345{
346//    delete fDigitList;
347    delete fPosPrefixPattern;
348    delete fPosSuffixPattern;
349    delete fNegPrefixPattern;
350    delete fNegSuffixPattern;
351    delete fCurrencyChoice;
352    delete fSymbols;
353    delete fRoundingIncrement;
354}
355
356//------------------------------------------------------------------------------
357// copy constructor
358
359DecimalFormat::DecimalFormat(const DecimalFormat &source)
360:   NumberFormat(source),
361//    fDigitList(NULL),
362    fPosPrefixPattern(NULL),
363    fPosSuffixPattern(NULL),
364    fNegPrefixPattern(NULL),
365    fNegSuffixPattern(NULL),
366    fCurrencyChoice(NULL),
367    fSymbols(NULL),
368    fRoundingIncrement(NULL)
369{
370    *this = source;
371}
372
373//------------------------------------------------------------------------------
374// assignment operator
375// Note that fDigitList is not considered a significant part of the
376// DecimalFormat because it's used as a buffer to process the numbers.
377
378static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) {
379    if (source == NULL) {
380        delete *pdest;
381        *pdest = NULL;
382    } else if (*pdest == NULL) {
383        *pdest = new UnicodeString(*source);
384    } else {
385        **pdest  = *source;
386    }
387}
388
389DecimalFormat&
390DecimalFormat::operator=(const DecimalFormat& rhs)
391{
392    if(this != &rhs) {
393        NumberFormat::operator=(rhs);
394        fPositivePrefix = rhs.fPositivePrefix;
395        fPositiveSuffix = rhs.fPositiveSuffix;
396        fNegativePrefix = rhs.fNegativePrefix;
397        fNegativeSuffix = rhs.fNegativeSuffix;
398        _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
399        _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
400        _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
401        _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
402        if (rhs.fCurrencyChoice == 0) {
403            delete fCurrencyChoice;
404            fCurrencyChoice = 0;
405        } else {
406            fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone();
407        }
408        if(rhs.fRoundingIncrement == NULL) {
409            delete fRoundingIncrement;
410            fRoundingIncrement = NULL;
411        }
412        else if(fRoundingIncrement == NULL) {
413            fRoundingIncrement = new DigitList(*rhs.fRoundingIncrement);
414        }
415        else {
416            *fRoundingIncrement = *rhs.fRoundingIncrement;
417        }
418        fRoundingDouble = rhs.fRoundingDouble;
419        fRoundingMode = rhs.fRoundingMode;
420        fMultiplier = rhs.fMultiplier;
421        fGroupingSize = rhs.fGroupingSize;
422        fGroupingSize2 = rhs.fGroupingSize2;
423        fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
424        if(fSymbols == NULL) {
425            fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
426        } else {
427            *fSymbols = *rhs.fSymbols;
428        }
429        fUseExponentialNotation = rhs.fUseExponentialNotation;
430        fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
431        /*Bertrand A. D. Update 98.03.17*/
432        fIsCurrencyFormat = rhs.fIsCurrencyFormat;
433        /*end of Update*/
434        fMinExponentDigits = rhs.fMinExponentDigits;
435        //    if (fDigitList == NULL)
436        //        fDigitList = new DigitList();
437
438        /* sfb 990629 */
439        fFormatWidth = rhs.fFormatWidth;
440        fPad = rhs.fPad;
441        fPadPosition = rhs.fPadPosition;
442        /* end sfb */
443        fMinSignificantDigits = rhs.fMinSignificantDigits;
444        fMaxSignificantDigits = rhs.fMaxSignificantDigits;
445        fUseSignificantDigits = rhs.fUseSignificantDigits;
446    }
447    return *this;
448}
449
450//------------------------------------------------------------------------------
451
452UBool
453DecimalFormat::operator==(const Format& that) const
454{
455    if (this == &that)
456        return TRUE;
457
458    // NumberFormat::operator== guarantees this cast is safe
459    const DecimalFormat* other = (DecimalFormat*)&that;
460
461#ifdef FMT_DEBUG
462    // This code makes it easy to determine why two format objects that should
463    // be equal aren't.
464    UBool first = TRUE;
465    if (!NumberFormat::operator==(that)) {
466        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
467        debug("NumberFormat::!=");
468    }
469    if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null
470              fPositivePrefix == other->fPositivePrefix)
471           || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
472               *fPosPrefixPattern  == *other->fPosPrefixPattern))) {
473        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
474        debug("Pos Prefix !=");
475    }
476    if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null
477           fPositiveSuffix == other->fPositiveSuffix)
478          || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
479              *fPosSuffixPattern  == *other->fPosSuffixPattern))) {
480        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
481        debug("Pos Suffix !=");
482    }
483    if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null
484           fNegativePrefix == other->fNegativePrefix)
485          || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
486              *fNegPrefixPattern  == *other->fNegPrefixPattern))) {
487        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
488        debug("Neg Prefix ");
489        if (fNegPrefixPattern == NULL) {
490            debug("NULL(");
491            debugout(fNegativePrefix);
492            debug(")");
493        } else {
494            debugout(*fNegPrefixPattern);
495        }
496        debug(" != ");
497        if (other->fNegPrefixPattern == NULL) {
498            debug("NULL(");
499            debugout(other->fNegativePrefix);
500            debug(")");
501        } else {
502            debugout(*other->fNegPrefixPattern);
503        }
504    }
505    if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null
506           fNegativeSuffix == other->fNegativeSuffix)
507          || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
508              *fNegSuffixPattern  == *other->fNegSuffixPattern))) {
509        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
510        debug("Neg Suffix ");
511        if (fNegSuffixPattern == NULL) {
512            debug("NULL(");
513            debugout(fNegativeSuffix);
514            debug(")");
515        } else {
516            debugout(*fNegSuffixPattern);
517        }
518        debug(" != ");
519        if (other->fNegSuffixPattern == NULL) {
520            debug("NULL(");
521            debugout(other->fNegativeSuffix);
522            debug(")");
523        } else {
524            debugout(*other->fNegSuffixPattern);
525        }
526    }
527    if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
528          || (fRoundingIncrement != NULL &&
529              other->fRoundingIncrement != NULL &&
530              *fRoundingIncrement == *other->fRoundingIncrement))) {
531        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
532        debug("Rounding Increment !=");
533              }
534    if (fMultiplier != other->fMultiplier) {
535        if (first) { printf("[ "); first = FALSE; }
536        printf("Multiplier %ld != %ld", fMultiplier, other->fMultiplier);
537    }
538    if (fGroupingSize != other->fGroupingSize) {
539        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
540        printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
541    }
542    if (fGroupingSize2 != other->fGroupingSize2) {
543        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
544        printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2);
545    }
546    if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
547        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
548        printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown);
549    }
550    if (fUseExponentialNotation != other->fUseExponentialNotation) {
551        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
552        debug("Use Exp !=");
553    }
554    if (!(!fUseExponentialNotation ||
555          fMinExponentDigits != other->fMinExponentDigits)) {
556        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
557        debug("Exp Digits !=");
558    }
559    if (*fSymbols != *(other->fSymbols)) {
560        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
561        debug("Symbols !=");
562    }
563    // TODO Add debug stuff for significant digits here
564    if (!first) { printf(" ]"); }
565#endif
566
567    return (NumberFormat::operator==(that) &&
568            ((fPosPrefixPattern == other->fPosPrefixPattern && // both null
569              fPositivePrefix == other->fPositivePrefix)
570             || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
571                 *fPosPrefixPattern  == *other->fPosPrefixPattern)) &&
572            ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
573              fPositiveSuffix == other->fPositiveSuffix)
574             || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
575                 *fPosSuffixPattern  == *other->fPosSuffixPattern)) &&
576            ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
577              fNegativePrefix == other->fNegativePrefix)
578             || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
579                 *fNegPrefixPattern  == *other->fNegPrefixPattern)) &&
580            ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
581              fNegativeSuffix == other->fNegativeSuffix)
582             || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
583                 *fNegSuffixPattern  == *other->fNegSuffixPattern)) &&
584            ((fRoundingIncrement == other->fRoundingIncrement) // both null
585             || (fRoundingIncrement != NULL &&
586                 other->fRoundingIncrement != NULL &&
587                 *fRoundingIncrement == *other->fRoundingIncrement)) &&
588        fMultiplier == other->fMultiplier &&
589        fGroupingSize == other->fGroupingSize &&
590        fGroupingSize2 == other->fGroupingSize2 &&
591        fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
592        fUseExponentialNotation == other->fUseExponentialNotation &&
593        (!fUseExponentialNotation ||
594         fMinExponentDigits == other->fMinExponentDigits) &&
595        *fSymbols == *(other->fSymbols) &&
596        fUseSignificantDigits == other->fUseSignificantDigits &&
597        (!fUseSignificantDigits ||
598         (fMinSignificantDigits == other->fMinSignificantDigits &&
599          fMaxSignificantDigits == other->fMaxSignificantDigits)));
600}
601
602//------------------------------------------------------------------------------
603
604Format*
605DecimalFormat::clone() const
606{
607    return new DecimalFormat(*this);
608}
609
610//------------------------------------------------------------------------------
611
612UnicodeString&
613DecimalFormat::format(int32_t number,
614                      UnicodeString& appendTo,
615                      FieldPosition& fieldPosition) const
616{
617    return format((int64_t)number, appendTo, fieldPosition);
618}
619
620//------------------------------------------------------------------------------
621
622UnicodeString&
623DecimalFormat::format(int64_t number,
624                      UnicodeString& appendTo,
625                      FieldPosition& fieldPosition) const
626{
627    DigitList digits;
628
629    // Clears field positions.
630    fieldPosition.setBeginIndex(0);
631    fieldPosition.setEndIndex(0);
632
633    // If we are to do rounding, we need to move into the BigDecimal
634    // domain in order to do divide/multiply correctly.
635    // ||
636    // In general, long values always represent real finite numbers, so
637    // we don't have to check for +/- Infinity or NaN.  However, there
638    // is one case we have to be careful of:  The multiplier can push
639    // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
640    // check for this before multiplying, and if it happens we use doubles
641    // instead, trading off accuracy for range.
642    if (fRoundingIncrement != NULL
643        || (fMultiplier != 0 && (number > (U_INT64_MAX / fMultiplier)
644                              || number < (U_INT64_MIN / fMultiplier))))
645    {
646        digits.set(((double)number) * fMultiplier,
647                   precision(FALSE),
648                   !fUseExponentialNotation && !areSignificantDigitsUsed());
649    }
650    else
651    {
652        digits.set(number * fMultiplier, precision(TRUE));
653    }
654
655    return subformat(appendTo, fieldPosition, digits, TRUE);
656}
657
658//------------------------------------------------------------------------------
659
660UnicodeString&
661DecimalFormat::format(  double number,
662                        UnicodeString& appendTo,
663                        FieldPosition& fieldPosition) const
664{
665    // Clears field positions.
666    fieldPosition.setBeginIndex(0);
667    fieldPosition.setEndIndex(0);
668
669    // Special case for NaN, sets the begin and end index to be the
670    // the string length of localized name of NaN.
671    if (uprv_isNaN(number))
672    {
673        if (fieldPosition.getField() == NumberFormat::kIntegerField)
674            fieldPosition.setBeginIndex(appendTo.length());
675
676        appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
677
678        if (fieldPosition.getField() == NumberFormat::kIntegerField)
679            fieldPosition.setEndIndex(appendTo.length());
680
681        addPadding(appendTo, fieldPosition, 0, 0);
682        return appendTo;
683    }
684
685    /* Detecting whether a double is negative is easy with the exception of
686     * the value -0.0.  This is a double which has a zero mantissa (and
687     * exponent), but a negative sign bit.  It is semantically distinct from
688     * a zero with a positive sign bit, and this distinction is important
689     * to certain kinds of computations.  However, it's a little tricky to
690     * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
691     * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
692     * -Infinity.  Proper detection of -0.0 is needed to deal with the
693     * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
694     */
695    UBool isNegative = uprv_isNegative(number);
696
697    // Do this BEFORE checking to see if value is infinite! Sets the
698    // begin and end index to be length of the string composed of
699    // localized name of Infinite and the positive/negative localized
700    // signs.
701
702    number *= fMultiplier;
703
704    // Apply rounding after multiplier
705    if (fRoundingIncrement != NULL) {
706        if (isNegative)     // For rounding in the correct direction
707            number = -number;
708        number = fRoundingDouble
709            * round(number / fRoundingDouble, fRoundingMode, isNegative);
710        if (isNegative)
711            number = -number;
712    }
713
714    // Special case for INFINITE,
715    if (uprv_isInfinite(number))
716    {
717        int32_t prefixLen = appendAffix(appendTo, number, isNegative, TRUE);
718
719        if (fieldPosition.getField() == NumberFormat::kIntegerField)
720            fieldPosition.setBeginIndex(appendTo.length());
721
722        appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
723
724        if (fieldPosition.getField() == NumberFormat::kIntegerField)
725            fieldPosition.setEndIndex(appendTo.length());
726
727        int32_t suffixLen = appendAffix(appendTo, number, isNegative, FALSE);
728
729        addPadding(appendTo, fieldPosition, prefixLen, suffixLen);
730        return appendTo;
731    }
732
733    DigitList digits;
734
735    // This detects negativity too.
736    if (fRoundingIncrement == NULL) {
737        // If we did not round in binary space, round in decimal space
738        digits.fRoundingMode = fRoundingMode;
739    }
740    digits.set(number, precision(FALSE),
741               !fUseExponentialNotation && !areSignificantDigitsUsed());
742
743    return subformat(appendTo, fieldPosition, digits, FALSE);
744}
745
746/**
747 * Round a double value to the nearest integer according to the
748 * given mode.
749 * @param a the absolute value of the number to be rounded
750 * @param mode a BigDecimal rounding mode
751 * @param isNegative true if the number to be rounded is negative
752 * @return the absolute value of the rounded result
753 */
754double DecimalFormat::round(double a, ERoundingMode mode, UBool isNegative) {
755    switch (mode) {
756    case kRoundCeiling:
757        return isNegative ? uprv_floor(a) : uprv_ceil(a);
758    case kRoundFloor:
759        return isNegative ? uprv_ceil(a) : uprv_floor(a);
760    case kRoundDown:
761        return uprv_floor(a);
762    case kRoundUp:
763        return uprv_ceil(a);
764    case kRoundHalfEven:
765        {
766            double f = uprv_floor(a);
767            if ((a - f) != 0.5) {
768                return uprv_floor(a + 0.5);
769            }
770            double g = f / 2.0;
771            return (g == uprv_floor(g)) ? f : (f + 1.0);
772        }
773    case kRoundHalfDown:
774        return ((a - uprv_floor(a)) <= 0.5) ? uprv_floor(a) : uprv_ceil(a);
775    case kRoundHalfUp:
776        return ((a - uprv_floor(a)) < 0.5) ? uprv_floor(a) : uprv_ceil(a);
777    }
778    return 1.0;
779}
780
781UnicodeString&
782DecimalFormat::format(  const Formattable& obj,
783                        UnicodeString& appendTo,
784                        FieldPosition& fieldPosition,
785                        UErrorCode& status) const
786{
787    return NumberFormat::format(obj, appendTo, fieldPosition, status);
788}
789
790/**
791 * Return true if a grouping separator belongs at the given
792 * position, based on whether grouping is in use and the values of
793 * the primary and secondary grouping interval.
794 * @param pos the number of integer digits to the right of
795 * the current position.  Zero indicates the position after the
796 * rightmost integer digit.
797 * @return true if a grouping character belongs at the current
798 * position.
799 */
800UBool DecimalFormat::isGroupingPosition(int32_t pos) const {
801    UBool result = FALSE;
802    if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) {
803        if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) {
804            result = ((pos - fGroupingSize) % fGroupingSize2) == 0;
805        } else {
806            result = pos % fGroupingSize == 0;
807        }
808    }
809    return result;
810}
811
812//------------------------------------------------------------------------------
813
814/**
815 * Complete the formatting of a finite number.  On entry, the fDigitList must
816 * be filled in with the correct digits.
817 */
818UnicodeString&
819DecimalFormat::subformat(UnicodeString& appendTo,
820                         FieldPosition& fieldPosition,
821                         DigitList&     digits,
822                         UBool         isInteger) const
823{
824    // Gets the localized zero Unicode character.
825    UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
826    int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
827    const UnicodeString *grouping ;
828    if(fIsCurrencyFormat) {
829        grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
830    }else{
831        grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
832    }
833    const UnicodeString *decimal;
834    if(fIsCurrencyFormat) {
835        decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
836    } else {
837        decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
838    }
839    UBool useSigDig = areSignificantDigitsUsed();
840    int32_t maxIntDig = getMaximumIntegerDigits();
841    int32_t minIntDig = getMinimumIntegerDigits();
842
843    /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
844     * format as zero.  This allows sensible computations and preserves
845     * relations such as signum(1/x) = signum(x), where x is +Infinity or
846     * -Infinity.  Prior to this fix, we always formatted zero values as if
847     * they were positive.  Liu 7/6/98.
848     */
849    if (digits.isZero())
850    {
851        digits.fDecimalAt = digits.fCount = 0; // Normalize
852    }
853
854    // Appends the prefix.
855    double doubleValue = digits.getDouble();
856    int32_t prefixLen = appendAffix(appendTo, doubleValue, !digits.fIsPositive, TRUE);
857
858    if (fUseExponentialNotation)
859    {
860        // Record field information for caller.
861        if (fieldPosition.getField() == NumberFormat::kIntegerField)
862        {
863            fieldPosition.setBeginIndex(appendTo.length());
864            fieldPosition.setEndIndex(-1);
865        }
866        else if (fieldPosition.getField() == NumberFormat::kFractionField)
867        {
868            fieldPosition.setBeginIndex(-1);
869        }
870
871        int32_t minFracDig = 0;
872        if (useSigDig) {
873            maxIntDig = minIntDig = 1;
874            minFracDig = getMinimumSignificantDigits() - 1;
875        } else {
876            minFracDig = getMinimumFractionDigits();
877            if (maxIntDig > kMaxScientificIntegerDigits) {
878                maxIntDig = 1;
879                if (maxIntDig < minIntDig) {
880                    maxIntDig = minIntDig;
881                }
882            }
883            if (maxIntDig > minIntDig) {
884                minIntDig = 1;
885            }
886        }
887
888        // Minimum integer digits are handled in exponential format by
889        // adjusting the exponent.  For example, 0.01234 with 3 minimum
890        // integer digits is "123.4E-4".
891
892        // Maximum integer digits are interpreted as indicating the
893        // repeating range.  This is useful for engineering notation, in
894        // which the exponent is restricted to a multiple of 3.  For
895        // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
896        // If maximum integer digits are defined and are larger than
897        // minimum integer digits, then minimum integer digits are
898        // ignored.
899        int32_t exponent = digits.fDecimalAt;
900        if (maxIntDig > 1 && maxIntDig != minIntDig) {
901            // A exponent increment is defined; adjust to it.
902            exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
903                                      : (exponent / maxIntDig) - 1;
904            exponent *= maxIntDig;
905        } else {
906            // No exponent increment is defined; use minimum integer digits.
907            // If none is specified, as in "#E0", generate 1 integer digit.
908            exponent -= (minIntDig > 0 || minFracDig > 0)
909                        ? minIntDig : 1;
910        }
911
912        // We now output a minimum number of digits, and more if there
913        // are more digits, up to the maximum number of digits.  We
914        // place the decimal point after the "integer" digits, which
915        // are the first (decimalAt - exponent) digits.
916        int32_t minimumDigits =  minIntDig + minFracDig;
917        // The number of integer digits is handled specially if the number
918        // is zero, since then there may be no digits.
919        int32_t integerDigits = digits.isZero() ? minIntDig :
920            digits.fDecimalAt - exponent;
921        int32_t totalDigits = digits.fCount;
922        if (minimumDigits > totalDigits)
923            totalDigits = minimumDigits;
924        if (integerDigits > totalDigits)
925            totalDigits = integerDigits;
926
927        // totalDigits records total number of digits needs to be processed
928        int32_t i;
929        for (i=0; i<totalDigits; ++i)
930        {
931            if (i == integerDigits)
932            {
933                // Record field information for caller.
934                if (fieldPosition.getField() == NumberFormat::kIntegerField)
935                    fieldPosition.setEndIndex(appendTo.length());
936
937                appendTo += *decimal;
938
939                // Record field information for caller.
940                if (fieldPosition.getField() == NumberFormat::kFractionField)
941                    fieldPosition.setBeginIndex(appendTo.length());
942            }
943            // Restores the digit character or pads the buffer with zeros.
944            UChar32 c = (UChar32)((i < digits.fCount) ?
945                          (digits.fDigits[i] + zeroDelta) :
946                          zero);
947            appendTo += c;
948        }
949
950        // Record field information
951        if (fieldPosition.getField() == NumberFormat::kIntegerField)
952        {
953            if (fieldPosition.getEndIndex() < 0)
954                fieldPosition.setEndIndex(appendTo.length());
955        }
956        else if (fieldPosition.getField() == NumberFormat::kFractionField)
957        {
958            if (fieldPosition.getBeginIndex() < 0)
959                fieldPosition.setBeginIndex(appendTo.length());
960            fieldPosition.setEndIndex(appendTo.length());
961        }
962
963        // The exponent is output using the pattern-specified minimum
964        // exponent digits.  There is no maximum limit to the exponent
965        // digits, since truncating the exponent would appendTo in an
966        // unacceptable inaccuracy.
967        appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
968
969        // For zero values, we force the exponent to zero.  We
970        // must do this here, and not earlier, because the value
971        // is used to determine integer digit count above.
972        if (digits.isZero())
973            exponent = 0;
974
975        if (exponent < 0) {
976            appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
977        } else if (fExponentSignAlwaysShown) {
978            appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
979        }
980
981        DigitList expDigits;
982        expDigits.set(exponent);
983        {
984            int expDig = fMinExponentDigits;
985            if (fUseExponentialNotation && expDig < 1) {
986                expDig = 1;
987            }
988            for (i=expDigits.fDecimalAt; i<expDig; ++i)
989                appendTo += (zero);
990        }
991        for (i=0; i<expDigits.fDecimalAt; ++i)
992        {
993            UChar32 c = (UChar32)((i < expDigits.fCount) ?
994                          (expDigits.fDigits[i] + zeroDelta) : zero);
995            appendTo += c;
996        }
997    }
998    else  // Not using exponential notation
999    {
1000        // Record field information for caller.
1001        if (fieldPosition.getField() == NumberFormat::kIntegerField)
1002            fieldPosition.setBeginIndex(appendTo.length());
1003
1004        int32_t sigCount = 0;
1005        int32_t minSigDig = getMinimumSignificantDigits();
1006        int32_t maxSigDig = getMaximumSignificantDigits();
1007        if (!useSigDig) {
1008            minSigDig = 0;
1009            maxSigDig = INT32_MAX;
1010        }
1011
1012        // Output the integer portion.  Here 'count' is the total
1013        // number of integer digits we will display, including both
1014        // leading zeros required to satisfy getMinimumIntegerDigits,
1015        // and actual digits present in the number.
1016        int32_t count = useSigDig ?
1017            _max(1, digits.fDecimalAt) : minIntDig;
1018        if (digits.fDecimalAt > 0 && count < digits.fDecimalAt) {
1019            count = digits.fDecimalAt;
1020        }
1021
1022        // Handle the case where getMaximumIntegerDigits() is smaller
1023        // than the real number of integer digits.  If this is so, we
1024        // output the least significant max integer digits.  For example,
1025        // the value 1997 printed with 2 max integer digits is just "97".
1026
1027        int32_t digitIndex = 0; // Index into digitList.fDigits[]
1028        if (count > maxIntDig && maxIntDig >= 0) {
1029            count = maxIntDig;
1030            digitIndex = digits.fDecimalAt - count;
1031        }
1032
1033        int32_t sizeBeforeIntegerPart = appendTo.length();
1034
1035        int32_t i;
1036        for (i=count-1; i>=0; --i)
1037        {
1038            if (i < digits.fDecimalAt && digitIndex < digits.fCount &&
1039                sigCount < maxSigDig) {
1040                // Output a real digit
1041                appendTo += ((UChar32)(digits.fDigits[digitIndex++] + zeroDelta));
1042                ++sigCount;
1043            }
1044            else
1045            {
1046                // Output a zero (leading or trailing)
1047                appendTo += (zero);
1048                if (sigCount > 0) {
1049                    ++sigCount;
1050                }
1051            }
1052
1053            // Output grouping separator if necessary.
1054            if (isGroupingPosition(i)) {
1055                appendTo.append(*grouping);
1056            }
1057        }
1058
1059        // Record field information for caller.
1060        if (fieldPosition.getField() == NumberFormat::kIntegerField)
1061            fieldPosition.setEndIndex(appendTo.length());
1062
1063        // Determine whether or not there are any printable fractional
1064        // digits.  If we've used up the digits we know there aren't.
1065        UBool fractionPresent = (!isInteger && digitIndex < digits.fCount) ||
1066            (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));
1067
1068        // If there is no fraction present, and we haven't printed any
1069        // integer digits, then print a zero.  Otherwise we won't print
1070        // _any_ digits, and we won't be able to parse this string.
1071        if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart)
1072            appendTo += (zero);
1073
1074        // Output the decimal separator if we always do so.
1075        if (fDecimalSeparatorAlwaysShown || fractionPresent)
1076            appendTo += *decimal;
1077
1078        // Record field information for caller.
1079        if (fieldPosition.getField() == NumberFormat::kFractionField)
1080            fieldPosition.setBeginIndex(appendTo.length());
1081
1082        count = useSigDig ? INT32_MAX : getMaximumFractionDigits();
1083        if (useSigDig && (sigCount == maxSigDig ||
1084                          (sigCount >= minSigDig && digitIndex == digits.fCount))) {
1085            count = 0;
1086        }
1087
1088        for (i=0; i < count; ++i) {
1089            // Here is where we escape from the loop.  We escape
1090            // if we've output the maximum fraction digits
1091            // (specified in the for expression above).  We also
1092            // stop when we've output the minimum digits and
1093            // either: we have an integer, so there is no
1094            // fractional stuff to display, or we're out of
1095            // significant digits.
1096            if (!useSigDig && i >= getMinimumFractionDigits() &&
1097                (isInteger || digitIndex >= digits.fCount)) {
1098                break;
1099            }
1100
1101            // Output leading fractional zeros.  These are zeros
1102            // that come after the decimal but before any
1103            // significant digits.  These are only output if
1104            // abs(number being formatted) < 1.0.
1105            if (-1-i > (digits.fDecimalAt-1)) {
1106                appendTo += zero;
1107                continue;
1108            }
1109
1110            // Output a digit, if we have any precision left, or a
1111            // zero if we don't.  We don't want to output noise digits.
1112            if (!isInteger && digitIndex < digits.fCount) {
1113                appendTo += ((UChar32)(digits.fDigits[digitIndex++] + zeroDelta));
1114            } else {
1115                appendTo += zero;
1116            }
1117
1118            // If we reach the maximum number of significant
1119            // digits, or if we output all the real digits and
1120            // reach the minimum, then we are done.
1121            ++sigCount;
1122            if (useSigDig &&
1123                (sigCount == maxSigDig ||
1124                 (digitIndex == digits.fCount && sigCount >= minSigDig))) {
1125                break;
1126            }
1127        }
1128
1129        // Record field information for caller.
1130        if (fieldPosition.getField() == NumberFormat::kFractionField)
1131            fieldPosition.setEndIndex(appendTo.length());
1132    }
1133
1134    int32_t suffixLen = appendAffix(appendTo, doubleValue, !digits.fIsPositive, FALSE);
1135
1136    addPadding(appendTo, fieldPosition, prefixLen, suffixLen);
1137    return appendTo;
1138}
1139
1140/**
1141 * Inserts the character fPad as needed to expand result to fFormatWidth.
1142 * @param result the string to be padded
1143 */
1144void DecimalFormat::addPadding(UnicodeString& appendTo,
1145                               FieldPosition& fieldPosition,
1146                               int32_t prefixLen,
1147                               int32_t suffixLen) const
1148{
1149    if (fFormatWidth > 0) {
1150        int32_t len = fFormatWidth - appendTo.length();
1151        if (len > 0) {
1152            UnicodeString padding;
1153            for (int32_t i=0; i<len; ++i) {
1154                padding += fPad;
1155            }
1156            switch (fPadPosition) {
1157            case kPadAfterPrefix:
1158                appendTo.insert(prefixLen, padding);
1159                break;
1160            case kPadBeforePrefix:
1161                appendTo.insert(0, padding);
1162                break;
1163            case kPadBeforeSuffix:
1164                appendTo.insert(appendTo.length() - suffixLen, padding);
1165                break;
1166            case kPadAfterSuffix:
1167                appendTo += padding;
1168                break;
1169            }
1170            if (fPadPosition == kPadBeforePrefix ||
1171                fPadPosition == kPadAfterPrefix) {
1172                fieldPosition.setBeginIndex(len + fieldPosition.getBeginIndex());
1173                fieldPosition.setEndIndex(len + fieldPosition.getEndIndex());
1174            }
1175        }
1176    }
1177}
1178
1179//------------------------------------------------------------------------------
1180
1181void
1182DecimalFormat::parse(const UnicodeString& text,
1183                     Formattable& result,
1184                     UErrorCode& status) const
1185{
1186    NumberFormat::parse(text, result, status);
1187}
1188
1189void
1190DecimalFormat::parse(const UnicodeString& text,
1191                     Formattable& result,
1192                     ParsePosition& parsePosition) const {
1193    parse(text, result, parsePosition, FALSE);
1194}
1195
1196Formattable& DecimalFormat::parseCurrency(const UnicodeString& text,
1197                                          Formattable& result,
1198                                          ParsePosition& pos) const {
1199    parse(text, result, pos, TRUE);
1200    return result;
1201}
1202
1203/**
1204 * Parses the given text as either a number or a currency amount.
1205 * @param text the string to parse
1206 * @param result output parameter for the result
1207 * @param parsePosition input-output position; on input, the
1208 * position within text to match; must have 0 <= pos.getIndex() <
1209 * text.length(); on output, the position after the last matched
1210 * character. If the parse fails, the position in unchanged upon
1211 * output.
1212 * @param parseCurrency if true, a currency amount is parsed;
1213 * otherwise a Number is parsed
1214 */
1215void DecimalFormat::parse(const UnicodeString& text,
1216                          Formattable& result,
1217                          ParsePosition& parsePosition,
1218                          UBool parseCurrency) const {
1219    int32_t backup;
1220    int32_t i = backup = parsePosition.getIndex();
1221
1222    // Handle NaN as a special case:
1223
1224    // Skip padding characters, if around prefix
1225    if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix ||
1226                             fPadPosition == kPadAfterPrefix)) {
1227        i = skipPadding(text, i);
1228    }
1229    // If the text is composed of the representation of NaN, returns NaN.length
1230    const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1231    int32_t nanLen = (text.compare(i, nan->length(), *nan)
1232                      ? 0 : nan->length());
1233    if (nanLen) {
1234        i += nanLen;
1235        if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix ||
1236                                 fPadPosition == kPadAfterSuffix)) {
1237            i = skipPadding(text, i);
1238        }
1239        parsePosition.setIndex(i);
1240        result.setDouble(uprv_getNaN());
1241        return;
1242    }
1243
1244    // NaN parse failed; start over
1245    i = backup;
1246
1247    // status is used to record whether a number is infinite.
1248    UBool status[fgStatusLength];
1249    UChar curbuf[4];
1250    UChar* currency = parseCurrency ? curbuf : NULL;
1251    DigitList digits;
1252
1253    if (!subparse(text, parsePosition, digits, status, currency)) {
1254        parsePosition.setIndex(backup);
1255        return;
1256    }
1257
1258    // Handle infinity
1259    if (status[fgStatusInfinite]) {
1260        double inf = uprv_getInfinity();
1261        result.setDouble(digits.fIsPositive ? inf : -inf);
1262    }
1263
1264    else {
1265        // Do as much of the multiplier conversion as possible without
1266        // losing accuracy.
1267        int32_t mult = fMultiplier; // Don't modify this.multiplier
1268        while (mult % 10 == 0) {
1269            mult /= 10;
1270            --digits.fDecimalAt;
1271        }
1272
1273        // Handle integral values.  We want to return the most
1274        // parsimonious type that will accommodate all of the result's
1275        // precision.  We therefore only return a long if the result fits
1276        // entirely within a long (taking into account the multiplier) --
1277        // otherwise we fall through and return a double.  When more
1278        // numeric types are supported by Formattable (e.g., 64-bit
1279        // integers, bignums) we will extend this logic to include them.
1280        if (digits.fitsIntoLong(isParseIntegerOnly())) {
1281            int32_t n = digits.getLong();
1282            if (n % mult == 0) {
1283                result.setLong(n / mult);
1284            }
1285            else {  // else handle the remainder
1286                result.setDouble(((double)n) / mult);
1287            }
1288        }
1289        else if (digits.fitsIntoInt64(isParseIntegerOnly())) {
1290            int64_t n = digits.getInt64();
1291            if (n % mult == 0) {
1292                result.setInt64(n / mult);
1293            }
1294            else {  // else handle the remainder
1295                result.setDouble(((double)n) / mult);
1296            }
1297        }
1298        else {
1299            // Handle non-integral or very large values
1300            // Dividing by one is okay and not that costly.
1301            result.setDouble(digits.getDouble() / mult);
1302        }
1303    }
1304
1305    if (parseCurrency) {
1306        UErrorCode ec = U_ZERO_ERROR;
1307        Formattable n(result);
1308        result.adoptObject(new CurrencyAmount(n, curbuf, ec));
1309        U_ASSERT(U_SUCCESS(ec)); // should always succeed
1310    }
1311}
1312
1313
1314/*
1315This is an old implimentation that was preparing for 64-bit numbers in ICU.
1316It is very slow, and 64-bit numbers are not ANSI-C compatible. This code
1317is here if we change our minds.
1318
1319^^^ what is this referring to? remove? ^^^ [alan]
1320*/
1321
1322/**
1323 * Parse the given text into a number.  The text is parsed beginning at
1324 * parsePosition, until an unparseable character is seen.
1325 * @param text the string to parse.
1326 * @param parsePosition The position at which to being parsing.  Upon
1327 * return, the first unparsed character.
1328 * @param digits the DigitList to set to the parsed value.
1329 * @param status output param containing boolean status flags indicating
1330 * whether the value was infinite and whether it was positive.
1331 * @param currency return value for parsed currency, for generic
1332 * currency parsing mode, or NULL for normal parsing. In generic
1333 * currency parsing mode, any currency is parsed, not just the
1334 * currency that this formatter is set to.
1335 */
1336UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePosition,
1337                              DigitList& digits, UBool* status,
1338                              UChar* currency) const
1339{
1340    int32_t position = parsePosition.getIndex();
1341    int32_t oldStart = position;
1342
1343    // Match padding before prefix
1344    if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) {
1345        position = skipPadding(text, position);
1346    }
1347
1348    // Match positive and negative prefixes; prefer longest match.
1349    int32_t posMatch = compareAffix(text, position, FALSE, TRUE, currency);
1350    int32_t negMatch = compareAffix(text, position, TRUE, TRUE, currency);
1351    if (posMatch >= 0 && negMatch >= 0) {
1352        if (posMatch > negMatch) {
1353            negMatch = -1;
1354        } else if (negMatch > posMatch) {
1355            posMatch = -1;
1356        }
1357    }
1358    if (posMatch >= 0) {
1359        position += posMatch;
1360    } else if (negMatch >= 0) {
1361        position += negMatch;
1362    } else {
1363        parsePosition.setErrorIndex(position);
1364        return FALSE;
1365    }
1366
1367    // Match padding before prefix
1368    if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) {
1369        position = skipPadding(text, position);
1370    }
1371
1372    // process digits or Inf, find decimal position
1373    const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
1374    int32_t infLen = (text.compare(position, inf->length(), *inf)
1375        ? 0 : inf->length());
1376    position += infLen; // infLen is non-zero when it does equal to infinity
1377    status[fgStatusInfinite] = (UBool)infLen;
1378    if (!infLen)
1379    {
1380        // We now have a string of digits, possibly with grouping symbols,
1381        // and decimal points.  We want to process these into a DigitList.
1382        // We don't want to put a bunch of leading zeros into the DigitList
1383        // though, so we keep track of the location of the decimal point,
1384        // put only significant digits into the DigitList, and adjust the
1385        // exponent as needed.
1386
1387        digits.fDecimalAt = digits.fCount = 0;
1388        UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
1389
1390        const UnicodeString *decimal;
1391        if(fIsCurrencyFormat) {
1392            decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1393        } else {
1394            decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
1395        }
1396        const UnicodeString *grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
1397        UBool sawDecimal = FALSE;
1398        UBool sawDigit = FALSE;
1399        int32_t backup = -1;
1400        int32_t digit;
1401        int32_t textLength = text.length(); // One less pointer to follow
1402        int32_t groupingLen = grouping->length();
1403        int32_t decimalLen = decimal->length();
1404
1405        // We have to track digitCount ourselves, because digits.fCount will
1406        // pin when the maximum allowable digits is reached.
1407        int32_t digitCount = 0;
1408
1409        for (; position < textLength; )
1410        {
1411            UChar32 ch = text.char32At(position);
1412
1413            /* We recognize all digit ranges, not only the Latin digit range
1414             * '0'..'9'.  We do so by using the Character.digit() method,
1415             * which converts a valid Unicode digit to the range 0..9.
1416             *
1417             * The character 'ch' may be a digit.  If so, place its value
1418             * from 0 to 9 in 'digit'.  First try using the locale digit,
1419             * which may or MAY NOT be a standard Unicode digit range.  If
1420             * this fails, try using the standard Unicode digit ranges by
1421             * calling Character.digit().  If this also fails, digit will
1422             * have a value outside the range 0..9.
1423             */
1424            digit = ch - zero;
1425            if (digit < 0 || digit > 9)
1426            {
1427                digit = u_charDigitValue(ch);
1428            }
1429
1430            if (digit > 0 && digit <= 9)
1431            {
1432                // Cancel out backup setting (see grouping handler below)
1433                backup = -1;
1434
1435                sawDigit = TRUE;
1436                // output a regular non-zero digit.
1437                ++digitCount;
1438                digits.append((char)(digit + '0'));
1439                position += U16_LENGTH(ch);
1440            }
1441            else if (digit == 0)
1442            {
1443                // Cancel out backup setting (see grouping handler below)
1444                backup = -1;
1445                sawDigit = TRUE;
1446
1447                // Check for leading zeros
1448                if (digits.fCount != 0)
1449                {
1450                    // output a regular zero digit.
1451                    ++digitCount;
1452                    digits.append((char)(digit + '0'));
1453                }
1454                else if (sawDecimal)
1455                {
1456                    // If we have seen the decimal, but no significant digits yet,
1457                    // then we account for leading zeros by decrementing the
1458                    // digits.fDecimalAt into negative values.
1459                    --digits.fDecimalAt;
1460                }
1461                // else ignore leading zeros in integer part of number.
1462                position += U16_LENGTH(ch);
1463            }
1464            else if (!text.compare(position, groupingLen, *grouping) && isGroupingUsed())
1465            {
1466                // Ignore grouping characters, if we are using them, but require
1467                // that they be followed by a digit.  Otherwise we backup and
1468                // reprocess them.
1469                backup = position;
1470                position += groupingLen;
1471            }
1472            else if (!text.compare(position, decimalLen, *decimal) && !isParseIntegerOnly() && !sawDecimal)
1473            {
1474                // If we're only parsing integers, or if we ALREADY saw the
1475                // decimal, then don't parse this one.
1476
1477                digits.fDecimalAt = digitCount; // Not digits.fCount!
1478                sawDecimal = TRUE;
1479                position += decimalLen;
1480            }
1481            else {
1482                const UnicodeString *tmp;
1483                tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
1484                if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT))    // error code is set below if !sawDigit
1485                {
1486                    // Parse sign, if present
1487                    int32_t pos = position + tmp->length();
1488                    DigitList exponentDigits;
1489
1490                    if (pos < textLength)
1491                    {
1492                        tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
1493                        if (!text.compare(pos, tmp->length(), *tmp))
1494                        {
1495                            pos += tmp->length();
1496                        }
1497                        else {
1498                            tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
1499                            if (!text.compare(pos, tmp->length(), *tmp))
1500                            {
1501                                pos += tmp->length();
1502                                exponentDigits.fIsPositive = FALSE;
1503                            }
1504                        }
1505                    }
1506
1507                    while (pos < textLength) {
1508                        ch = text[(int32_t)pos];
1509                        digit = ch - zero;
1510
1511                        if (digit < 0 || digit > 9) {
1512                            digit = u_charDigitValue(ch);
1513                        }
1514                        if (0 <= digit && digit <= 9) {
1515                            ++pos;
1516                            exponentDigits.append((char)(digit + '0'));
1517                        } else {
1518                            break;
1519                        }
1520                    }
1521
1522                    if (exponentDigits.fCount > 0) {
1523                        exponentDigits.fDecimalAt = exponentDigits.fCount;
1524                        digits.fDecimalAt += exponentDigits.getLong();
1525                        position = pos; // Advance past the exponent
1526                    }
1527
1528                    break; // Whether we fail or succeed, we exit this loop
1529                }
1530                else {
1531                    break;
1532                }
1533            }
1534        }
1535
1536        if (backup != -1)
1537        {
1538            position = backup;
1539        }
1540
1541        // If there was no decimal point we have an integer
1542        if (!sawDecimal)
1543        {
1544            digits.fDecimalAt += digitCount; // Not digits.fCount!
1545        }
1546
1547        // If none of the text string was recognized.  For example, parse
1548        // "x" with pattern "#0.00" (return index and error index both 0)
1549        // parse "$" with pattern "$#0.00". (return index 0 and error index
1550        // 1).
1551        if (!sawDigit && digitCount == 0) {
1552            parsePosition.setIndex(oldStart);
1553            parsePosition.setErrorIndex(oldStart);
1554            return FALSE;
1555        }
1556    }
1557
1558    // Match padding before suffix
1559    if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) {
1560        position = skipPadding(text, position);
1561    }
1562
1563    // Match positive and negative suffixes; prefer longest match.
1564    if (posMatch >= 0) {
1565        posMatch = compareAffix(text, position, FALSE, FALSE, currency);
1566    }
1567    if (negMatch >= 0) {
1568        negMatch = compareAffix(text, position, TRUE, FALSE, currency);
1569    }
1570    if (posMatch >= 0 && negMatch >= 0) {
1571        if (posMatch > negMatch) {
1572            negMatch = -1;
1573        } else if (negMatch > posMatch) {
1574            posMatch = -1;
1575        }
1576    }
1577
1578    // Fail if neither or both
1579    if ((posMatch >= 0) == (negMatch >= 0)) {
1580        parsePosition.setErrorIndex(position);
1581        return FALSE;
1582    }
1583
1584    position += (posMatch>=0 ? posMatch : negMatch);
1585
1586    // Match padding before suffix
1587    if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) {
1588        position = skipPadding(text, position);
1589    }
1590
1591    parsePosition.setIndex(position);
1592
1593    digits.fIsPositive = (posMatch >= 0);
1594
1595    if(parsePosition.getIndex() == oldStart)
1596    {
1597        parsePosition.setErrorIndex(position);
1598        return FALSE;
1599    }
1600    return TRUE;
1601}
1602
1603/**
1604 * Starting at position, advance past a run of pad characters, if any.
1605 * Return the index of the first character after position that is not a pad
1606 * character.  Result is >= position.
1607 */
1608int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
1609    int32_t padLen = U16_LENGTH(fPad);
1610    while (position < text.length() &&
1611           text.char32At(position) == fPad) {
1612        position += padLen;
1613    }
1614    return position;
1615}
1616
1617/**
1618 * Return the length matched by the given affix, or -1 if none.
1619 * Runs of white space in the affix, match runs of white space in
1620 * the input.  Pattern white space and input white space are
1621 * determined differently; see code.
1622 * @param text input text
1623 * @param pos offset into input at which to begin matching
1624 * @param isNegative
1625 * @param isPrefix
1626 * @param currency return value for parsed currency, for generic
1627 * currency parsing mode, or null for normal parsing. In generic
1628 * currency parsing mode, any currency is parsed, not just the
1629 * currency that this formatter is set to.
1630 * @return length of input that matches, or -1 if match failure
1631 */
1632int32_t DecimalFormat::compareAffix(const UnicodeString& text,
1633                                    int32_t pos,
1634                                    UBool isNegative,
1635                                    UBool isPrefix,
1636                                    UChar* currency) const
1637{
1638    const UnicodeString *patternToCompare;
1639    if (fCurrencyChoice != NULL || currency != NULL) {
1640        if (isNegative) {
1641            if (isPrefix) {
1642                patternToCompare = fNegPrefixPattern;
1643            }
1644            else {
1645                patternToCompare = fNegSuffixPattern;
1646            }
1647        }
1648        else {
1649            if (isPrefix) {
1650                patternToCompare = fPosPrefixPattern;
1651            }
1652            else {
1653                patternToCompare = fPosSuffixPattern;
1654            }
1655        }
1656        if (patternToCompare != NULL) {
1657            return compareComplexAffix(*patternToCompare, text, pos, currency);
1658        }
1659        /* else the caller modified the pattern. Fallback to normal behavior. */
1660    }
1661
1662    if (isNegative) {
1663        if (isPrefix) {
1664            patternToCompare = &fNegativePrefix;
1665        }
1666        else {
1667            patternToCompare = &fNegativeSuffix;
1668        }
1669    }
1670    else {
1671        if (isPrefix) {
1672            patternToCompare = &fPositivePrefix;
1673        }
1674        else {
1675            patternToCompare = &fPositiveSuffix;
1676        }
1677    }
1678    return compareSimpleAffix(*patternToCompare, text, pos);
1679}
1680
1681/**
1682 * Return the length matched by the given affix, or -1 if none.
1683 * Runs of white space in the affix, match runs of white space in
1684 * the input.  Pattern white space and input white space are
1685 * determined differently; see code.
1686 * @param affix pattern string, taken as a literal
1687 * @param input input text
1688 * @param pos offset into input at which to begin matching
1689 * @return length of input that matches, or -1 if match failure
1690 */
1691int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
1692                                          const UnicodeString& input,
1693                                          int32_t pos) {
1694    int32_t start = pos;
1695    for (int32_t i=0; i<affix.length(); ) {
1696        UChar32 c = affix.char32At(i);
1697        int32_t len = U16_LENGTH(c);
1698        if (uprv_isRuleWhiteSpace(c)) {
1699            // We may have a pattern like: \u200F \u0020
1700            //        and input text like: \u200F \u0020
1701            // Note that U+200F and U+0020 are RuleWhiteSpace but only
1702            // U+0020 is UWhiteSpace.  So we have to first do a direct
1703            // match of the run of RULE whitespace in the pattern,
1704            // then match any extra characters.
1705            UBool literalMatch = FALSE;
1706            while (pos < input.length() &&
1707                   input.char32At(pos) == c) {
1708                literalMatch = TRUE;
1709                i += len;
1710                pos += len;
1711                if (i == affix.length()) {
1712                    break;
1713                }
1714                c = affix.char32At(i);
1715                len = U16_LENGTH(c);
1716                if (!uprv_isRuleWhiteSpace(c)) {
1717                    break;
1718                }
1719            }
1720
1721            // Advance over run in pattern
1722            i = skipRuleWhiteSpace(affix, i);
1723
1724            // Advance over run in input text
1725            // Must see at least one white space char in input,
1726            // unless we've already matched some characters literally.
1727            int32_t s = pos;
1728            pos = skipUWhiteSpace(input, pos);
1729            if (pos == s && !literalMatch) {
1730                return -1;
1731            }
1732        } else {
1733            if (pos < input.length() &&
1734                input.char32At(pos) == c) {
1735                i += len;
1736                pos += len;
1737            } else {
1738                return -1;
1739            }
1740        }
1741    }
1742    return pos - start;
1743}
1744
1745/**
1746 * Skip over a run of zero or more isRuleWhiteSpace() characters at
1747 * pos in text.
1748 */
1749int32_t DecimalFormat::skipRuleWhiteSpace(const UnicodeString& text, int32_t pos) {
1750    while (pos < text.length()) {
1751        UChar32 c = text.char32At(pos);
1752        if (!uprv_isRuleWhiteSpace(c)) {
1753            break;
1754        }
1755        pos += U16_LENGTH(c);
1756    }
1757    return pos;
1758}
1759
1760/**
1761 * Skip over a run of zero or more isUWhiteSpace() characters at pos
1762 * in text.
1763 */
1764int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) {
1765    while (pos < text.length()) {
1766        UChar32 c = text.char32At(pos);
1767        if (!u_isUWhiteSpace(c)) {
1768            break;
1769        }
1770        pos += U16_LENGTH(c);
1771    }
1772    return pos;
1773}
1774
1775/**
1776 * Return the length matched by the given affix, or -1 if none.
1777 * @param affixPat pattern string
1778 * @param input input text
1779 * @param pos offset into input at which to begin matching
1780 * @param currency return value for parsed currency, for generic
1781 * currency parsing mode, or null for normal parsing. In generic
1782 * currency parsing mode, any currency is parsed, not just the
1783 * currency that this formatter is set to.
1784 * @return length of input that matches, or -1 if match failure
1785 */
1786int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat,
1787                                           const UnicodeString& text,
1788                                           int32_t pos,
1789                                           UChar* currency) const
1790{
1791    int32_t start = pos;
1792    U_ASSERT(currency != NULL ||
1793             (fCurrencyChoice != NULL && *getCurrency() != 0));
1794
1795    for (int32_t i=0; i<affixPat.length() && pos >= 0; ) {
1796        UChar32 c = affixPat.char32At(i);
1797        i += U16_LENGTH(c);
1798
1799        if (c == kQuote) {
1800            U_ASSERT(i <= affixPat.length());
1801            c = affixPat.char32At(i);
1802            i += U16_LENGTH(c);
1803
1804            const UnicodeString* affix = NULL;
1805
1806            switch (c) {
1807            case kCurrencySign: {
1808                // If currency != null, then perform generic currency matching.
1809                // Otherwise, do currency choice parsing.
1810                UBool intl = i<affixPat.length() &&
1811                    affixPat.char32At(i) == kCurrencySign;
1812                // Parse generic currency -- anything for which we
1813                // have a display name, or any 3-letter ISO code.
1814                if (currency != NULL) {
1815                    // Try to parse display name for our locale; first
1816                    // determine our locale.
1817                    UErrorCode ec = U_ZERO_ERROR;
1818                    const char* loc = getLocaleID(ULOC_VALID_LOCALE, ec);
1819                    if (U_FAILURE(ec) || loc == NULL || *loc == 0) {
1820                        // applyPattern has been called; use the symbols
1821                        loc = fSymbols->getLocale().getName();
1822                        ec = U_ZERO_ERROR;
1823                    }
1824                    // Delegate parse of display name => ISO code to Currency
1825                    ParsePosition ppos(pos);
1826                    UChar curr[4];
1827                    uprv_parseCurrency(loc, text, ppos, curr, ec);
1828
1829                    // If parse succeeds, populate currency[0]
1830                    if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
1831                        u_strcpy(currency, curr);
1832                        pos = ppos.getIndex();
1833                    } else {
1834                        pos = -1;
1835                    }
1836                } else {
1837                    if (intl) {
1838                        ++i;
1839                        pos = match(text, pos, getCurrency());
1840                    } else {
1841                        ParsePosition ppos(pos);
1842                        Formattable result;
1843                        fCurrencyChoice->parse(text, result, ppos);
1844                        pos = (ppos.getIndex() == pos) ? -1 : ppos.getIndex();
1845                    }
1846                }
1847                continue;
1848            }
1849            case kPatternPercent:
1850                affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
1851                break;
1852            case kPatternPerMill:
1853                affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
1854                break;
1855            case kPatternPlus:
1856                affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
1857                break;
1858            case kPatternMinus:
1859                affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
1860                break;
1861            default:
1862                // fall through to affix!=0 test, which will fail
1863                break;
1864            }
1865
1866            if (affix != NULL) {
1867                pos = match(text, pos, *affix);
1868                continue;
1869            }
1870        }
1871
1872        pos = match(text, pos, c);
1873        if (uprv_isRuleWhiteSpace(c)) {
1874            i = skipRuleWhiteSpace(affixPat, i);
1875        }
1876    }
1877    return pos - start;
1878}
1879
1880/**
1881 * Match a single character at text[pos] and return the index of the
1882 * next character upon success.  Return -1 on failure.  If
1883 * isRuleWhiteSpace(ch) then match a run of white space in text.
1884 */
1885int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) {
1886    if (uprv_isRuleWhiteSpace(ch)) {
1887        // Advance over run of white space in input text
1888        // Must see at least one white space char in input
1889        int32_t s = pos;
1890        pos = skipUWhiteSpace(text, pos);
1891        if (pos == s) {
1892            return -1;
1893        }
1894        return pos;
1895    }
1896    return (pos >= 0 && text.char32At(pos) == ch) ?
1897        (pos + U16_LENGTH(ch)) : -1;
1898}
1899
1900/**
1901 * Match a string at text[pos] and return the index of the next
1902 * character upon success.  Return -1 on failure.  Match a run of
1903 * white space in str with a run of white space in text.
1904 */
1905int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) {
1906    for (int32_t i=0; i<str.length() && pos >= 0; ) {
1907        UChar32 ch = str.char32At(i);
1908        i += U16_LENGTH(ch);
1909        if (uprv_isRuleWhiteSpace(ch)) {
1910            i = skipRuleWhiteSpace(str, i);
1911        }
1912        pos = match(text, pos, ch);
1913    }
1914    return pos;
1915}
1916
1917//------------------------------------------------------------------------------
1918// Gets the pointer to the localized decimal format symbols
1919
1920const DecimalFormatSymbols*
1921DecimalFormat::getDecimalFormatSymbols() const
1922{
1923    return fSymbols;
1924}
1925
1926//------------------------------------------------------------------------------
1927// De-owning the current localized symbols and adopt the new symbols.
1928
1929void
1930DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
1931{
1932    if (symbolsToAdopt == NULL) {
1933        return; // do not allow caller to set fSymbols to NULL
1934    }
1935
1936    UBool sameSymbols = FALSE;
1937    if (fSymbols != NULL) {
1938        sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) ==
1939            symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) &&
1940            getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) ==
1941            symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1942        delete fSymbols;
1943    }
1944
1945    fSymbols = symbolsToAdopt;
1946    if (!sameSymbols) {
1947        // If the currency symbols are the same, there is no need to recalculate.
1948        setCurrencyForSymbols();
1949    }
1950    expandAffixes();
1951}
1952//------------------------------------------------------------------------------
1953// Setting the symbols is equlivalent to adopting a newly created localized
1954// symbols.
1955
1956void
1957DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
1958{
1959    adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
1960}
1961
1962/**
1963 * Update the currency object to match the symbols.  This method
1964 * is used only when the caller has passed in a symbols object
1965 * that may not be the default object for its locale.
1966 */
1967void
1968DecimalFormat::setCurrencyForSymbols() {
1969    /*Bug 4212072
1970      Update the affix strings accroding to symbols in order to keep
1971      the affix strings up to date.
1972      [Richard/GCL]
1973    */
1974
1975    // With the introduction of the Currency object, the currency
1976    // symbols in the DFS object are ignored.  For backward
1977    // compatibility, we check any explicitly set DFS object.  If it
1978    // is a default symbols object for its locale, we change the
1979    // currency object to one for that locale.  If it is custom,
1980    // we set the currency to null.
1981    UErrorCode ec = U_ZERO_ERROR;
1982    const UChar* c = NULL;
1983    const char* loc = fSymbols->getLocale().getName();
1984    UChar intlCurrencySymbol[4];
1985    ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec);
1986    UnicodeString currencySymbol;
1987
1988    uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec);
1989    if (U_SUCCESS(ec)
1990        && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol
1991        && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == intlCurrencySymbol)
1992    {
1993        // Trap an error in mapping locale to currency.  If we can't
1994        // map, then don't fail and set the currency to "".
1995        c = intlCurrencySymbol;
1996    }
1997    ec = U_ZERO_ERROR; // reset local error code!
1998    setCurrency(c, ec);
1999}
2000
2001
2002//------------------------------------------------------------------------------
2003// Gets the positive prefix of the number pattern.
2004
2005UnicodeString&
2006DecimalFormat::getPositivePrefix(UnicodeString& result) const
2007{
2008    result = fPositivePrefix;
2009    return result;
2010}
2011
2012//------------------------------------------------------------------------------
2013// Sets the positive prefix of the number pattern.
2014
2015void
2016DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
2017{
2018    fPositivePrefix = newValue;
2019    delete fPosPrefixPattern;
2020    fPosPrefixPattern = 0;
2021}
2022
2023//------------------------------------------------------------------------------
2024// Gets the negative prefix  of the number pattern.
2025
2026UnicodeString&
2027DecimalFormat::getNegativePrefix(UnicodeString& result) const
2028{
2029    result = fNegativePrefix;
2030    return result;
2031}
2032
2033//------------------------------------------------------------------------------
2034// Gets the negative prefix  of the number pattern.
2035
2036void
2037DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
2038{
2039    fNegativePrefix = newValue;
2040    delete fNegPrefixPattern;
2041    fNegPrefixPattern = 0;
2042}
2043
2044//------------------------------------------------------------------------------
2045// Gets the positive suffix of the number pattern.
2046
2047UnicodeString&
2048DecimalFormat::getPositiveSuffix(UnicodeString& result) const
2049{
2050    result = fPositiveSuffix;
2051    return result;
2052}
2053
2054//------------------------------------------------------------------------------
2055// Sets the positive suffix of the number pattern.
2056
2057void
2058DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
2059{
2060    fPositiveSuffix = newValue;
2061    delete fPosSuffixPattern;
2062    fPosSuffixPattern = 0;
2063}
2064
2065//------------------------------------------------------------------------------
2066// Gets the negative suffix of the number pattern.
2067
2068UnicodeString&
2069DecimalFormat::getNegativeSuffix(UnicodeString& result) const
2070{
2071    result = fNegativeSuffix;
2072    return result;
2073}
2074
2075//------------------------------------------------------------------------------
2076// Sets the negative suffix of the number pattern.
2077
2078void
2079DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
2080{
2081    fNegativeSuffix = newValue;
2082    delete fNegSuffixPattern;
2083    fNegSuffixPattern = 0;
2084}
2085
2086//------------------------------------------------------------------------------
2087// Gets the multiplier of the number pattern.
2088
2089int32_t DecimalFormat::getMultiplier() const
2090{
2091    return fMultiplier;
2092}
2093
2094//------------------------------------------------------------------------------
2095// Sets the multiplier of the number pattern.
2096void
2097DecimalFormat::setMultiplier(int32_t newValue)
2098{
2099//    if (newValue <= 0) {
2100//        throw new IllegalArgumentException("Bad multiplier: " + newValue);
2101//    }
2102    if (newValue > 0) {
2103        fMultiplier = newValue;
2104    }
2105    // else No way to return an error.
2106}
2107
2108/**
2109 * Get the rounding increment.
2110 * @return A positive rounding increment, or 0.0 if rounding
2111 * is not in effect.
2112 * @see #setRoundingIncrement
2113 * @see #getRoundingMode
2114 * @see #setRoundingMode
2115 */
2116double DecimalFormat::getRoundingIncrement() const {
2117    return fRoundingDouble;
2118}
2119
2120/**
2121 * Set the rounding increment.  This method also controls whether
2122 * rounding is enabled.
2123 * @param newValue A positive rounding increment, or 0.0 to disable rounding.
2124 * Negative increments are equivalent to 0.0.
2125 * @see #getRoundingIncrement
2126 * @see #getRoundingMode
2127 * @see #setRoundingMode
2128 */
2129void DecimalFormat::setRoundingIncrement(double newValue) {
2130    if (newValue > 0.0) {
2131        if (fRoundingIncrement == NULL) {
2132            fRoundingIncrement = new DigitList();
2133        }
2134        fRoundingIncrement->set((int32_t)newValue);
2135        fRoundingDouble = newValue;
2136    } else {
2137        delete fRoundingIncrement;
2138        fRoundingIncrement = NULL;
2139        fRoundingDouble = 0.0;
2140    }
2141}
2142
2143/**
2144 * Get the rounding mode.
2145 * @return A rounding mode
2146 * @see #setRoundingIncrement
2147 * @see #getRoundingIncrement
2148 * @see #setRoundingMode
2149 */
2150DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const {
2151    return fRoundingMode;
2152}
2153
2154/**
2155 * Set the rounding mode.  This has no effect unless the rounding
2156 * increment is greater than zero.
2157 * @param roundingMode A rounding mode
2158 * @see #setRoundingIncrement
2159 * @see #getRoundingIncrement
2160 * @see #getRoundingMode
2161 */
2162void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
2163    fRoundingMode = roundingMode;
2164}
2165
2166/**
2167 * Get the width to which the output of <code>format()</code> is padded.
2168 * @return the format width, or zero if no padding is in effect
2169 * @see #setFormatWidth
2170 * @see #getPadCharacter
2171 * @see #setPadCharacter
2172 * @see #getPadPosition
2173 * @see #setPadPosition
2174 */
2175int32_t DecimalFormat::getFormatWidth() const {
2176    return fFormatWidth;
2177}
2178
2179/**
2180 * Set the width to which the output of <code>format()</code> is padded.
2181 * This method also controls whether padding is enabled.
2182 * @param width the width to which to pad the result of
2183 * <code>format()</code>, or zero to disable padding.  A negative
2184 * width is equivalent to 0.
2185 * @see #getFormatWidth
2186 * @see #getPadCharacter
2187 * @see #setPadCharacter
2188 * @see #getPadPosition
2189 * @see #setPadPosition
2190 */
2191void DecimalFormat::setFormatWidth(int32_t width) {
2192    fFormatWidth = (width > 0) ? width : 0;
2193}
2194
2195UnicodeString DecimalFormat::getPadCharacterString() const {
2196    return fPad;
2197}
2198
2199void DecimalFormat::setPadCharacter(const UnicodeString &padChar) {
2200    if (padChar.length() > 0) {
2201        fPad = padChar.char32At(0);
2202    }
2203    else {
2204        fPad = kDefaultPad;
2205    }
2206}
2207
2208/**
2209 * Get the position at which padding will take place.  This is the location
2210 * at which padding will be inserted if the result of <code>format()</code>
2211 * is shorter than the format width.
2212 * @return the pad position, one of <code>kPadBeforePrefix</code>,
2213 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2214 * <code>kPadAfterSuffix</code>.
2215 * @see #setFormatWidth
2216 * @see #getFormatWidth
2217 * @see #setPadCharacter
2218 * @see #getPadCharacter
2219 * @see #setPadPosition
2220 * @see #kPadBeforePrefix
2221 * @see #kPadAfterPrefix
2222 * @see #kPadBeforeSuffix
2223 * @see #kPadAfterSuffix
2224 */
2225DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const {
2226    return fPadPosition;
2227}
2228
2229/**
2230 * <strong><font face=helvetica color=red>NEW</font></strong>
2231 * Set the position at which padding will take place.  This is the location
2232 * at which padding will be inserted if the result of <code>format()</code>
2233 * is shorter than the format width.  This has no effect unless padding is
2234 * enabled.
2235 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
2236 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2237 * <code>kPadAfterSuffix</code>.
2238 * @see #setFormatWidth
2239 * @see #getFormatWidth
2240 * @see #setPadCharacter
2241 * @see #getPadCharacter
2242 * @see #getPadPosition
2243 * @see #kPadBeforePrefix
2244 * @see #kPadAfterPrefix
2245 * @see #kPadBeforeSuffix
2246 * @see #kPadAfterSuffix
2247 */
2248void DecimalFormat::setPadPosition(EPadPosition padPos) {
2249    fPadPosition = padPos;
2250}
2251
2252/**
2253 * Return whether or not scientific notation is used.
2254 * @return TRUE if this object formats and parses scientific notation
2255 * @see #setScientificNotation
2256 * @see #getMinimumExponentDigits
2257 * @see #setMinimumExponentDigits
2258 * @see #isExponentSignAlwaysShown
2259 * @see #setExponentSignAlwaysShown
2260 */
2261UBool DecimalFormat::isScientificNotation() {
2262    return fUseExponentialNotation;
2263}
2264
2265/**
2266 * Set whether or not scientific notation is used.
2267 * @param useScientific TRUE if this object formats and parses scientific
2268 * notation
2269 * @see #isScientificNotation
2270 * @see #getMinimumExponentDigits
2271 * @see #setMinimumExponentDigits
2272 * @see #isExponentSignAlwaysShown
2273 * @see #setExponentSignAlwaysShown
2274 */
2275void DecimalFormat::setScientificNotation(UBool useScientific) {
2276    fUseExponentialNotation = useScientific;
2277}
2278
2279/**
2280 * Return the minimum exponent digits that will be shown.
2281 * @return the minimum exponent digits that will be shown
2282 * @see #setScientificNotation
2283 * @see #isScientificNotation
2284 * @see #setMinimumExponentDigits
2285 * @see #isExponentSignAlwaysShown
2286 * @see #setExponentSignAlwaysShown
2287 */
2288int8_t DecimalFormat::getMinimumExponentDigits() const {
2289    return fMinExponentDigits;
2290}
2291
2292/**
2293 * Set the minimum exponent digits that will be shown.  This has no
2294 * effect unless scientific notation is in use.
2295 * @param minExpDig a value >= 1 indicating the fewest exponent digits
2296 * that will be shown.  Values less than 1 will be treated as 1.
2297 * @see #setScientificNotation
2298 * @see #isScientificNotation
2299 * @see #getMinimumExponentDigits
2300 * @see #isExponentSignAlwaysShown
2301 * @see #setExponentSignAlwaysShown
2302 */
2303void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
2304    fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
2305}
2306
2307/**
2308 * Return whether the exponent sign is always shown.
2309 * @return TRUE if the exponent is always prefixed with either the
2310 * localized minus sign or the localized plus sign, false if only negative
2311 * exponents are prefixed with the localized minus sign.
2312 * @see #setScientificNotation
2313 * @see #isScientificNotation
2314 * @see #setMinimumExponentDigits
2315 * @see #getMinimumExponentDigits
2316 * @see #setExponentSignAlwaysShown
2317 */
2318UBool DecimalFormat::isExponentSignAlwaysShown() {
2319    return fExponentSignAlwaysShown;
2320}
2321
2322/**
2323 * Set whether the exponent sign is always shown.  This has no effect
2324 * unless scientific notation is in use.
2325 * @param expSignAlways TRUE if the exponent is always prefixed with either
2326 * the localized minus sign or the localized plus sign, false if only
2327 * negative exponents are prefixed with the localized minus sign.
2328 * @see #setScientificNotation
2329 * @see #isScientificNotation
2330 * @see #setMinimumExponentDigits
2331 * @see #getMinimumExponentDigits
2332 * @see #isExponentSignAlwaysShown
2333 */
2334void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
2335    fExponentSignAlwaysShown = expSignAlways;
2336}
2337
2338//------------------------------------------------------------------------------
2339// Gets the grouping size of the number pattern.  For example, thousand or 10
2340// thousand groupings.
2341
2342int32_t
2343DecimalFormat::getGroupingSize() const
2344{
2345    return fGroupingSize;
2346}
2347
2348//------------------------------------------------------------------------------
2349// Gets the grouping size of the number pattern.
2350
2351void
2352DecimalFormat::setGroupingSize(int32_t newValue)
2353{
2354    fGroupingSize = newValue;
2355}
2356
2357//------------------------------------------------------------------------------
2358
2359int32_t
2360DecimalFormat::getSecondaryGroupingSize() const
2361{
2362    return fGroupingSize2;
2363}
2364
2365//------------------------------------------------------------------------------
2366
2367void
2368DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
2369{
2370    fGroupingSize2 = newValue;
2371}
2372
2373//------------------------------------------------------------------------------
2374// Checks if to show the decimal separator.
2375
2376UBool
2377DecimalFormat::isDecimalSeparatorAlwaysShown() const
2378{
2379    return fDecimalSeparatorAlwaysShown;
2380}
2381
2382//------------------------------------------------------------------------------
2383// Sets to always show the decimal separator.
2384
2385void
2386DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
2387{
2388    fDecimalSeparatorAlwaysShown = newValue;
2389}
2390
2391//------------------------------------------------------------------------------
2392// Emits the pattern of this DecimalFormat instance.
2393
2394UnicodeString&
2395DecimalFormat::toPattern(UnicodeString& result) const
2396{
2397    return toPattern(result, FALSE);
2398}
2399
2400//------------------------------------------------------------------------------
2401// Emits the localized pattern this DecimalFormat instance.
2402
2403UnicodeString&
2404DecimalFormat::toLocalizedPattern(UnicodeString& result) const
2405{
2406    return toPattern(result, TRUE);
2407}
2408
2409//------------------------------------------------------------------------------
2410/**
2411 * Expand the affix pattern strings into the expanded affix strings.  If any
2412 * affix pattern string is null, do not expand it.  This method should be
2413 * called any time the symbols or the affix patterns change in order to keep
2414 * the expanded affix strings up to date.
2415 */
2416void DecimalFormat::expandAffixes() {
2417    if (fPosPrefixPattern != 0) {
2418        expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, FALSE);
2419    }
2420    if (fPosSuffixPattern != 0) {
2421        expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, FALSE);
2422    }
2423    if (fNegPrefixPattern != 0) {
2424        expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, FALSE);
2425    }
2426    if (fNegSuffixPattern != 0) {
2427        expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, FALSE);
2428    }
2429#ifdef FMT_DEBUG
2430    UnicodeString s;
2431    s.append("[")
2432        .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern)
2433        .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern)
2434        .append("]->[")
2435        .append(fPositivePrefix).append("|").append(fPositiveSuffix)
2436        .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix)
2437        .append("]\n");
2438    debugout(s);
2439#endif
2440}
2441
2442/**
2443 * Expand an affix pattern into an affix string.  All characters in the
2444 * pattern are literal unless prefixed by kQuote.  The following characters
2445 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2446 * PATTERN_MINUS, and kCurrencySign.  If kCurrencySign is doubled (kQuote +
2447 * kCurrencySign + kCurrencySign), it is interpreted as an international
2448 * currency sign.  Any other character after a kQuote represents itself.
2449 * kQuote must be followed by another character; kQuote may not occur by
2450 * itself at the end of the pattern.
2451 *
2452 * This method is used in two distinct ways.  First, it is used to expand
2453 * the stored affix patterns into actual affixes.  For this usage, doFormat
2454 * must be false.  Second, it is used to expand the stored affix patterns
2455 * given a specific number (doFormat == true), for those rare cases in
2456 * which a currency format references a ChoiceFormat (e.g., en_IN display
2457 * name for INR).  The number itself is taken from digitList.
2458 *
2459 * When used in the first way, this method has a side effect: It sets
2460 * currencyChoice to a ChoiceFormat object, if the currency's display name
2461 * in this locale is a ChoiceFormat pattern (very rare).  It only does this
2462 * if currencyChoice is null to start with.
2463 *
2464 * @param pattern the non-null, fPossibly empty pattern
2465 * @param affix string to receive the expanded equivalent of pattern.
2466 * Previous contents are deleted.
2467 * @param doFormat if false, then the pattern will be expanded, and if a
2468 * currency symbol is encountered that expands to a ChoiceFormat, the
2469 * currencyChoice member variable will be initialized if it is null.  If
2470 * doFormat is true, then it is assumed that the currencyChoice has been
2471 * created, and it will be used to format the value in digitList.
2472 */
2473void DecimalFormat::expandAffix(const UnicodeString& pattern,
2474                                UnicodeString& affix,
2475                                double number,
2476                                UBool doFormat) const {
2477    affix.remove();
2478    for (int i=0; i<pattern.length(); ) {
2479        UChar32 c = pattern.char32At(i);
2480        i += U16_LENGTH(c);
2481        if (c == kQuote) {
2482            c = pattern.char32At(i);
2483            i += U16_LENGTH(c);
2484            switch (c) {
2485            case kCurrencySign: {
2486                // As of ICU 2.2 we use the currency object, and
2487                // ignore the currency symbols in the DFS, unless
2488                // we have a null currency object.  This occurs if
2489                // resurrecting a pre-2.2 object or if the user
2490                // sets a custom DFS.
2491                UBool intl = i<pattern.length() &&
2492                    pattern.char32At(i) == kCurrencySign;
2493                if (intl) {
2494                    ++i;
2495                }
2496                const UChar* currencyUChars = getCurrency();
2497                if (currencyUChars[0] != 0) {
2498                    UErrorCode ec = U_ZERO_ERROR;
2499                    if(intl) {
2500                        affix += currencyUChars;
2501                    } else {
2502                        int32_t len;
2503                        UBool isChoiceFormat;
2504                        const UChar* s = ucurr_getName(currencyUChars, fSymbols->getLocale().getName(),
2505                                                       UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec);
2506                        if (isChoiceFormat) {
2507                            // Two modes here: If doFormat is false, we set up
2508                            // currencyChoice.  If doFormat is true, we use the
2509                            // previously created currencyChoice to format the
2510                            // value in digitList.
2511                            if (!doFormat) {
2512                                // If the currency is handled by a ChoiceFormat,
2513                                // then we're not going to use the expanded
2514                                // patterns.  Instantiate the ChoiceFormat and
2515                                // return.
2516                                if (fCurrencyChoice == NULL) {
2517                                    // TODO Replace double-check with proper thread-safe code
2518                                    ChoiceFormat* fmt = new ChoiceFormat(s, ec);
2519                                    if (U_SUCCESS(ec)) {
2520                                        umtx_lock(NULL);
2521                                        if (fCurrencyChoice == NULL) {
2522                                            // Cast away const
2523                                            ((DecimalFormat*)this)->fCurrencyChoice = fmt;
2524                                            fmt = NULL;
2525                                        }
2526                                        umtx_unlock(NULL);
2527                                        delete fmt;
2528                                    }
2529                                }
2530                                // We could almost return null or "" here, since the
2531                                // expanded affixes are almost not used at all
2532                                // in this situation.  However, one method --
2533                                // toPattern() -- still does use the expanded
2534                                // affixes, in order to set up a padding
2535                                // pattern.  We use the CURRENCY_SIGN as a
2536                                // placeholder.
2537                                affix.append(kCurrencySign);
2538                            } else {
2539                                if (fCurrencyChoice != NULL) {
2540                                    FieldPosition pos(0); // ignored
2541                                    if (number < 0) {
2542                                        number = -number;
2543                                    }
2544                                    fCurrencyChoice->format(number, affix, pos);
2545                                } else {
2546                                    // We only arrive here if the currency choice
2547                                    // format in the locale data is INVALID.
2548                                    affix += currencyUChars;
2549                                }
2550                            }
2551                            continue;
2552                        }
2553                        affix += UnicodeString(s, len);
2554                    }
2555                } else {
2556                    if(intl) {
2557                        affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
2558                    } else {
2559                        affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
2560                    }
2561                }
2562                break;
2563            }
2564            case kPatternPercent:
2565                affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
2566                break;
2567            case kPatternPerMill:
2568                affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
2569                break;
2570            case kPatternPlus:
2571                affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2572                break;
2573            case kPatternMinus:
2574                affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2575                break;
2576            default:
2577                affix.append(c);
2578                break;
2579            }
2580        }
2581        else {
2582            affix.append(c);
2583        }
2584    }
2585}
2586
2587/**
2588 * Append an affix to the given StringBuffer.
2589 * @param buf buffer to append to
2590 * @param isNegative
2591 * @param isPrefix
2592 */
2593int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number,
2594                                   UBool isNegative, UBool isPrefix) const {
2595    if (fCurrencyChoice != 0) {
2596        const UnicodeString* affixPat;
2597        if (isPrefix) {
2598            affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern;
2599        } else {
2600            affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern;
2601        }
2602        if (affixPat) {
2603            UnicodeString affixBuf;
2604            expandAffix(*affixPat, affixBuf, number, TRUE);
2605            buf.append(affixBuf);
2606            return affixBuf.length();
2607        }
2608        // else someone called a function that reset the pattern.
2609    }
2610
2611    const UnicodeString* affix;
2612    if (isPrefix) {
2613        affix = isNegative ? &fNegativePrefix : &fPositivePrefix;
2614    } else {
2615        affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix;
2616    }
2617    buf.append(*affix);
2618    return affix->length();
2619}
2620
2621/**
2622 * Appends an affix pattern to the given StringBuffer, quoting special
2623 * characters as needed.  Uses the internal affix pattern, if that exists,
2624 * or the literal affix, if the internal affix pattern is null.  The
2625 * appended string will generate the same affix pattern (or literal affix)
2626 * when passed to toPattern().
2627 *
2628 * @param appendTo the affix string is appended to this
2629 * @param affixPattern a pattern such as fPosPrefixPattern; may be null
2630 * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
2631 * Ignored unless affixPattern is null.  If affixPattern is null, then
2632 * expAffix is appended as a literal affix.
2633 * @param localized true if the appended pattern should contain localized
2634 * pattern characters; otherwise, non-localized pattern chars are appended
2635 */
2636void DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
2637                                       const UnicodeString* affixPattern,
2638                                       const UnicodeString& expAffix,
2639                                       UBool localized) const {
2640    if (affixPattern == 0) {
2641        appendAffixPattern(appendTo, expAffix, localized);
2642    } else {
2643        int i;
2644        for (int pos=0; pos<affixPattern->length(); pos=i) {
2645            i = affixPattern->indexOf(kQuote, pos);
2646            if (i < 0) {
2647                UnicodeString s;
2648                affixPattern->extractBetween(pos, affixPattern->length(), s);
2649                appendAffixPattern(appendTo, s, localized);
2650                break;
2651            }
2652            if (i > pos) {
2653                UnicodeString s;
2654                affixPattern->extractBetween(pos, i, s);
2655                appendAffixPattern(appendTo, s, localized);
2656            }
2657            UChar32 c = affixPattern->char32At(++i);
2658            ++i;
2659            if (c == kQuote) {
2660                appendTo.append(c).append(c);
2661                // Fall through and append another kQuote below
2662            } else if (c == kCurrencySign &&
2663                       i<affixPattern->length() &&
2664                       affixPattern->char32At(i) == kCurrencySign) {
2665                ++i;
2666                appendTo.append(c).append(c);
2667            } else if (localized) {
2668                switch (c) {
2669                case kPatternPercent:
2670                    appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
2671                    break;
2672                case kPatternPerMill:
2673                    appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
2674                    break;
2675                case kPatternPlus:
2676                    appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2677                    break;
2678                case kPatternMinus:
2679                    appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2680                    break;
2681                default:
2682                    appendTo.append(c);
2683                }
2684            } else {
2685                appendTo.append(c);
2686            }
2687        }
2688    }
2689}
2690
2691/**
2692 * Append an affix to the given StringBuffer, using quotes if
2693 * there are special characters.  Single quotes themselves must be
2694 * escaped in either case.
2695 */
2696void
2697DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
2698                                  const UnicodeString& affix,
2699                                  UBool localized) const {
2700    UBool needQuote;
2701    if(localized) {
2702        needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0
2703            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0
2704            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0
2705            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0
2706            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0
2707            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0
2708            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0
2709            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0
2710            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0
2711            || affix.indexOf(kCurrencySign) >= 0;
2712    }
2713    else {
2714        needQuote = affix.indexOf(kPatternZeroDigit) >= 0
2715            || affix.indexOf(kPatternGroupingSeparator) >= 0
2716            || affix.indexOf(kPatternDecimalSeparator) >= 0
2717            || affix.indexOf(kPatternPercent) >= 0
2718            || affix.indexOf(kPatternPerMill) >= 0
2719            || affix.indexOf(kPatternDigit) >= 0
2720            || affix.indexOf(kPatternSeparator) >= 0
2721            || affix.indexOf(kPatternExponent) >= 0
2722            || affix.indexOf(kPatternPlus) >= 0
2723            || affix.indexOf(kPatternMinus) >= 0
2724            || affix.indexOf(kCurrencySign) >= 0;
2725    }
2726    if (needQuote)
2727        appendTo += (UChar)0x0027 /*'\''*/;
2728    if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0)
2729        appendTo += affix;
2730    else {
2731        for (int32_t j = 0; j < affix.length(); ) {
2732            UChar32 c = affix.char32At(j);
2733            j += U16_LENGTH(c);
2734            appendTo += c;
2735            if (c == 0x0027 /*'\''*/)
2736                appendTo += c;
2737        }
2738    }
2739    if (needQuote)
2740        appendTo += (UChar)0x0027 /*'\''*/;
2741}
2742
2743//------------------------------------------------------------------------------
2744
2745UnicodeString&
2746DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
2747{
2748    result.remove();
2749    UChar32 zero, sigDigit = kPatternSignificantDigit;
2750    UnicodeString digit, group;
2751    int32_t i;
2752    int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
2753    UnicodeString roundingDigits;
2754    int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
2755    UnicodeString padSpec;
2756    UBool useSigDig = areSignificantDigitsUsed();
2757
2758    if (localized) {
2759        digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
2760        group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
2761        zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
2762        if (useSigDig) {
2763            sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
2764        }
2765    }
2766    else {
2767        digit.append((UChar)kPatternDigit);
2768        group.append((UChar)kPatternGroupingSeparator);
2769        zero = (UChar32)kPatternZeroDigit;
2770    }
2771    if (fFormatWidth > 0) {
2772        if (localized) {
2773            padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
2774        }
2775        else {
2776            padSpec.append((UChar)kPatternPadEscape);
2777        }
2778        padSpec.append(fPad);
2779    }
2780    if (fRoundingIncrement != NULL) {
2781        for(i=0; i<fRoundingIncrement->fCount; ++i) {
2782            roundingDigits.append((UChar)fRoundingIncrement->fDigits[i]);
2783        }
2784        roundingDecimalPos = fRoundingIncrement->fDecimalAt;
2785    }
2786    for (int32_t part=0; part<2; ++part) {
2787        if (padPos == kPadBeforePrefix) {
2788            result.append(padSpec);
2789        }
2790        appendAffixPattern(result,
2791                    (part==0 ? fPosPrefixPattern : fNegPrefixPattern),
2792                    (part==0 ? fPositivePrefix : fNegativePrefix),
2793                    localized);
2794        if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) {
2795            result.append(padSpec);
2796        }
2797        int32_t sub0Start = result.length();
2798        int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0;
2799        if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) {
2800            g += fGroupingSize2;
2801        }
2802        int32_t maxDig = 0, minDig = 0, maxSigDig = 0;
2803        if (useSigDig) {
2804            minDig = getMinimumSignificantDigits();
2805            maxDig = maxSigDig = getMaximumSignificantDigits();
2806        } else {
2807            minDig = getMinimumIntegerDigits();
2808            maxDig = getMaximumIntegerDigits();
2809        }
2810        if (fUseExponentialNotation) {
2811            if (maxDig > kMaxScientificIntegerDigits) {
2812                maxDig = 1;
2813            }
2814        } else if (useSigDig) {
2815            maxDig = _max(maxDig, g+1);
2816        } else {
2817            maxDig = _max(_max(g, getMinimumIntegerDigits()),
2818                          roundingDecimalPos) + 1;
2819        }
2820        for (i = maxDig; i > 0; --i) {
2821            if (!fUseExponentialNotation && i<maxDig &&
2822                isGroupingPosition(i)) {
2823                result.append(group);
2824            }
2825            if (useSigDig) {
2826                //  #@,@###   (maxSigDig == 5, minSigDig == 2)
2827                //  65 4321   (1-based pos, count from the right)
2828                // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
2829                // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
2830                if (maxSigDig >= i && i > (maxSigDig - minDig)) {
2831                    result.append(sigDigit);
2832                } else {
2833                    result.append(digit);
2834                }
2835            } else {
2836                if (! roundingDigits.isEmpty()) {
2837                    int32_t pos = roundingDecimalPos - i;
2838                    if (pos >= 0 && pos < roundingDigits.length()) {
2839                        result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
2840                        continue;
2841                    }
2842                }
2843                if (i<=minDig) {
2844                    result.append(zero);
2845                } else {
2846                    result.append(digit);
2847                }
2848            }
2849        }
2850        if (!useSigDig) {
2851            if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
2852                if (localized) {
2853                    result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
2854                }
2855                else {
2856                    result.append((UChar)kPatternDecimalSeparator);
2857                }
2858            }
2859            int32_t pos = roundingDecimalPos;
2860            for (i = 0; i < getMaximumFractionDigits(); ++i) {
2861                if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) {
2862                    if (pos < 0) {
2863                        result.append(zero);
2864                    }
2865                    else {
2866                        result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
2867                    }
2868                    ++pos;
2869                    continue;
2870                }
2871                if (i<getMinimumFractionDigits()) {
2872                    result.append(zero);
2873                }
2874                else {
2875                    result.append(digit);
2876                }
2877            }
2878        }
2879        if (fUseExponentialNotation) {
2880            if (localized) {
2881                result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
2882            }
2883            else {
2884                result.append((UChar)kPatternExponent);
2885            }
2886            if (fExponentSignAlwaysShown) {
2887                if (localized) {
2888                    result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2889                }
2890                else {
2891                    result.append((UChar)kPatternPlus);
2892                }
2893            }
2894            for (i=0; i<fMinExponentDigits; ++i) {
2895                result.append(zero);
2896            }
2897        }
2898        if (! padSpec.isEmpty() && !fUseExponentialNotation) {
2899            int32_t add = fFormatWidth - result.length() + sub0Start
2900                - ((part == 0)
2901                   ? fPositivePrefix.length() + fPositiveSuffix.length()
2902                   : fNegativePrefix.length() + fNegativeSuffix.length());
2903            while (add > 0) {
2904                result.insert(sub0Start, digit);
2905                ++maxDig;
2906                --add;
2907                // Only add a grouping separator if we have at least
2908                // 2 additional characters to be added, so we don't
2909                // end up with ",###".
2910                if (add>1 && isGroupingPosition(maxDig)) {
2911                    result.insert(sub0Start, group);
2912                    --add;
2913                }
2914            }
2915        }
2916        if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) {
2917            result.append(padSpec);
2918        }
2919        if (part == 0) {
2920            appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized);
2921            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
2922                result.append(padSpec);
2923            }
2924            UBool isDefault = FALSE;
2925            if ((fNegSuffixPattern == fPosSuffixPattern && // both null
2926                 fNegativeSuffix == fPositiveSuffix)
2927                || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 &&
2928                    *fNegSuffixPattern == *fPosSuffixPattern))
2929            {
2930                if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL)
2931                {
2932                    int32_t length = fPosPrefixPattern->length();
2933                    isDefault = fNegPrefixPattern->length() == (length+2) &&
2934                        (*fNegPrefixPattern)[(int32_t)0] == kQuote &&
2935                        (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus &&
2936                        fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0;
2937                }
2938                if (!isDefault &&
2939                    fNegPrefixPattern == NULL && fPosPrefixPattern == NULL)
2940                {
2941                    int32_t length = fPositivePrefix.length();
2942                    isDefault = fNegativePrefix.length() == (length+1) &&
2943                        fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
2944                        fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
2945                }
2946            }
2947            if (isDefault) {
2948                break; // Don't output default negative subpattern
2949            } else {
2950                if (localized) {
2951                    result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
2952                }
2953                else {
2954                    result.append((UChar)kPatternSeparator);
2955                }
2956            }
2957        } else {
2958            appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized);
2959            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
2960                result.append(padSpec);
2961            }
2962        }
2963    }
2964
2965    return result;
2966}
2967
2968//------------------------------------------------------------------------------
2969
2970void
2971DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
2972{
2973    UParseError parseError;
2974    applyPattern(pattern, FALSE, parseError, status);
2975}
2976
2977//------------------------------------------------------------------------------
2978
2979void
2980DecimalFormat::applyPattern(const UnicodeString& pattern,
2981                            UParseError& parseError,
2982                            UErrorCode& status)
2983{
2984    applyPattern(pattern, FALSE, parseError, status);
2985}
2986//------------------------------------------------------------------------------
2987
2988void
2989DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
2990{
2991    UParseError parseError;
2992    applyPattern(pattern, TRUE,parseError,status);
2993}
2994
2995//------------------------------------------------------------------------------
2996
2997void
2998DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
2999                                     UParseError& parseError,
3000                                     UErrorCode& status)
3001{
3002    applyPattern(pattern, TRUE,parseError,status);
3003}
3004
3005//------------------------------------------------------------------------------
3006
3007void
3008DecimalFormat::applyPattern(const UnicodeString& pattern,
3009                            UBool localized,
3010                            UParseError& parseError,
3011                            UErrorCode& status)
3012{
3013    if (U_FAILURE(status))
3014    {
3015        return;
3016    }
3017    // Clear error struct
3018    parseError.offset = -1;
3019    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
3020
3021    // Set the significant pattern symbols
3022    UChar32 zeroDigit               = kPatternZeroDigit; // '0'
3023    UChar32 sigDigit                = kPatternSignificantDigit; // '@'
3024    UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator);
3025    UnicodeString decimalSeparator  ((UChar)kPatternDecimalSeparator);
3026    UnicodeString percent           ((UChar)kPatternPercent);
3027    UnicodeString perMill           ((UChar)kPatternPerMill);
3028    UnicodeString digit             ((UChar)kPatternDigit); // '#'
3029    UnicodeString separator         ((UChar)kPatternSeparator);
3030    UnicodeString exponent          ((UChar)kPatternExponent);
3031    UnicodeString plus              ((UChar)kPatternPlus);
3032    UnicodeString minus             ((UChar)kPatternMinus);
3033    UnicodeString padEscape         ((UChar)kPatternPadEscape);
3034    // Substitute with the localized symbols if necessary
3035    if (localized) {
3036        zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
3037        sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
3038        groupingSeparator.  remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
3039        decimalSeparator.   remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
3040        percent.            remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
3041        perMill.            remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
3042        digit.              remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
3043        separator.          remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
3044        exponent.           remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol));
3045        plus.               remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol));
3046        minus.              remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
3047        padEscape.          remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
3048    }
3049    UChar nineDigit = (UChar)(zeroDigit + 9);
3050    int32_t digitLen = digit.length();
3051    int32_t groupSepLen = groupingSeparator.length();
3052    int32_t decimalSepLen = decimalSeparator.length();
3053
3054    int32_t pos = 0;
3055    int32_t patLen = pattern.length();
3056    // Part 0 is the positive pattern.  Part 1, if present, is the negative
3057    // pattern.
3058    for (int32_t part=0; part<2 && pos<patLen; ++part) {
3059        // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
3060        // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
3061        // between the prefix and suffix, and consists of pattern
3062        // characters.  In the prefix and suffix, percent, perMill, and
3063        // currency symbols are recognized and translated.
3064        int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
3065
3066        // It's important that we don't change any fields of this object
3067        // prematurely.  We set the following variables for the multiplier,
3068        // grouping, etc., and then only change the actual object fields if
3069        // everything parses correctly.  This also lets us register
3070        // the data from part 0 and ignore the part 1, except for the
3071        // prefix and suffix.
3072        UnicodeString prefix;
3073        UnicodeString suffix;
3074        int32_t decimalPos = -1;
3075        int32_t multiplier = 1;
3076        int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
3077        int8_t groupingCount = -1;
3078        int8_t groupingCount2 = -1;
3079        int32_t padPos = -1;
3080        UChar32 padChar = 0;
3081        int32_t roundingPos = -1;
3082        DigitList roundingInc;
3083        int8_t expDigits = -1;
3084        UBool expSignAlways = FALSE;
3085        UBool isCurrency = FALSE;
3086
3087        // The affix is either the prefix or the suffix.
3088        UnicodeString* affix = &prefix;
3089
3090        int32_t start = pos;
3091        UBool isPartDone = FALSE;
3092        UChar32 ch;
3093
3094        for (; !isPartDone && pos < patLen; ) {
3095            // Todo: account for surrogate pairs
3096            ch = pattern.char32At(pos);
3097            switch (subpart) {
3098            case 0: // Pattern proper subpart (between prefix & suffix)
3099                // Process the digits, decimal, and grouping characters.  We
3100                // record five pieces of information.  We expect the digits
3101                // to occur in the pattern ####00.00####, and we record the
3102                // number of left digits, zero (central) digits, and right
3103                // digits.  The position of the last grouping character is
3104                // recorded (should be somewhere within the first two blocks
3105                // of characters), as is the position of the decimal point,
3106                // if any (should be in the zero digits).  If there is no
3107                // decimal point, then there should be no right digits.
3108                if (pattern.compare(pos, digitLen, digit) == 0) {
3109                    if (zeroDigitCount > 0 || sigDigitCount > 0) {
3110                        ++digitRightCount;
3111                    } else {
3112                        ++digitLeftCount;
3113                    }
3114                    if (groupingCount >= 0 && decimalPos < 0) {
3115                        ++groupingCount;
3116                    }
3117                    pos += digitLen;
3118                } else if ((ch >= zeroDigit && ch <= nineDigit) ||
3119                           ch == sigDigit) {
3120                    if (digitRightCount > 0) {
3121                        // Unexpected '0'
3122                        debug("Unexpected '0'")
3123                        status = U_UNEXPECTED_TOKEN;
3124                        syntaxError(pattern,pos,parseError);
3125                        return;
3126                    }
3127                    if (ch == sigDigit) {
3128                        ++sigDigitCount;
3129                    } else {
3130                        ++zeroDigitCount;
3131                        if (ch != zeroDigit && roundingPos < 0) {
3132                            roundingPos = digitLeftCount + zeroDigitCount;
3133                        }
3134                        if (roundingPos >= 0) {
3135                            roundingInc.append((char)(ch - zeroDigit + '0'));
3136                        }
3137                    }
3138                    if (groupingCount >= 0 && decimalPos < 0) {
3139                        ++groupingCount;
3140                    }
3141                    pos += U16_LENGTH(ch);
3142                } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
3143                    if (decimalPos >= 0) {
3144                        // Grouping separator after decimal
3145                        debug("Grouping separator after decimal")
3146                        status = U_UNEXPECTED_TOKEN;
3147                        syntaxError(pattern,pos,parseError);
3148                        return;
3149                    }
3150                    groupingCount2 = groupingCount;
3151                    groupingCount = 0;
3152                    pos += groupSepLen;
3153                } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
3154                    if (decimalPos >= 0) {
3155                        // Multiple decimal separators
3156                        debug("Multiple decimal separators")
3157                        status = U_MULTIPLE_DECIMAL_SEPARATORS;
3158                        syntaxError(pattern,pos,parseError);
3159                        return;
3160                    }
3161                    // Intentionally incorporate the digitRightCount,
3162                    // even though it is illegal for this to be > 0
3163                    // at this point.  We check pattern syntax below.
3164                    decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
3165                    pos += decimalSepLen;
3166                } else {
3167                    if (pattern.compare(pos, exponent.length(), exponent) == 0) {
3168                        if (expDigits >= 0) {
3169                            // Multiple exponential symbols
3170                            debug("Multiple exponential symbols")
3171                            status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
3172                            syntaxError(pattern,pos,parseError);
3173                            return;
3174                        }
3175                        if (groupingCount >= 0) {
3176                            // Grouping separator in exponential pattern
3177                            debug("Grouping separator in exponential pattern")
3178                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
3179                            syntaxError(pattern,pos,parseError);
3180                            return;
3181                        }
3182                        pos += exponent.length();
3183                        // Check for positive prefix
3184                        if (pos < patLen
3185                            && pattern.compare(pos, plus.length(), plus) == 0) {
3186                            expSignAlways = TRUE;
3187                            pos += plus.length();
3188                        }
3189                        // Use lookahead to parse out the exponential part of the
3190                        // pattern, then jump into suffix subpart.
3191                        expDigits = 0;
3192                        while (pos < patLen &&
3193                               pattern.char32At(pos) == zeroDigit) {
3194                            ++expDigits;
3195                            pos += U16_LENGTH(zeroDigit);
3196                        }
3197
3198                        // 1. Require at least one mantissa pattern digit
3199                        // 2. Disallow "#+ @" in mantissa
3200                        // 3. Require at least one exponent pattern digit
3201                        if (((digitLeftCount + zeroDigitCount) < 1 &&
3202                             (sigDigitCount + digitRightCount) < 1) ||
3203                            (sigDigitCount > 0 && digitLeftCount > 0) ||
3204                            expDigits < 1) {
3205                            // Malformed exponential pattern
3206                            debug("Malformed exponential pattern")
3207                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
3208                            syntaxError(pattern,pos,parseError);
3209                            return;
3210                        }
3211                    }
3212                    // Transition to suffix subpart
3213                    subpart = 2; // suffix subpart
3214                    affix = &suffix;
3215                    sub0Limit = pos;
3216                    continue;
3217                }
3218                break;
3219            case 1: // Prefix subpart
3220            case 2: // Suffix subpart
3221                // Process the prefix / suffix characters
3222                // Process unquoted characters seen in prefix or suffix
3223                // subpart.
3224
3225                // Several syntax characters implicitly begins the
3226                // next subpart if we are in the prefix; otherwise
3227                // they are illegal if unquoted.
3228                if (!pattern.compare(pos, digitLen, digit) ||
3229                    !pattern.compare(pos, groupSepLen, groupingSeparator) ||
3230                    !pattern.compare(pos, decimalSepLen, decimalSeparator) ||
3231                    (ch >= zeroDigit && ch <= nineDigit) ||
3232                    ch == sigDigit) {
3233                    if (subpart == 1) { // prefix subpart
3234                        subpart = 0; // pattern proper subpart
3235                        sub0Start = pos; // Reprocess this character
3236                        continue;
3237                    } else {
3238                        status = U_UNQUOTED_SPECIAL;
3239                        syntaxError(pattern,pos,parseError);
3240                        return;
3241                    }
3242                } else if (ch == kCurrencySign) {
3243                    affix->append(kQuote); // Encode currency
3244                    // Use lookahead to determine if the currency sign is
3245                    // doubled or not.
3246                    U_ASSERT(U16_LENGTH(kCurrencySign) == 1);
3247                    if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) {
3248                        affix->append(kCurrencySign);
3249                        ++pos; // Skip over the doubled character
3250                    }
3251                    isCurrency = TRUE;
3252                    // Fall through to append(ch)
3253                } else if (ch == kQuote) {
3254                    // A quote outside quotes indicates either the opening
3255                    // quote or two quotes, which is a quote literal.  That is,
3256                    // we have the first quote in 'do' or o''clock.
3257                    U_ASSERT(U16_LENGTH(kQuote) == 1);
3258                    ++pos;
3259                    if (pos < pattern.length() && pattern[pos] == kQuote) {
3260                        affix->append(kQuote); // Encode quote
3261                        // Fall through to append(ch)
3262                    } else {
3263                        subpart += 2; // open quote
3264                        continue;
3265                    }
3266                } else if (pattern.compare(pos, separator.length(), separator) == 0) {
3267                    // Don't allow separators in the prefix, and don't allow
3268                    // separators in the second pattern (part == 1).
3269                    if (subpart == 1 || part == 1) {
3270                        // Unexpected separator
3271                        debug("Unexpected separator")
3272                        status = U_UNEXPECTED_TOKEN;
3273                        syntaxError(pattern,pos,parseError);
3274                        return;
3275                    }
3276                    sub2Limit = pos;
3277                    isPartDone = TRUE; // Go to next part
3278                    pos += separator.length();
3279                    break;
3280                } else if (pattern.compare(pos, percent.length(), percent) == 0) {
3281                    // Next handle characters which are appended directly.
3282                    if (multiplier != 1) {
3283                        // Too many percent/perMill characters
3284                        debug("Too many percent characters")
3285                        status = U_MULTIPLE_PERCENT_SYMBOLS;
3286                        syntaxError(pattern,pos,parseError);
3287                        return;
3288                    }
3289                    affix->append(kQuote); // Encode percent/perMill
3290                    affix->append(kPatternPercent); // Use unlocalized pattern char
3291                    multiplier = 100;
3292                    pos += percent.length();
3293                    break;
3294                } else if (pattern.compare(pos, perMill.length(), perMill) == 0) {
3295                    // Next handle characters which are appended directly.
3296                    if (multiplier != 1) {
3297                        // Too many percent/perMill characters
3298                        debug("Too many perMill characters")
3299                        status = U_MULTIPLE_PERMILL_SYMBOLS;
3300                        syntaxError(pattern,pos,parseError);
3301                        return;
3302                    }
3303                    affix->append(kQuote); // Encode percent/perMill
3304                    affix->append(kPatternPerMill); // Use unlocalized pattern char
3305                    multiplier = 1000;
3306                    pos += perMill.length();
3307                    break;
3308                } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) {
3309                    if (padPos >= 0 ||               // Multiple pad specifiers
3310                        (pos+1) == pattern.length()) { // Nothing after padEscape
3311                        debug("Multiple pad specifiers")
3312                        status = U_MULTIPLE_PAD_SPECIFIERS;
3313                        syntaxError(pattern,pos,parseError);
3314                        return;
3315                    }
3316                    padPos = pos;
3317                    pos += padEscape.length();
3318                    padChar = pattern.char32At(pos);
3319                    pos += U16_LENGTH(padChar);
3320                    break;
3321                } else if (pattern.compare(pos, minus.length(), minus) == 0) {
3322                    affix->append(kQuote); // Encode minus
3323                    affix->append(kPatternMinus);
3324                    pos += minus.length();
3325                    break;
3326                } else if (pattern.compare(pos, plus.length(), plus) == 0) {
3327                    affix->append(kQuote); // Encode plus
3328                    affix->append(kPatternPlus);
3329                    pos += plus.length();
3330                    break;
3331                }
3332                // Unquoted, non-special characters fall through to here, as
3333                // well as other code which needs to append something to the
3334                // affix.
3335                affix->append(ch);
3336                pos += U16_LENGTH(ch);
3337                break;
3338            case 3: // Prefix subpart, in quote
3339            case 4: // Suffix subpart, in quote
3340                // A quote within quotes indicates either the closing
3341                // quote or two quotes, which is a quote literal.  That is,
3342                // we have the second quote in 'do' or 'don''t'.
3343                if (ch == kQuote) {
3344                    ++pos;
3345                    if (pos < pattern.length() && pattern[pos] == kQuote) {
3346                        affix->append(kQuote); // Encode quote
3347                        // Fall through to append(ch)
3348                    } else {
3349                        subpart -= 2; // close quote
3350                        continue;
3351                    }
3352                }
3353                affix->append(ch);
3354                pos += U16_LENGTH(ch);
3355                break;
3356            }
3357        }
3358
3359        if (sub0Limit == 0) {
3360            sub0Limit = pattern.length();
3361        }
3362
3363        if (sub2Limit == 0) {
3364            sub2Limit = pattern.length();
3365        }
3366
3367        /* Handle patterns with no '0' pattern character.  These patterns
3368         * are legal, but must be recodified to make sense.  "##.###" ->
3369         * "#0.###".  ".###" -> ".0##".
3370         *
3371         * We allow patterns of the form "####" to produce a zeroDigitCount
3372         * of zero (got that?); although this seems like it might make it
3373         * possible for format() to produce empty strings, format() checks
3374         * for this condition and outputs a zero digit in this situation.
3375         * Having a zeroDigitCount of zero yields a minimum integer digits
3376         * of zero, which allows proper round-trip patterns.  We don't want
3377         * "#" to become "#0" when toPattern() is called (even though that's
3378         * what it really is, semantically).
3379         */
3380        if (zeroDigitCount == 0 && sigDigitCount == 0 &&
3381            digitLeftCount > 0 && decimalPos >= 0) {
3382            // Handle "###.###" and "###." and ".###"
3383            int n = decimalPos;
3384            if (n == 0)
3385                ++n; // Handle ".###"
3386            digitRightCount = digitLeftCount - n;
3387            digitLeftCount = n - 1;
3388            zeroDigitCount = 1;
3389        }
3390
3391        // Do syntax checking on the digits, decimal points, and quotes.
3392        if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
3393            (decimalPos >= 0 &&
3394             (sigDigitCount > 0 ||
3395              decimalPos < digitLeftCount ||
3396              decimalPos > (digitLeftCount + zeroDigitCount))) ||
3397            groupingCount == 0 || groupingCount2 == 0 ||
3398            (sigDigitCount > 0 && zeroDigitCount > 0) ||
3399            subpart > 2)
3400        { // subpart > 2 == unmatched quote
3401            debug("Syntax error")
3402            status = U_PATTERN_SYNTAX_ERROR;
3403            syntaxError(pattern,pos,parseError);
3404            return;
3405        }
3406
3407        // Make sure pad is at legal position before or after affix.
3408        if (padPos >= 0) {
3409            if (padPos == start) {
3410                padPos = kPadBeforePrefix;
3411            } else if (padPos+2 == sub0Start) {
3412                padPos = kPadAfterPrefix;
3413            } else if (padPos == sub0Limit) {
3414                padPos = kPadBeforeSuffix;
3415            } else if (padPos+2 == sub2Limit) {
3416                padPos = kPadAfterSuffix;
3417            } else {
3418                // Illegal pad position
3419                debug("Illegal pad position")
3420                status = U_ILLEGAL_PAD_POSITION;
3421                syntaxError(pattern,pos,parseError);
3422                return;
3423            }
3424        }
3425
3426        if (part == 0) {
3427            delete fPosPrefixPattern;
3428            delete fPosSuffixPattern;
3429            delete fNegPrefixPattern;
3430            delete fNegSuffixPattern;
3431            fPosPrefixPattern = new UnicodeString(prefix);
3432            /* test for NULL */
3433            if (fPosPrefixPattern == 0) {
3434                status = U_MEMORY_ALLOCATION_ERROR;
3435                return;
3436            }
3437            fPosSuffixPattern = new UnicodeString(suffix);
3438            /* test for NULL */
3439            if (fPosSuffixPattern == 0) {
3440                status = U_MEMORY_ALLOCATION_ERROR;
3441                delete fPosPrefixPattern;
3442                return;
3443            }
3444            fNegPrefixPattern = 0;
3445            fNegSuffixPattern = 0;
3446
3447            fUseExponentialNotation = (expDigits >= 0);
3448            if (fUseExponentialNotation) {
3449                fMinExponentDigits = expDigits;
3450            }
3451            fExponentSignAlwaysShown = expSignAlways;
3452            fIsCurrencyFormat = isCurrency;
3453            int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
3454            // The effectiveDecimalPos is the position the decimal is at or
3455            // would be at if there is no decimal.  Note that if
3456            // decimalPos<0, then digitTotalCount == digitLeftCount +
3457            // zeroDigitCount.
3458            int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
3459            UBool isSigDig = (sigDigitCount > 0);
3460            setSignificantDigitsUsed(isSigDig);
3461            if (isSigDig) {
3462                setMinimumSignificantDigits(sigDigitCount);
3463                setMaximumSignificantDigits(sigDigitCount + digitRightCount);
3464            } else {
3465                int32_t minInt = effectiveDecimalPos - digitLeftCount;
3466                setMinimumIntegerDigits(minInt);
3467                setMaximumIntegerDigits(fUseExponentialNotation
3468                    ? digitLeftCount + getMinimumIntegerDigits()
3469                    : kDoubleIntegerDigits);
3470                setMaximumFractionDigits(decimalPos >= 0
3471                    ? (digitTotalCount - decimalPos) : 0);
3472                setMinimumFractionDigits(decimalPos >= 0
3473                    ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
3474            }
3475            setGroupingUsed(groupingCount > 0);
3476            fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
3477            fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
3478                ? groupingCount2 : 0;
3479            fMultiplier = multiplier;
3480            setDecimalSeparatorAlwaysShown(decimalPos == 0
3481                    || decimalPos == digitTotalCount);
3482            if (padPos >= 0) {
3483                fPadPosition = (EPadPosition) padPos;
3484                // To compute the format width, first set up sub0Limit -
3485                // sub0Start.  Add in prefix/suffix length later.
3486
3487                // fFormatWidth = prefix.length() + suffix.length() +
3488                //    sub0Limit - sub0Start;
3489                fFormatWidth = sub0Limit - sub0Start;
3490                fPad = padChar;
3491            } else {
3492                fFormatWidth = 0;
3493            }
3494            if (roundingPos >= 0) {
3495                roundingInc.fDecimalAt = effectiveDecimalPos - roundingPos;
3496                if (fRoundingIncrement != NULL) {
3497                    *fRoundingIncrement = roundingInc;
3498                } else {
3499                    fRoundingIncrement = new DigitList(roundingInc);
3500                    /* test for NULL */
3501                    if (fRoundingIncrement == 0) {
3502                        status = U_MEMORY_ALLOCATION_ERROR;
3503                        delete fPosPrefixPattern;
3504                        delete fPosSuffixPattern;
3505                        return;
3506                    }
3507                }
3508                fRoundingDouble = fRoundingIncrement->getDouble();
3509                fRoundingMode = kRoundHalfEven;
3510            } else {
3511                setRoundingIncrement(0.0);
3512            }
3513        } else {
3514            fNegPrefixPattern = new UnicodeString(prefix);
3515            /* test for NULL */
3516            if (fNegPrefixPattern == 0) {
3517                status = U_MEMORY_ALLOCATION_ERROR;
3518                return;
3519            }
3520            fNegSuffixPattern = new UnicodeString(suffix);
3521            /* test for NULL */
3522            if (fNegSuffixPattern == 0) {
3523                delete fNegPrefixPattern;
3524                status = U_MEMORY_ALLOCATION_ERROR;
3525                return;
3526            }
3527        }
3528    }
3529
3530    if (pattern.length() == 0) {
3531        delete fNegPrefixPattern;
3532        delete fNegSuffixPattern;
3533        fNegPrefixPattern = NULL;
3534        fNegSuffixPattern = NULL;
3535        if (fPosPrefixPattern != NULL) {
3536            fPosPrefixPattern->remove();
3537        } else {
3538            fPosPrefixPattern = new UnicodeString();
3539            /* test for NULL */
3540            if (fPosPrefixPattern == 0) {
3541                status = U_MEMORY_ALLOCATION_ERROR;
3542                return;
3543            }
3544        }
3545        if (fPosSuffixPattern != NULL) {
3546            fPosSuffixPattern->remove();
3547        } else {
3548            fPosSuffixPattern = new UnicodeString();
3549            /* test for NULL */
3550            if (fPosSuffixPattern == 0) {
3551                delete fPosPrefixPattern;
3552                status = U_MEMORY_ALLOCATION_ERROR;
3553                return;
3554            }
3555        }
3556
3557        setMinimumIntegerDigits(0);
3558        setMaximumIntegerDigits(kDoubleIntegerDigits);
3559        setMinimumFractionDigits(0);
3560        setMaximumFractionDigits(kDoubleFractionDigits);
3561
3562        fUseExponentialNotation = FALSE;
3563        fIsCurrencyFormat = FALSE;
3564        setGroupingUsed(FALSE);
3565        fGroupingSize = 0;
3566        fGroupingSize2 = 0;
3567        fMultiplier = 1;
3568        setDecimalSeparatorAlwaysShown(FALSE);
3569        fFormatWidth = 0;
3570        setRoundingIncrement(0.0);
3571    }
3572
3573    // If there was no negative pattern, or if the negative pattern is
3574    // identical to the positive pattern, then prepend the minus sign to the
3575    // positive pattern to form the negative pattern.
3576    if (fNegPrefixPattern == NULL ||
3577        (*fNegPrefixPattern == *fPosPrefixPattern
3578         && *fNegSuffixPattern == *fPosSuffixPattern)) {
3579        _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern);
3580        if (fNegPrefixPattern == NULL) {
3581            fNegPrefixPattern = new UnicodeString();
3582            /* test for NULL */
3583            if (fNegPrefixPattern == 0) {
3584                status = U_MEMORY_ALLOCATION_ERROR;
3585                return;
3586            }
3587        } else {
3588            fNegPrefixPattern->remove();
3589        }
3590        fNegPrefixPattern->append(kQuote).append(kPatternMinus)
3591            .append(*fPosPrefixPattern);
3592    }
3593#ifdef FMT_DEBUG
3594    UnicodeString s;
3595    s.append("\"").append(pattern).append("\"->");
3596    debugout(s);
3597#endif
3598    expandAffixes();
3599    if (fFormatWidth > 0) {
3600        // Finish computing format width (see above)
3601        fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length();
3602    }
3603}
3604
3605/**
3606 * Sets the maximum number of digits allowed in the integer portion of a
3607 * number. This override limits the integer digit count to 309.
3608 * @see NumberFormat#setMaximumIntegerDigits
3609 */
3610void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
3611    NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
3612}
3613
3614/**
3615 * Sets the minimum number of digits allowed in the integer portion of a
3616 * number. This override limits the integer digit count to 309.
3617 * @see NumberFormat#setMinimumIntegerDigits
3618 */
3619void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
3620    NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
3621}
3622
3623/**
3624 * Sets the maximum number of digits allowed in the fraction portion of a
3625 * number. This override limits the fraction digit count to 340.
3626 * @see NumberFormat#setMaximumFractionDigits
3627 */
3628void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
3629    NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits));
3630}
3631
3632/**
3633 * Sets the minimum number of digits allowed in the fraction portion of a
3634 * number. This override limits the fraction digit count to 340.
3635 * @see NumberFormat#setMinimumFractionDigits
3636 */
3637void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
3638    NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits));
3639}
3640
3641int32_t DecimalFormat::getMinimumSignificantDigits() const {
3642    return fMinSignificantDigits;
3643}
3644
3645int32_t DecimalFormat::getMaximumSignificantDigits() const {
3646    return fMaxSignificantDigits;
3647}
3648
3649void DecimalFormat::setMinimumSignificantDigits(int32_t min) {
3650    if (min < 1) {
3651        min = 1;
3652    }
3653    // pin max sig dig to >= min
3654    int32_t max = _max(fMaxSignificantDigits, min);
3655    fMinSignificantDigits = min;
3656    fMaxSignificantDigits = max;
3657}
3658
3659void DecimalFormat::setMaximumSignificantDigits(int32_t max) {
3660    if (max < 1) {
3661        max = 1;
3662    }
3663    // pin min sig dig to 1..max
3664    U_ASSERT(fMinSignificantDigits >= 1);
3665    int32_t min = _min(fMinSignificantDigits, max);
3666    fMinSignificantDigits = min;
3667    fMaxSignificantDigits = max;
3668}
3669
3670UBool DecimalFormat::areSignificantDigitsUsed() const {
3671    return fUseSignificantDigits;
3672}
3673
3674void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
3675    fUseSignificantDigits = useSignificantDigits;
3676}
3677
3678void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
3679    // If we are a currency format, then modify our affixes to
3680    // encode the currency symbol for the given currency in our
3681    // locale, and adjust the decimal digits and rounding for the
3682    // given currency.
3683
3684    // Note: The code is ordered so that this object is *not changed*
3685    // until we are sure we are going to succeed.
3686
3687    // NULL or empty currency is *legal* and indicates no currency.
3688    UBool isCurr = (theCurrency && *theCurrency);
3689
3690    double rounding = 0.0;
3691    int32_t frac = 0;
3692    if (fIsCurrencyFormat && isCurr) {
3693        rounding = ucurr_getRoundingIncrement(theCurrency, &ec);
3694        frac = ucurr_getDefaultFractionDigits(theCurrency, &ec);
3695    }
3696
3697    NumberFormat::setCurrency(theCurrency, ec);
3698    if (U_FAILURE(ec)) return;
3699
3700    if (fIsCurrencyFormat) {
3701        // NULL or empty currency is *legal* and indicates no currency.
3702        if (isCurr) {
3703            setRoundingIncrement(rounding);
3704            setMinimumFractionDigits(frac);
3705            setMaximumFractionDigits(frac);
3706        }
3707        expandAffixes();
3708    }
3709}
3710
3711// Deprecated variant with no UErrorCode parameter
3712void DecimalFormat::setCurrency(const UChar* theCurrency) {
3713    UErrorCode ec = U_ZERO_ERROR;
3714    setCurrency(theCurrency, ec);
3715}
3716
3717void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& /*ec*/) const {
3718    const UChar* c = getCurrency();
3719    if (*c == 0) {
3720        const UnicodeString &intl =
3721            fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
3722        c = intl.getBuffer(); // ok for intl to go out of scope
3723    }
3724    u_strncpy(result, c, 3);
3725    result[3] = 0;
3726}
3727
3728/**
3729 * Return the number of fraction digits to display, or the total
3730 * number of digits for significant digit formats and exponential
3731 * formats.
3732 */
3733int32_t
3734DecimalFormat::precision(UBool isIntegral) const {
3735    if (areSignificantDigitsUsed()) {
3736        return getMaximumSignificantDigits();
3737    } else if (fUseExponentialNotation) {
3738        return getMinimumIntegerDigits() + getMaximumFractionDigits();
3739    } else {
3740        return isIntegral ? 0 : getMaximumFractionDigits();
3741    }
3742}
3743
3744U_NAMESPACE_END
3745
3746#endif /* #if !UCONFIG_NO_FORMATTING */
3747
3748//eof
3749