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