1/*
2*******************************************************************************
3* Copyright (C) 1997-2011, 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 "fphdlimp.h"
45#include "unicode/decimfmt.h"
46#include "unicode/choicfmt.h"
47#include "unicode/ucurr.h"
48#include "unicode/ustring.h"
49#include "unicode/dcfmtsym.h"
50#include "unicode/ures.h"
51#include "unicode/uchar.h"
52#include "unicode/uniset.h"
53#include "unicode/curramt.h"
54#include "unicode/currpinf.h"
55#include "unicode/plurrule.h"
56#include "uresimp.h"
57#include "ucurrimp.h"
58#include "charstr.h"
59#include "cmemory.h"
60#include "patternprops.h"
61#include "digitlst.h"
62#include "cstring.h"
63#include "umutex.h"
64#include "uassert.h"
65#include "putilimp.h"
66#include <math.h>
67#include "hash.h"
68#include "decfmtst.h"
69
70
71U_NAMESPACE_BEGIN
72
73/* For currency parsing purose,
74 * Need to remember all prefix patterns and suffix patterns of
75 * every currency format pattern,
76 * including the pattern of default currecny style
77 * and plural currency style. And the patterns are set through applyPattern.
78 */
79struct AffixPatternsForCurrency : public UMemory {
80	// negative prefix pattern
81	UnicodeString negPrefixPatternForCurrency;
82	// negative suffix pattern
83	UnicodeString negSuffixPatternForCurrency;
84	// positive prefix pattern
85	UnicodeString posPrefixPatternForCurrency;
86	// positive suffix pattern
87	UnicodeString posSuffixPatternForCurrency;
88	int8_t patternType;
89
90	AffixPatternsForCurrency(const UnicodeString& negPrefix,
91							 const UnicodeString& negSuffix,
92							 const UnicodeString& posPrefix,
93							 const UnicodeString& posSuffix,
94							 int8_t type) {
95		negPrefixPatternForCurrency = negPrefix;
96		negSuffixPatternForCurrency = negSuffix;
97		posPrefixPatternForCurrency = posPrefix;
98		posSuffixPatternForCurrency = posSuffix;
99		patternType = type;
100	}
101};
102
103/* affix for currency formatting when the currency sign in the pattern
104 * equals to 3, such as the pattern contains 3 currency sign or
105 * the formatter style is currency plural format style.
106 */
107struct AffixesForCurrency : public UMemory {
108	// negative prefix
109	UnicodeString negPrefixForCurrency;
110	// negative suffix
111	UnicodeString negSuffixForCurrency;
112	// positive prefix
113	UnicodeString posPrefixForCurrency;
114	// positive suffix
115	UnicodeString posSuffixForCurrency;
116
117	int32_t formatWidth;
118
119	AffixesForCurrency(const UnicodeString& negPrefix,
120					   const UnicodeString& negSuffix,
121					   const UnicodeString& posPrefix,
122					   const UnicodeString& posSuffix) {
123		negPrefixForCurrency = negPrefix;
124		negSuffixForCurrency = negSuffix;
125		posPrefixForCurrency = posPrefix;
126		posSuffixForCurrency = posSuffix;
127	}
128};
129
130U_CDECL_BEGIN
131
132/**
133 * @internal ICU 4.2
134 */
135static UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2);
136
137/**
138 * @internal ICU 4.2
139 */
140static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2);
141
142
143static UBool
144U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2) {
145    const AffixesForCurrency* affix_1 =
146        (AffixesForCurrency*)val1.pointer;
147    const AffixesForCurrency* affix_2 =
148        (AffixesForCurrency*)val2.pointer;
149    return affix_1->negPrefixForCurrency == affix_2->negPrefixForCurrency &&
150           affix_1->negSuffixForCurrency == affix_2->negSuffixForCurrency &&
151           affix_1->posPrefixForCurrency == affix_2->posPrefixForCurrency &&
152           affix_1->posSuffixForCurrency == affix_2->posSuffixForCurrency;
153}
154
155
156static UBool
157U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) {
158    const AffixPatternsForCurrency* affix_1 =
159        (AffixPatternsForCurrency*)val1.pointer;
160    const AffixPatternsForCurrency* affix_2 =
161        (AffixPatternsForCurrency*)val2.pointer;
162    return affix_1->negPrefixPatternForCurrency ==
163           affix_2->negPrefixPatternForCurrency &&
164           affix_1->negSuffixPatternForCurrency ==
165           affix_2->negSuffixPatternForCurrency &&
166           affix_1->posPrefixPatternForCurrency ==
167           affix_2->posPrefixPatternForCurrency &&
168           affix_1->posSuffixPatternForCurrency ==
169           affix_2->posSuffixPatternForCurrency &&
170           affix_1->patternType == affix_2->patternType;
171}
172
173U_CDECL_END
174
175
176//#define FMT_DEBUG
177
178#ifdef FMT_DEBUG
179#include <stdio.h>
180static void debugout(UnicodeString s) {
181    char buf[2000];
182    s.extract((int32_t) 0, s.length(), buf);
183    printf("%s\n", buf);
184}
185#define debug(x) printf("%s\n", x);
186#else
187#define debugout(x)
188#define debug(x)
189#endif
190
191
192
193// *****************************************************************************
194// class DecimalFormat
195// *****************************************************************************
196
197UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
198
199// Constants for characters used in programmatic (unlocalized) patterns.
200#define kPatternZeroDigit            ((UChar)0x0030) /*'0'*/
201#define kPatternSignificantDigit     ((UChar)0x0040) /*'@'*/
202#define kPatternGroupingSeparator    ((UChar)0x002C) /*','*/
203#define kPatternDecimalSeparator     ((UChar)0x002E) /*'.'*/
204#define kPatternPerMill              ((UChar)0x2030)
205#define kPatternPercent              ((UChar)0x0025) /*'%'*/
206#define kPatternDigit                ((UChar)0x0023) /*'#'*/
207#define kPatternSeparator            ((UChar)0x003B) /*';'*/
208#define kPatternExponent             ((UChar)0x0045) /*'E'*/
209#define kPatternPlus                 ((UChar)0x002B) /*'+'*/
210#define kPatternMinus                ((UChar)0x002D) /*'-'*/
211#define kPatternPadEscape            ((UChar)0x002A) /*'*'*/
212#define kQuote                       ((UChar)0x0027) /*'\''*/
213/**
214 * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
215 * is used in patterns and substitued with either the currency symbol,
216 * or if it is doubled, with the international currency symbol.  If the
217 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
218 * replaced with the monetary decimal separator.
219 */
220#define kCurrencySign                ((UChar)0x00A4)
221#define kDefaultPad                  ((UChar)0x0020) /* */
222
223const int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
224const int32_t DecimalFormat::kDoubleFractionDigits = 340;
225
226const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
227
228/**
229 * These are the tags we expect to see in normal resource bundle files associated
230 * with a locale.
231 */
232const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used
233static const char fgNumberElements[]="NumberElements";
234static const char fgLatn[]="latn";
235static const char fgPatterns[]="patterns";
236static const char fgDecimalFormat[]="decimalFormat";
237static const char fgCurrencyFormat[]="currencyFormat";
238static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
239
240inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
241inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
242
243//------------------------------------------------------------------------------
244// Constructs a DecimalFormat instance in the default locale.
245
246DecimalFormat::DecimalFormat(UErrorCode& status) {
247    init();
248    UParseError parseError;
249    construct(status, parseError);
250}
251
252//------------------------------------------------------------------------------
253// Constructs a DecimalFormat instance with the specified number format
254// pattern in the default locale.
255
256DecimalFormat::DecimalFormat(const UnicodeString& pattern,
257                             UErrorCode& status) {
258    init();
259    UParseError parseError;
260    construct(status, parseError, &pattern);
261}
262
263//------------------------------------------------------------------------------
264// Constructs a DecimalFormat instance with the specified number format
265// pattern and the number format symbols in the default locale.  The
266// created instance owns the symbols.
267
268DecimalFormat::DecimalFormat(const UnicodeString& pattern,
269                             DecimalFormatSymbols* symbolsToAdopt,
270                             UErrorCode& status) {
271    init();
272    UParseError parseError;
273    if (symbolsToAdopt == NULL)
274        status = U_ILLEGAL_ARGUMENT_ERROR;
275    construct(status, parseError, &pattern, symbolsToAdopt);
276}
277
278DecimalFormat::DecimalFormat(  const UnicodeString& pattern,
279                    DecimalFormatSymbols* symbolsToAdopt,
280                    UParseError& parseErr,
281                    UErrorCode& status) {
282    init();
283    if (symbolsToAdopt == NULL)
284        status = U_ILLEGAL_ARGUMENT_ERROR;
285    construct(status,parseErr, &pattern, symbolsToAdopt);
286}
287
288//------------------------------------------------------------------------------
289// Constructs a DecimalFormat instance with the specified number format
290// pattern and the number format symbols in the default locale.  The
291// created instance owns the clone of the symbols.
292
293DecimalFormat::DecimalFormat(const UnicodeString& pattern,
294                             const DecimalFormatSymbols& symbols,
295                             UErrorCode& status) {
296    init();
297    UParseError parseError;
298    construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
299}
300
301//------------------------------------------------------------------------------
302// Constructs a DecimalFormat instance with the specified number format
303// pattern, the number format symbols, and the number format style.
304// The created instance owns the clone of the symbols.
305
306DecimalFormat::DecimalFormat(const UnicodeString& pattern,
307                             DecimalFormatSymbols* symbolsToAdopt,
308                             UNumberFormatStyle style,
309                             UErrorCode& status) {
310    init();
311    fStyle = style;
312    UParseError parseError;
313    construct(status, parseError, &pattern, symbolsToAdopt);
314}
315
316//-----------------------------------------------------------------------------
317// Common DecimalFormat initialization.
318//    Put all fields of an uninitialized object into a known state.
319//    Common code, shared by all constructors.
320void
321DecimalFormat::init() {
322    fPosPrefixPattern = 0;
323    fPosSuffixPattern = 0;
324    fNegPrefixPattern = 0;
325    fNegSuffixPattern = 0;
326    fCurrencyChoice = 0;
327    fMultiplier = NULL;
328    fGroupingSize = 0;
329    fGroupingSize2 = 0;
330    fDecimalSeparatorAlwaysShown = FALSE;
331    fSymbols = NULL;
332    fUseSignificantDigits = FALSE;
333    fMinSignificantDigits = 1;
334    fMaxSignificantDigits = 6;
335    fUseExponentialNotation = FALSE;
336    fMinExponentDigits = 0;
337    fExponentSignAlwaysShown = FALSE;
338    fRoundingIncrement = 0;
339    fRoundingMode = kRoundHalfEven;
340    fPad = 0;
341    fFormatWidth = 0;
342    fPadPosition = kPadBeforePrefix;
343    fStyle = UNUM_DECIMAL;
344    fCurrencySignCount = 0;
345    fAffixPatternsForCurrency = NULL;
346    fAffixesForCurrency = NULL;
347    fPluralAffixesForCurrency = NULL;
348    fCurrencyPluralInfo = NULL;
349}
350
351//------------------------------------------------------------------------------
352// Constructs a DecimalFormat instance with the specified number format
353// pattern and the number format symbols in the desired locale.  The
354// created instance owns the symbols.
355
356void
357DecimalFormat::construct(UErrorCode&             status,
358                         UParseError&           parseErr,
359                         const UnicodeString*   pattern,
360                         DecimalFormatSymbols*  symbolsToAdopt)
361{
362    fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!!
363    fRoundingIncrement = NULL;
364    fRoundingMode = kRoundHalfEven;
365    fPad = kPatternPadEscape;
366    fPadPosition = kPadBeforePrefix;
367    if (U_FAILURE(status))
368        return;
369
370    fPosPrefixPattern = fPosSuffixPattern = NULL;
371    fNegPrefixPattern = fNegSuffixPattern = NULL;
372    setMultiplier(1);
373    fGroupingSize = 3;
374    fGroupingSize2 = 0;
375    fDecimalSeparatorAlwaysShown = FALSE;
376    fUseExponentialNotation = FALSE;
377    fMinExponentDigits = 0;
378
379    if (fSymbols == NULL)
380    {
381        fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status);
382        /* test for NULL */
383        if (fSymbols == 0) {
384            status = U_MEMORY_ALLOCATION_ERROR;
385            return;
386        }
387    }
388
389    UnicodeString str;
390    // Uses the default locale's number format pattern if there isn't
391    // one specified.
392    if (pattern == NULL)
393    {
394        int32_t len = 0;
395        UResourceBundle *resource = ures_open(NULL, Locale::getDefault().getName(), &status);
396
397        resource = ures_getByKeyWithFallback(resource, fgNumberElements, resource, &status);
398        // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn".
399        resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status);
400        resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
401        const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
402        str.setTo(TRUE, resStr, len);
403        pattern = &str;
404        ures_close(resource);
405    }
406
407    if (U_FAILURE(status))
408    {
409        return;
410    }
411
412    if (pattern->indexOf((UChar)kCurrencySign) >= 0) {
413        // If it looks like we are going to use a currency pattern
414        // then do the time consuming lookup.
415        setCurrencyForSymbols();
416    } else {
417        setCurrencyInternally(NULL, status);
418    }
419
420    const UnicodeString* patternUsed;
421    UnicodeString currencyPluralPatternForOther;
422    // apply pattern
423    if (fStyle == UNUM_CURRENCY_PLURAL) {
424        fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
425        if (U_FAILURE(status)) {
426            return;
427        }
428
429        // the pattern used in format is not fixed until formatting,
430        // in which, the number is known and
431        // will be used to pick the right pattern based on plural count.
432        // Here, set the pattern as the pattern of plural count == "other".
433        // For most locale, the patterns are probably the same for all
434        // plural count. If not, the right pattern need to be re-applied
435        // during format.
436        fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5), currencyPluralPatternForOther);
437        patternUsed = &currencyPluralPatternForOther;
438        // TODO: not needed?
439        setCurrencyForSymbols();
440
441    } else {
442        patternUsed = pattern;
443    }
444
445    if (patternUsed->indexOf(kCurrencySign) != -1) {
446        // initialize for currency, not only for plural format,
447        // but also for mix parsing
448        if (fCurrencyPluralInfo == NULL) {
449           fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
450           if (U_FAILURE(status)) {
451               return;
452           }
453        }
454        // need it for mix parsing
455        setupCurrencyAffixPatterns(status);
456        // expanded affixes for plural names
457        if (patternUsed->indexOf(fgTripleCurrencySign, 3, 0) != -1) {
458            setupCurrencyAffixes(*patternUsed, TRUE, TRUE, status);
459        }
460    }
461
462    applyPatternWithoutExpandAffix(*patternUsed,FALSE, parseErr, status);
463
464    // expand affixes
465    if (fCurrencySignCount != fgCurrencySignCountInPluralFormat) {
466        expandAffixAdjustWidth(NULL);
467    }
468
469    // If it was a currency format, apply the appropriate rounding by
470    // resetting the currency. NOTE: this copies fCurrency on top of itself.
471    if (fCurrencySignCount > fgCurrencySignCountZero) {
472        setCurrencyInternally(getCurrency(), status);
473    }
474}
475
476
477void
478DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) {
479    if (U_FAILURE(status)) {
480        return;
481    }
482    UParseError parseErr;
483    fAffixPatternsForCurrency = initHashForAffixPattern(status);
484    if (U_FAILURE(status)) {
485        return;
486    }
487
488    // Save the default currency patterns of this locale.
489    // Here, chose onlyApplyPatternWithoutExpandAffix without
490    // expanding the affix patterns into affixes.
491    UnicodeString currencyPattern;
492    UErrorCode error = U_ZERO_ERROR;
493
494    UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(), &error);
495    resource = ures_getByKeyWithFallback(resource, fgNumberElements, resource, &error);
496    // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn".
497    resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &error);
498    resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
499    int32_t patLen = 0;
500    const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,  &patLen, &error);
501    ures_close(resource);
502
503    if (U_SUCCESS(error)) {
504        applyPatternWithoutExpandAffix(UnicodeString(patResStr, patLen), false,
505                                       parseErr, status);
506        AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
507                                                    *fNegPrefixPattern,
508                                                    *fNegSuffixPattern,
509                                                    *fPosPrefixPattern,
510                                                    *fPosSuffixPattern,
511                                                    UCURR_SYMBOL_NAME);
512        fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, status);
513    }
514
515    // save the unique currency plural patterns of this locale.
516    Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern;
517    const UHashElement* element = NULL;
518    int32_t pos = -1;
519    Hashtable pluralPatternSet;
520    while ((element = pluralPtn->nextElement(pos)) != NULL) {
521        const UHashTok valueTok = element->value;
522        const UnicodeString* value = (UnicodeString*)valueTok.pointer;
523        const UHashTok keyTok = element->key;
524        const UnicodeString* key = (UnicodeString*)keyTok.pointer;
525        if (pluralPatternSet.geti(*value) != 1) {
526            pluralPatternSet.puti(*value, 1, status);
527            applyPatternWithoutExpandAffix(*value, false, parseErr, status);
528            AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
529                                                    *fNegPrefixPattern,
530                                                    *fNegSuffixPattern,
531                                                    *fPosPrefixPattern,
532                                                    *fPosSuffixPattern,
533                                                    UCURR_LONG_NAME);
534            fAffixPatternsForCurrency->put(*key, affixPtn, status);
535        }
536    }
537}
538
539
540void
541DecimalFormat::setupCurrencyAffixes(const UnicodeString& pattern,
542                                    UBool setupForCurrentPattern,
543                                    UBool setupForPluralPattern,
544                                    UErrorCode& status) {
545    if (U_FAILURE(status)) {
546        return;
547    }
548    UParseError parseErr;
549    if (setupForCurrentPattern) {
550        if (fAffixesForCurrency) {
551            deleteHashForAffix(fAffixesForCurrency);
552        }
553        fAffixesForCurrency = initHashForAffix(status);
554        if (U_SUCCESS(status)) {
555            applyPatternWithoutExpandAffix(pattern, false, parseErr, status);
556            const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules();
557            StringEnumeration* keywords = pluralRules->getKeywords(status);
558            if (U_SUCCESS(status)) {
559                const UnicodeString* pluralCount;
560                while ((pluralCount = keywords->snext(status)) != NULL) {
561                    if ( U_SUCCESS(status) ) {
562                        expandAffixAdjustWidth(pluralCount);
563                        AffixesForCurrency* affix = new AffixesForCurrency(
564                            fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix);
565                        fAffixesForCurrency->put(*pluralCount, affix, status);
566                    }
567                }
568            }
569            delete keywords;
570        }
571    }
572
573    if (U_FAILURE(status)) {
574        return;
575    }
576
577    if (setupForPluralPattern) {
578        if (fPluralAffixesForCurrency) {
579            deleteHashForAffix(fPluralAffixesForCurrency);
580        }
581        fPluralAffixesForCurrency = initHashForAffix(status);
582        if (U_SUCCESS(status)) {
583            const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules();
584            StringEnumeration* keywords = pluralRules->getKeywords(status);
585            if (U_SUCCESS(status)) {
586                const UnicodeString* pluralCount;
587                while ((pluralCount = keywords->snext(status)) != NULL) {
588                    if ( U_SUCCESS(status) ) {
589                        UnicodeString ptn;
590                        fCurrencyPluralInfo->getCurrencyPluralPattern(*pluralCount, ptn);
591                        applyPatternInternally(*pluralCount, ptn, false, parseErr, status);
592                        AffixesForCurrency* affix = new AffixesForCurrency(
593                            fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix);
594                        fPluralAffixesForCurrency->put(*pluralCount, affix, status);
595                    }
596                }
597            }
598            delete keywords;
599        }
600    }
601}
602
603
604//------------------------------------------------------------------------------
605
606DecimalFormat::~DecimalFormat()
607{
608    delete fPosPrefixPattern;
609    delete fPosSuffixPattern;
610    delete fNegPrefixPattern;
611    delete fNegSuffixPattern;
612    delete fCurrencyChoice;
613    delete fMultiplier;
614    delete fSymbols;
615    delete fRoundingIncrement;
616    deleteHashForAffixPattern();
617    deleteHashForAffix(fAffixesForCurrency);
618    deleteHashForAffix(fPluralAffixesForCurrency);
619    delete fCurrencyPluralInfo;
620}
621
622//------------------------------------------------------------------------------
623// copy constructor
624
625DecimalFormat::DecimalFormat(const DecimalFormat &source) :
626    NumberFormat(source) {
627    init();
628    *this = source;
629}
630
631//------------------------------------------------------------------------------
632// assignment operator
633
634static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) {
635    if (source == NULL) {
636        delete *pdest;
637        *pdest = NULL;
638    } else if (*pdest == NULL) {
639        *pdest = new UnicodeString(*source);
640    } else {
641        **pdest  = *source;
642    }
643}
644
645DecimalFormat&
646DecimalFormat::operator=(const DecimalFormat& rhs)
647{
648    if(this != &rhs) {
649        NumberFormat::operator=(rhs);
650        fPositivePrefix = rhs.fPositivePrefix;
651        fPositiveSuffix = rhs.fPositiveSuffix;
652        fNegativePrefix = rhs.fNegativePrefix;
653        fNegativeSuffix = rhs.fNegativeSuffix;
654        _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
655        _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
656        _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
657        _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
658        if (rhs.fCurrencyChoice == 0) {
659            delete fCurrencyChoice;
660            fCurrencyChoice = 0;
661        } else {
662            fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone();
663        }
664        setRoundingIncrement(rhs.getRoundingIncrement());
665        fRoundingMode = rhs.fRoundingMode;
666        setMultiplier(rhs.getMultiplier());
667        fGroupingSize = rhs.fGroupingSize;
668        fGroupingSize2 = rhs.fGroupingSize2;
669        fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
670        if(fSymbols == NULL) {
671            fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
672        } else {
673            *fSymbols = *rhs.fSymbols;
674        }
675        fUseExponentialNotation = rhs.fUseExponentialNotation;
676        fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
677        /*Bertrand A. D. Update 98.03.17*/
678        fCurrencySignCount = rhs.fCurrencySignCount;
679        /*end of Update*/
680        fMinExponentDigits = rhs.fMinExponentDigits;
681
682        /* sfb 990629 */
683        fFormatWidth = rhs.fFormatWidth;
684        fPad = rhs.fPad;
685        fPadPosition = rhs.fPadPosition;
686        /* end sfb */
687        fMinSignificantDigits = rhs.fMinSignificantDigits;
688        fMaxSignificantDigits = rhs.fMaxSignificantDigits;
689        fUseSignificantDigits = rhs.fUseSignificantDigits;
690        fFormatPattern = rhs.fFormatPattern;
691        fStyle = rhs.fStyle;
692        fCurrencySignCount = rhs.fCurrencySignCount;
693        if (rhs.fCurrencyPluralInfo) {
694            delete fCurrencyPluralInfo;
695            fCurrencyPluralInfo = rhs.fCurrencyPluralInfo->clone();
696        }
697        if (rhs.fAffixPatternsForCurrency) {
698            UErrorCode status = U_ZERO_ERROR;
699            deleteHashForAffixPattern();
700            fAffixPatternsForCurrency = initHashForAffixPattern(status);
701            copyHashForAffixPattern(rhs.fAffixPatternsForCurrency,
702                                    fAffixPatternsForCurrency, status);
703        }
704        if (rhs.fAffixesForCurrency) {
705            UErrorCode status = U_ZERO_ERROR;
706            deleteHashForAffix(fAffixesForCurrency);
707            fAffixesForCurrency = initHashForAffixPattern(status);
708            copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, status);
709        }
710        if (rhs.fPluralAffixesForCurrency) {
711            UErrorCode status = U_ZERO_ERROR;
712            deleteHashForAffix(fPluralAffixesForCurrency);
713            fPluralAffixesForCurrency = initHashForAffixPattern(status);
714            copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCurrency, status);
715        }
716    }
717    return *this;
718}
719
720//------------------------------------------------------------------------------
721
722UBool
723DecimalFormat::operator==(const Format& that) const
724{
725    if (this == &that)
726        return TRUE;
727
728    // NumberFormat::operator== guarantees this cast is safe
729    const DecimalFormat* other = (DecimalFormat*)&that;
730
731#ifdef FMT_DEBUG
732    // This code makes it easy to determine why two format objects that should
733    // be equal aren't.
734    UBool first = TRUE;
735    if (!NumberFormat::operator==(that)) {
736        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
737        debug("NumberFormat::!=");
738    } else {
739    if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null
740              fPositivePrefix == other->fPositivePrefix)
741           || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
742               *fPosPrefixPattern  == *other->fPosPrefixPattern))) {
743        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
744        debug("Pos Prefix !=");
745    }
746    if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null
747           fPositiveSuffix == other->fPositiveSuffix)
748          || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
749              *fPosSuffixPattern  == *other->fPosSuffixPattern))) {
750        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
751        debug("Pos Suffix !=");
752    }
753    if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null
754           fNegativePrefix == other->fNegativePrefix)
755          || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
756              *fNegPrefixPattern  == *other->fNegPrefixPattern))) {
757        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
758        debug("Neg Prefix ");
759        if (fNegPrefixPattern == NULL) {
760            debug("NULL(");
761            debugout(fNegativePrefix);
762            debug(")");
763        } else {
764            debugout(*fNegPrefixPattern);
765        }
766        debug(" != ");
767        if (other->fNegPrefixPattern == NULL) {
768            debug("NULL(");
769            debugout(other->fNegativePrefix);
770            debug(")");
771        } else {
772            debugout(*other->fNegPrefixPattern);
773        }
774    }
775    if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null
776           fNegativeSuffix == other->fNegativeSuffix)
777          || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
778              *fNegSuffixPattern  == *other->fNegSuffixPattern))) {
779        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
780        debug("Neg Suffix ");
781        if (fNegSuffixPattern == NULL) {
782            debug("NULL(");
783            debugout(fNegativeSuffix);
784            debug(")");
785        } else {
786            debugout(*fNegSuffixPattern);
787        }
788        debug(" != ");
789        if (other->fNegSuffixPattern == NULL) {
790            debug("NULL(");
791            debugout(other->fNegativeSuffix);
792            debug(")");
793        } else {
794            debugout(*other->fNegSuffixPattern);
795        }
796    }
797    if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
798          || (fRoundingIncrement != NULL &&
799              other->fRoundingIncrement != NULL &&
800              *fRoundingIncrement == *other->fRoundingIncrement))) {
801        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
802        debug("Rounding Increment !=");
803              }
804    if (getMultiplier() != other->getMultiplier()) {
805        if (first) { printf("[ "); first = FALSE; }
806        printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier());
807    }
808    if (fGroupingSize != other->fGroupingSize) {
809        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
810        printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
811    }
812    if (fGroupingSize2 != other->fGroupingSize2) {
813        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
814        printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2);
815    }
816    if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
817        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
818        printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown);
819    }
820    if (fUseExponentialNotation != other->fUseExponentialNotation) {
821        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
822        debug("Use Exp !=");
823    }
824    if (!(!fUseExponentialNotation ||
825          fMinExponentDigits != other->fMinExponentDigits)) {
826        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
827        debug("Exp Digits !=");
828    }
829    if (*fSymbols != *(other->fSymbols)) {
830        if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
831        debug("Symbols !=");
832    }
833    // TODO Add debug stuff for significant digits here
834    if (fUseSignificantDigits != other->fUseSignificantDigits) {
835        debug("fUseSignificantDigits !=");
836    }
837    if (fUseSignificantDigits &&
838        fMinSignificantDigits != other->fMinSignificantDigits) {
839        debug("fMinSignificantDigits !=");
840    }
841    if (fUseSignificantDigits &&
842        fMaxSignificantDigits != other->fMaxSignificantDigits) {
843        debug("fMaxSignificantDigits !=");
844    }
845
846    if (!first) { printf(" ]"); }
847    if (fCurrencySignCount != other->fCurrencySignCount) {
848        debug("fCurrencySignCount !=");
849    }
850    if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) {
851        debug("fCurrencyPluralInfo == ");
852        if (fCurrencyPluralInfo == NULL) {
853            debug("fCurrencyPluralInfo == NULL");
854        }
855    }
856    if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
857         *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) {
858        debug("fCurrencyPluralInfo !=");
859    }
860    if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL ||
861        fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) {
862        debug("fCurrencyPluralInfo one NULL, the other not");
863    }
864    if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) {
865        debug("fCurrencyPluralInfo == ");
866    }
867    }
868#endif
869
870    return (NumberFormat::operator==(that) &&
871            ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ?
872            (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) :
873            (((fPosPrefixPattern == other->fPosPrefixPattern && // both null
874              fPositivePrefix == other->fPositivePrefix)
875             || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
876                 *fPosPrefixPattern  == *other->fPosPrefixPattern)) &&
877            ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
878              fPositiveSuffix == other->fPositiveSuffix)
879             || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
880                 *fPosSuffixPattern  == *other->fPosSuffixPattern)) &&
881            ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
882              fNegativePrefix == other->fNegativePrefix)
883             || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
884                 *fNegPrefixPattern  == *other->fNegPrefixPattern)) &&
885            ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
886              fNegativeSuffix == other->fNegativeSuffix)
887             || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
888                 *fNegSuffixPattern  == *other->fNegSuffixPattern)))) &&
889            ((fRoundingIncrement == other->fRoundingIncrement) // both null
890             || (fRoundingIncrement != NULL &&
891                 other->fRoundingIncrement != NULL &&
892                 *fRoundingIncrement == *other->fRoundingIncrement)) &&
893        getMultiplier() == other->getMultiplier() &&
894        fGroupingSize == other->fGroupingSize &&
895        fGroupingSize2 == other->fGroupingSize2 &&
896        fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
897        fUseExponentialNotation == other->fUseExponentialNotation &&
898        (!fUseExponentialNotation ||
899         fMinExponentDigits == other->fMinExponentDigits) &&
900        *fSymbols == *(other->fSymbols) &&
901        fUseSignificantDigits == other->fUseSignificantDigits &&
902        (!fUseSignificantDigits ||
903         (fMinSignificantDigits == other->fMinSignificantDigits &&
904          fMaxSignificantDigits == other->fMaxSignificantDigits)) &&
905        fCurrencySignCount == other->fCurrencySignCount &&
906        ((fCurrencyPluralInfo == other->fCurrencyPluralInfo &&
907          fCurrencyPluralInfo == NULL) ||
908         (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
909         *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo))));
910}
911
912//------------------------------------------------------------------------------
913
914Format*
915DecimalFormat::clone() const
916{
917    return new DecimalFormat(*this);
918}
919
920//------------------------------------------------------------------------------
921
922UnicodeString&
923DecimalFormat::format(int32_t number,
924                      UnicodeString& appendTo,
925                      FieldPosition& fieldPosition) const
926{
927    return format((int64_t)number, appendTo, fieldPosition);
928}
929
930UnicodeString&
931DecimalFormat::format(int32_t number,
932                      UnicodeString& appendTo,
933                      FieldPositionIterator* posIter,
934                      UErrorCode& status) const
935{
936    return format((int64_t)number, appendTo, posIter, status);
937}
938
939//------------------------------------------------------------------------------
940
941UnicodeString&
942DecimalFormat::format(int64_t number,
943                      UnicodeString& appendTo,
944                      FieldPosition& fieldPosition) const
945{
946    FieldPositionOnlyHandler handler(fieldPosition);
947    return _format(number, appendTo, handler);
948}
949
950UnicodeString&
951DecimalFormat::format(int64_t number,
952                      UnicodeString& appendTo,
953                      FieldPositionIterator* posIter,
954                      UErrorCode& status) const
955{
956    FieldPositionIteratorHandler handler(posIter, status);
957    return _format(number, appendTo, handler);
958}
959
960UnicodeString&
961DecimalFormat::_format(int64_t number,
962                       UnicodeString& appendTo,
963                       FieldPositionHandler& handler) const
964{
965    UErrorCode status = U_ZERO_ERROR;
966    DigitList digits;
967    digits.set(number);
968    return _format(digits, appendTo, handler, status);
969}
970
971//------------------------------------------------------------------------------
972
973UnicodeString&
974DecimalFormat::format(  double number,
975                        UnicodeString& appendTo,
976                        FieldPosition& fieldPosition) const
977{
978    FieldPositionOnlyHandler handler(fieldPosition);
979    return _format(number, appendTo, handler);
980}
981
982UnicodeString&
983DecimalFormat::format(  double number,
984                        UnicodeString& appendTo,
985                        FieldPositionIterator* posIter,
986                        UErrorCode& status) const
987{
988  FieldPositionIteratorHandler handler(posIter, status);
989  return _format(number, appendTo, handler);
990}
991
992UnicodeString&
993DecimalFormat::_format( double number,
994                        UnicodeString& appendTo,
995                        FieldPositionHandler& handler) const
996{
997    // Special case for NaN, sets the begin and end index to be the
998    // the string length of localized name of NaN.
999    // TODO:  let NaNs go through DigitList.
1000    if (uprv_isNaN(number))
1001    {
1002        int begin = appendTo.length();
1003        appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1004
1005        handler.addAttribute(kIntegerField, begin, appendTo.length());
1006
1007        addPadding(appendTo, handler, 0, 0);
1008        return appendTo;
1009    }
1010
1011    UErrorCode status = U_ZERO_ERROR;
1012    DigitList digits;
1013    digits.set(number);
1014    _format(digits, appendTo, handler, status);
1015    // No way to return status from here.
1016    return appendTo;
1017}
1018
1019//------------------------------------------------------------------------------
1020
1021
1022UnicodeString&
1023DecimalFormat::format(const StringPiece &number,
1024                      UnicodeString &toAppendTo,
1025                      FieldPositionIterator *posIter,
1026                      UErrorCode &status) const
1027{
1028    DigitList   dnum;
1029    dnum.set(number, status);
1030    if (U_FAILURE(status)) {
1031        return toAppendTo;
1032    }
1033    FieldPositionIteratorHandler handler(posIter, status);
1034    _format(dnum, toAppendTo, handler, status);
1035    return toAppendTo;
1036}
1037
1038
1039UnicodeString&
1040DecimalFormat::format(const DigitList &number,
1041                      UnicodeString &appendTo,
1042                      FieldPositionIterator *posIter,
1043                      UErrorCode &status) const {
1044    FieldPositionIteratorHandler handler(posIter, status);
1045    _format(number, appendTo, handler, status);
1046    return appendTo;
1047}
1048
1049
1050
1051UnicodeString&
1052DecimalFormat::format(const DigitList &number,
1053                     UnicodeString& appendTo,
1054                     FieldPosition& pos,
1055                     UErrorCode &status) const {
1056    FieldPositionOnlyHandler handler(pos);
1057    _format(number, appendTo, handler, status);
1058    return appendTo;
1059}
1060
1061
1062
1063UnicodeString&
1064DecimalFormat::_format(const DigitList &number,
1065                        UnicodeString& appendTo,
1066                        FieldPositionHandler& handler,
1067                        UErrorCode &status) const
1068{
1069    // Special case for NaN, sets the begin and end index to be the
1070    // the string length of localized name of NaN.
1071    if (number.isNaN())
1072    {
1073        int begin = appendTo.length();
1074        appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1075
1076        handler.addAttribute(kIntegerField, begin, appendTo.length());
1077
1078        addPadding(appendTo, handler, 0, 0);
1079        return appendTo;
1080    }
1081
1082    // Do this BEFORE checking to see if value is infinite or negative! Sets the
1083    // begin and end index to be length of the string composed of
1084    // localized name of Infinite and the positive/negative localized
1085    // signs.
1086
1087    DigitList adjustedNum(number);  // Copy, so we do not alter the original.
1088    adjustedNum.setRoundingMode(fRoundingMode);
1089    if (fMultiplier != NULL) {
1090        adjustedNum.mult(*fMultiplier, status);
1091    }
1092
1093    /*
1094     * Note: sign is important for zero as well as non-zero numbers.
1095     * Proper detection of -0.0 is needed to deal with the
1096     * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
1097     */
1098    UBool isNegative = !adjustedNum.isPositive();
1099
1100    // Apply rounding after multiplier
1101
1102    adjustedNum.fContext.status &= ~DEC_Inexact;
1103    if (fRoundingIncrement != NULL) {
1104        adjustedNum.div(*fRoundingIncrement, status);
1105        adjustedNum.toIntegralValue();
1106        adjustedNum.mult(*fRoundingIncrement, status);
1107        adjustedNum.trim();
1108    }
1109    if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) {
1110        status = U_FORMAT_INEXACT_ERROR;
1111        return appendTo;
1112    }
1113
1114
1115    // Special case for INFINITE,
1116    if (adjustedNum.isInfinite()) {
1117        int32_t prefixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, TRUE);
1118
1119        int begin = appendTo.length();
1120        appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
1121
1122        handler.addAttribute(kIntegerField, begin, appendTo.length());
1123
1124        int32_t suffixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, FALSE);
1125
1126        addPadding(appendTo, handler, prefixLen, suffixLen);
1127        return appendTo;
1128    }
1129
1130    if (fUseExponentialNotation || areSignificantDigitsUsed()) {
1131        int32_t sigDigits = precision();
1132        if (sigDigits > 0) {
1133            adjustedNum.round(sigDigits);
1134        }
1135    } else {
1136        // Fixed point format.  Round to a set number of fraction digits.
1137        int32_t numFractionDigits = precision();
1138        adjustedNum.roundFixedPoint(numFractionDigits);
1139    }
1140    if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) {
1141        status = U_FORMAT_INEXACT_ERROR;
1142        return appendTo;
1143    }
1144
1145    return subformat(appendTo, handler, adjustedNum, FALSE);
1146}
1147
1148
1149UnicodeString&
1150DecimalFormat::format(  const Formattable& obj,
1151                        UnicodeString& appendTo,
1152                        FieldPosition& fieldPosition,
1153                        UErrorCode& status) const
1154{
1155    return NumberFormat::format(obj, appendTo, fieldPosition, status);
1156}
1157
1158/**
1159 * Return true if a grouping separator belongs at the given
1160 * position, based on whether grouping is in use and the values of
1161 * the primary and secondary grouping interval.
1162 * @param pos the number of integer digits to the right of
1163 * the current position.  Zero indicates the position after the
1164 * rightmost integer digit.
1165 * @return true if a grouping character belongs at the current
1166 * position.
1167 */
1168UBool DecimalFormat::isGroupingPosition(int32_t pos) const {
1169    UBool result = FALSE;
1170    if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) {
1171        if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) {
1172            result = ((pos - fGroupingSize) % fGroupingSize2) == 0;
1173        } else {
1174            result = pos % fGroupingSize == 0;
1175        }
1176    }
1177    return result;
1178}
1179
1180//------------------------------------------------------------------------------
1181
1182/**
1183 * Complete the formatting of a finite number.  On entry, the DigitList must
1184 * be filled in with the correct digits.
1185 */
1186UnicodeString&
1187DecimalFormat::subformat(UnicodeString& appendTo,
1188                         FieldPositionHandler& handler,
1189                         DigitList&     digits,
1190                         UBool          isInteger) const
1191{
1192    // char zero = '0';
1193    // DigitList returns digits as '0' thru '9', so we will need to
1194    // always need to subtract the character 0 to get the numeric value to use for indexing.
1195
1196    UChar32 localizedDigits[10];
1197    localizedDigits[0] = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
1198    localizedDigits[1] = getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol).char32At(0);
1199    localizedDigits[2] = getConstSymbol(DecimalFormatSymbols::kTwoDigitSymbol).char32At(0);
1200    localizedDigits[3] = getConstSymbol(DecimalFormatSymbols::kThreeDigitSymbol).char32At(0);
1201    localizedDigits[4] = getConstSymbol(DecimalFormatSymbols::kFourDigitSymbol).char32At(0);
1202    localizedDigits[5] = getConstSymbol(DecimalFormatSymbols::kFiveDigitSymbol).char32At(0);
1203    localizedDigits[6] = getConstSymbol(DecimalFormatSymbols::kSixDigitSymbol).char32At(0);
1204    localizedDigits[7] = getConstSymbol(DecimalFormatSymbols::kSevenDigitSymbol).char32At(0);
1205    localizedDigits[8] = getConstSymbol(DecimalFormatSymbols::kEightDigitSymbol).char32At(0);
1206    localizedDigits[9] = getConstSymbol(DecimalFormatSymbols::kNineDigitSymbol).char32At(0);
1207
1208    const UnicodeString *grouping ;
1209    if(fCurrencySignCount > fgCurrencySignCountZero) {
1210        grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
1211    }else{
1212        grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
1213    }
1214    const UnicodeString *decimal;
1215    if(fCurrencySignCount > fgCurrencySignCountZero) {
1216        decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1217    } else {
1218        decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
1219    }
1220    UBool useSigDig = areSignificantDigitsUsed();
1221    int32_t maxIntDig = getMaximumIntegerDigits();
1222    int32_t minIntDig = getMinimumIntegerDigits();
1223
1224    // Appends the prefix.
1225    double doubleValue = digits.getDouble();
1226    int32_t prefixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), TRUE);
1227
1228    if (fUseExponentialNotation)
1229    {
1230        int currentLength = appendTo.length();
1231        int intBegin = currentLength;
1232        int intEnd = -1;
1233        int fracBegin = -1;
1234
1235        int32_t minFracDig = 0;
1236        if (useSigDig) {
1237            maxIntDig = minIntDig = 1;
1238            minFracDig = getMinimumSignificantDigits() - 1;
1239        } else {
1240            minFracDig = getMinimumFractionDigits();
1241            if (maxIntDig > kMaxScientificIntegerDigits) {
1242                maxIntDig = 1;
1243                if (maxIntDig < minIntDig) {
1244                    maxIntDig = minIntDig;
1245                }
1246            }
1247            if (maxIntDig > minIntDig) {
1248                minIntDig = 1;
1249            }
1250        }
1251
1252        // Minimum integer digits are handled in exponential format by
1253        // adjusting the exponent.  For example, 0.01234 with 3 minimum
1254        // integer digits is "123.4E-4".
1255
1256        // Maximum integer digits are interpreted as indicating the
1257        // repeating range.  This is useful for engineering notation, in
1258        // which the exponent is restricted to a multiple of 3.  For
1259        // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
1260        // If maximum integer digits are defined and are larger than
1261        // minimum integer digits, then minimum integer digits are
1262        // ignored.
1263        digits.reduce();   // Removes trailing zero digits.
1264        int32_t exponent = digits.getDecimalAt();
1265        if (maxIntDig > 1 && maxIntDig != minIntDig) {
1266            // A exponent increment is defined; adjust to it.
1267            exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
1268                                      : (exponent / maxIntDig) - 1;
1269            exponent *= maxIntDig;
1270        } else {
1271            // No exponent increment is defined; use minimum integer digits.
1272            // If none is specified, as in "#E0", generate 1 integer digit.
1273            exponent -= (minIntDig > 0 || minFracDig > 0)
1274                        ? minIntDig : 1;
1275        }
1276
1277        // We now output a minimum number of digits, and more if there
1278        // are more digits, up to the maximum number of digits.  We
1279        // place the decimal point after the "integer" digits, which
1280        // are the first (decimalAt - exponent) digits.
1281        int32_t minimumDigits =  minIntDig + minFracDig;
1282        // The number of integer digits is handled specially if the number
1283        // is zero, since then there may be no digits.
1284        int32_t integerDigits = digits.isZero() ? minIntDig :
1285            digits.getDecimalAt() - exponent;
1286        int32_t totalDigits = digits.getCount();
1287        if (minimumDigits > totalDigits)
1288            totalDigits = minimumDigits;
1289        if (integerDigits > totalDigits)
1290            totalDigits = integerDigits;
1291
1292        // totalDigits records total number of digits needs to be processed
1293        int32_t i;
1294        for (i=0; i<totalDigits; ++i)
1295        {
1296            if (i == integerDigits)
1297            {
1298                intEnd = appendTo.length();
1299                handler.addAttribute(kIntegerField, intBegin, intEnd);
1300
1301                appendTo += *decimal;
1302
1303                fracBegin = appendTo.length();
1304                handler.addAttribute(kDecimalSeparatorField, fracBegin - 1, fracBegin);
1305            }
1306            // Restores the digit character or pads the buffer with zeros.
1307            UChar32 c = (UChar32)((i < digits.getCount()) ?
1308                          localizedDigits[digits.getDigitValue(i)] :
1309                          localizedDigits[0]);
1310            appendTo += c;
1311        }
1312
1313        currentLength = appendTo.length();
1314
1315        if (intEnd < 0) {
1316            handler.addAttribute(kIntegerField, intBegin, currentLength);
1317        }
1318        if (fracBegin > 0) {
1319            handler.addAttribute(kFractionField, fracBegin, currentLength);
1320        }
1321
1322        // The exponent is output using the pattern-specified minimum
1323        // exponent digits.  There is no maximum limit to the exponent
1324        // digits, since truncating the exponent would appendTo in an
1325        // unacceptable inaccuracy.
1326        appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
1327
1328        handler.addAttribute(kExponentSymbolField, currentLength, appendTo.length());
1329        currentLength = appendTo.length();
1330
1331        // For zero values, we force the exponent to zero.  We
1332        // must do this here, and not earlier, because the value
1333        // is used to determine integer digit count above.
1334        if (digits.isZero())
1335            exponent = 0;
1336
1337        if (exponent < 0) {
1338            appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
1339            handler.addAttribute(kExponentSignField, currentLength, appendTo.length());
1340        } else if (fExponentSignAlwaysShown) {
1341            appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
1342            handler.addAttribute(kExponentSignField, currentLength, appendTo.length());
1343        }
1344
1345        currentLength = appendTo.length();
1346
1347        DigitList expDigits;
1348        expDigits.set(exponent);
1349        {
1350            int expDig = fMinExponentDigits;
1351            if (fUseExponentialNotation && expDig < 1) {
1352                expDig = 1;
1353            }
1354            for (i=expDigits.getDecimalAt(); i<expDig; ++i)
1355                appendTo += (localizedDigits[0]);
1356        }
1357        for (i=0; i<expDigits.getDecimalAt(); ++i)
1358        {
1359            UChar32 c = (UChar32)((i < expDigits.getCount()) ?
1360                          localizedDigits[expDigits.getDigitValue(i)] :
1361                          localizedDigits[0]);
1362            appendTo += c;
1363        }
1364
1365        handler.addAttribute(kExponentField, currentLength, appendTo.length());
1366    }
1367    else  // Not using exponential notation
1368    {
1369        int currentLength = appendTo.length();
1370        int intBegin = currentLength;
1371
1372        int32_t sigCount = 0;
1373        int32_t minSigDig = getMinimumSignificantDigits();
1374        int32_t maxSigDig = getMaximumSignificantDigits();
1375        if (!useSigDig) {
1376            minSigDig = 0;
1377            maxSigDig = INT32_MAX;
1378        }
1379
1380        // Output the integer portion.  Here 'count' is the total
1381        // number of integer digits we will display, including both
1382        // leading zeros required to satisfy getMinimumIntegerDigits,
1383        // and actual digits present in the number.
1384        int32_t count = useSigDig ?
1385            _max(1, digits.getDecimalAt()) : minIntDig;
1386        if (digits.getDecimalAt() > 0 && count < digits.getDecimalAt()) {
1387            count = digits.getDecimalAt();
1388        }
1389
1390        // Handle the case where getMaximumIntegerDigits() is smaller
1391        // than the real number of integer digits.  If this is so, we
1392        // output the least significant max integer digits.  For example,
1393        // the value 1997 printed with 2 max integer digits is just "97".
1394
1395        int32_t digitIndex = 0; // Index into digitList.fDigits[]
1396        if (count > maxIntDig && maxIntDig >= 0) {
1397            count = maxIntDig;
1398            digitIndex = digits.getDecimalAt() - count;
1399        }
1400
1401        int32_t sizeBeforeIntegerPart = appendTo.length();
1402
1403        int32_t i;
1404        for (i=count-1; i>=0; --i)
1405        {
1406            if (i < digits.getDecimalAt() && digitIndex < digits.getCount() &&
1407                sigCount < maxSigDig) {
1408                // Output a real digit
1409                appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)];
1410                ++sigCount;
1411            }
1412            else
1413            {
1414                // Output a zero (leading or trailing)
1415                appendTo += localizedDigits[0];
1416                if (sigCount > 0) {
1417                    ++sigCount;
1418                }
1419            }
1420
1421            // Output grouping separator if necessary.
1422            if (isGroupingPosition(i)) {
1423                currentLength = appendTo.length();
1424                appendTo.append(*grouping);
1425                handler.addAttribute(kGroupingSeparatorField, currentLength, appendTo.length());
1426            }
1427        }
1428
1429        // TODO(dlf): this looks like it was a bug, we marked the int field as ending
1430        // before the zero was generated.
1431        // Record field information for caller.
1432        // if (fieldPosition.getField() == NumberFormat::kIntegerField)
1433        //     fieldPosition.setEndIndex(appendTo.length());
1434
1435        // Determine whether or not there are any printable fractional
1436        // digits.  If we've used up the digits we know there aren't.
1437        UBool fractionPresent = (!isInteger && digitIndex < digits.getCount()) ||
1438            (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));
1439
1440        // If there is no fraction present, and we haven't printed any
1441        // integer digits, then print a zero.  Otherwise we won't print
1442        // _any_ digits, and we won't be able to parse this string.
1443        if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart)
1444            appendTo += localizedDigits[0];
1445
1446        currentLength = appendTo.length();
1447        handler.addAttribute(kIntegerField, intBegin, currentLength);
1448
1449        // Output the decimal separator if we always do so.
1450        if (fDecimalSeparatorAlwaysShown || fractionPresent) {
1451            appendTo += *decimal;
1452            handler.addAttribute(kDecimalSeparatorField, currentLength, appendTo.length());
1453            currentLength = appendTo.length();
1454        }
1455
1456        int fracBegin = currentLength;
1457
1458        count = useSigDig ? INT32_MAX : getMaximumFractionDigits();
1459        if (useSigDig && (sigCount == maxSigDig ||
1460                          (sigCount >= minSigDig && digitIndex == digits.getCount()))) {
1461            count = 0;
1462        }
1463
1464        for (i=0; i < count; ++i) {
1465            // Here is where we escape from the loop.  We escape
1466            // if we've output the maximum fraction digits
1467            // (specified in the for expression above).  We also
1468            // stop when we've output the minimum digits and
1469            // either: we have an integer, so there is no
1470            // fractional stuff to display, or we're out of
1471            // significant digits.
1472            if (!useSigDig && i >= getMinimumFractionDigits() &&
1473                (isInteger || digitIndex >= digits.getCount())) {
1474                break;
1475            }
1476
1477            // Output leading fractional zeros.  These are zeros
1478            // that come after the decimal but before any
1479            // significant digits.  These are only output if
1480            // abs(number being formatted) < 1.0.
1481            if (-1-i > (digits.getDecimalAt()-1)) {
1482                appendTo += localizedDigits[0];
1483                continue;
1484            }
1485
1486            // Output a digit, if we have any precision left, or a
1487            // zero if we don't.  We don't want to output noise digits.
1488            if (!isInteger && digitIndex < digits.getCount()) {
1489                appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)];
1490            } else {
1491                appendTo += localizedDigits[0];
1492            }
1493
1494            // If we reach the maximum number of significant
1495            // digits, or if we output all the real digits and
1496            // reach the minimum, then we are done.
1497            ++sigCount;
1498            if (useSigDig &&
1499                (sigCount == maxSigDig ||
1500                 (digitIndex == digits.getCount() && sigCount >= minSigDig))) {
1501                break;
1502            }
1503        }
1504
1505        handler.addAttribute(kFractionField, fracBegin, appendTo.length());
1506    }
1507
1508    int32_t suffixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), FALSE);
1509
1510    addPadding(appendTo, handler, prefixLen, suffixLen);
1511    return appendTo;
1512}
1513
1514/**
1515 * Inserts the character fPad as needed to expand result to fFormatWidth.
1516 * @param result the string to be padded
1517 */
1518void DecimalFormat::addPadding(UnicodeString& appendTo,
1519                               FieldPositionHandler& handler,
1520                               int32_t prefixLen,
1521                               int32_t suffixLen) const
1522{
1523    if (fFormatWidth > 0) {
1524        int32_t len = fFormatWidth - appendTo.length();
1525        if (len > 0) {
1526            UnicodeString padding;
1527            for (int32_t i=0; i<len; ++i) {
1528                padding += fPad;
1529            }
1530            switch (fPadPosition) {
1531            case kPadAfterPrefix:
1532                appendTo.insert(prefixLen, padding);
1533                break;
1534            case kPadBeforePrefix:
1535                appendTo.insert(0, padding);
1536                break;
1537            case kPadBeforeSuffix:
1538                appendTo.insert(appendTo.length() - suffixLen, padding);
1539                break;
1540            case kPadAfterSuffix:
1541                appendTo += padding;
1542                break;
1543            }
1544            if (fPadPosition == kPadBeforePrefix || fPadPosition == kPadAfterPrefix) {
1545                handler.shiftLast(len);
1546            }
1547        }
1548    }
1549}
1550
1551//------------------------------------------------------------------------------
1552
1553void
1554DecimalFormat::parse(const UnicodeString& text,
1555                     Formattable& result,
1556                     UErrorCode& status) const
1557{
1558    NumberFormat::parse(text, result, status);
1559}
1560
1561void
1562DecimalFormat::parse(const UnicodeString& text,
1563                     Formattable& result,
1564                     ParsePosition& parsePosition) const {
1565    parse(text, result, parsePosition, FALSE);
1566}
1567
1568Formattable& DecimalFormat::parseCurrency(const UnicodeString& text,
1569                                          Formattable& result,
1570                                          ParsePosition& pos) const {
1571    parse(text, result, pos, TRUE);
1572    return result;
1573}
1574
1575/**
1576 * Parses the given text as either a number or a currency amount.
1577 * @param text the string to parse
1578 * @param result output parameter for the result
1579 * @param parsePosition input-output position; on input, the
1580 * position within text to match; must have 0 <= pos.getIndex() <
1581 * text.length(); on output, the position after the last matched
1582 * character. If the parse fails, the position in unchanged upon
1583 * output.
1584 * @param parseCurrency if true, a currency amount is parsed;
1585 * otherwise a Number is parsed
1586 */
1587void DecimalFormat::parse(const UnicodeString& text,
1588                          Formattable& result,
1589                          ParsePosition& parsePosition,
1590                          UBool parseCurrency) const {
1591    int32_t backup;
1592    int32_t i = backup = parsePosition.getIndex();
1593
1594    // clear any old contents in the result.  In particular, clears any DigitList
1595    //   that it may be holding.
1596    result.setLong(0);
1597
1598    // Handle NaN as a special case:
1599
1600    // Skip padding characters, if around prefix
1601    if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix ||
1602                             fPadPosition == kPadAfterPrefix)) {
1603        i = skipPadding(text, i);
1604    }
1605
1606    if (isLenient()) {
1607        // skip any leading whitespace
1608        i = backup = skipUWhiteSpace(text, i);
1609    }
1610
1611    // If the text is composed of the representation of NaN, returns NaN.length
1612    const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1613    int32_t nanLen = (text.compare(i, nan->length(), *nan)
1614                      ? 0 : nan->length());
1615    if (nanLen) {
1616        i += nanLen;
1617        if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix ||
1618                                 fPadPosition == kPadAfterSuffix)) {
1619            i = skipPadding(text, i);
1620        }
1621        parsePosition.setIndex(i);
1622        result.setDouble(uprv_getNaN());
1623        return;
1624    }
1625
1626    // NaN parse failed; start over
1627    i = backup;
1628    parsePosition.setIndex(i);
1629
1630    // status is used to record whether a number is infinite.
1631    UBool status[fgStatusLength];
1632    UChar curbuf[4];
1633    UChar* currency = parseCurrency ? curbuf : NULL;
1634    DigitList *digits = new DigitList;
1635    if (digits == NULL) {
1636        return;    // no way to report error from here.
1637    }
1638
1639    if (fCurrencySignCount > fgCurrencySignCountZero) {
1640        if (!parseForCurrency(text, parsePosition, *digits,
1641                              status, currency)) {
1642            delete digits;
1643            return;
1644        }
1645    } else {
1646        if (!subparse(text,
1647                      fNegPrefixPattern, fNegSuffixPattern,
1648                      fPosPrefixPattern, fPosSuffixPattern,
1649                      FALSE, UCURR_SYMBOL_NAME,
1650                      parsePosition, *digits, status, currency)) {
1651            parsePosition.setIndex(backup);
1652            delete digits;
1653            return;
1654        }
1655    }
1656
1657    // Handle infinity
1658    if (status[fgStatusInfinite]) {
1659        double inf = uprv_getInfinity();
1660        result.setDouble(digits->isPositive() ? inf : -inf);
1661        delete digits;    // TODO:  set the dl to infinity, and let it fall into the code below.
1662    }
1663
1664    else {
1665
1666        if (fMultiplier != NULL) {
1667            UErrorCode ec = U_ZERO_ERROR;
1668            digits->div(*fMultiplier, ec);
1669        }
1670
1671        // Negative zero special case:
1672        //    if parsing integerOnly, change to +0, which goes into an int32 in a Formattable.
1673        //    if not parsing integerOnly, leave as -0, which a double can represent.
1674        if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) {
1675            digits->setPositive(TRUE);
1676        }
1677        result.adoptDigitList(digits);
1678    }
1679
1680    if (parseCurrency) {
1681        UErrorCode ec = U_ZERO_ERROR;
1682        Formattable n(result);
1683        result.adoptObject(new CurrencyAmount(n, curbuf, ec));
1684        U_ASSERT(U_SUCCESS(ec)); // should always succeed
1685    }
1686}
1687
1688
1689
1690UBool
1691DecimalFormat::parseForCurrency(const UnicodeString& text,
1692                                ParsePosition& parsePosition,
1693                                DigitList& digits,
1694                                UBool* status,
1695                                UChar* currency) const {
1696    int origPos = parsePosition.getIndex();
1697    int maxPosIndex = origPos;
1698    int maxErrorPos = -1;
1699    // First, parse against current pattern.
1700    // Since current pattern could be set by applyPattern(),
1701    // it could be an arbitrary pattern, and it may not be the one
1702    // defined in current locale.
1703    UBool tmpStatus[fgStatusLength];
1704    ParsePosition tmpPos(origPos);
1705    DigitList tmpDigitList;
1706    UBool found;
1707    if (fStyle == UNUM_CURRENCY_PLURAL) {
1708        found = subparse(text,
1709                         fNegPrefixPattern, fNegSuffixPattern,
1710                         fPosPrefixPattern, fPosSuffixPattern,
1711                         TRUE, UCURR_LONG_NAME,
1712                         tmpPos, tmpDigitList, tmpStatus, currency);
1713    } else {
1714        found = subparse(text,
1715                         fNegPrefixPattern, fNegSuffixPattern,
1716                         fPosPrefixPattern, fPosSuffixPattern,
1717                         TRUE, UCURR_SYMBOL_NAME,
1718                         tmpPos, tmpDigitList, tmpStatus, currency);
1719    }
1720    if (found) {
1721        if (tmpPos.getIndex() > maxPosIndex) {
1722            maxPosIndex = tmpPos.getIndex();
1723            for (int32_t i = 0; i < fgStatusLength; ++i) {
1724                status[i] = tmpStatus[i];
1725            }
1726            digits = tmpDigitList;
1727        }
1728    } else {
1729        maxErrorPos = tmpPos.getErrorIndex();
1730    }
1731    // Then, parse against affix patterns.
1732    // Those are currency patterns and currency plural patterns.
1733    int32_t pos = -1;
1734    const UHashElement* element = NULL;
1735    while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
1736        const UHashTok valueTok = element->value;
1737        const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)valueTok.pointer;
1738        UBool tmpStatus[fgStatusLength];
1739        ParsePosition tmpPos(origPos);
1740        DigitList tmpDigitList;
1741        UBool result = subparse(text,
1742                                &affixPtn->negPrefixPatternForCurrency,
1743                                &affixPtn->negSuffixPatternForCurrency,
1744                                &affixPtn->posPrefixPatternForCurrency,
1745                                &affixPtn->posSuffixPatternForCurrency,
1746                                TRUE, affixPtn->patternType,
1747                                tmpPos, tmpDigitList, tmpStatus, currency);
1748        if (result) {
1749            found = true;
1750            if (tmpPos.getIndex() > maxPosIndex) {
1751                maxPosIndex = tmpPos.getIndex();
1752                for (int32_t i = 0; i < fgStatusLength; ++i) {
1753                    status[i] = tmpStatus[i];
1754                }
1755                digits = tmpDigitList;
1756            }
1757        } else {
1758            maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
1759                          tmpPos.getErrorIndex() : maxErrorPos;
1760        }
1761    }
1762    // Finally, parse against simple affix to find the match.
1763    // For example, in TestMonster suite,
1764    // if the to-be-parsed text is "-\u00A40,00".
1765    // complexAffixCompare will not find match,
1766    // since there is no ISO code matches "\u00A4",
1767    // and the parse stops at "\u00A4".
1768    // We will just use simple affix comparison (look for exact match)
1769    // to pass it.
1770    UBool tmpStatus_2[fgStatusLength];
1771    ParsePosition tmpPos_2(origPos);
1772    DigitList tmpDigitList_2;
1773    // set currencySignCount to 0 so that compareAffix function will
1774    // fall to compareSimpleAffix path, not compareComplexAffix path.
1775    // ?? TODO: is it right? need "false"?
1776    UBool result = subparse(text,
1777                            &fNegativePrefix, &fNegativeSuffix,
1778                            &fPositivePrefix, &fPositiveSuffix,
1779                            FALSE, UCURR_SYMBOL_NAME,
1780                            tmpPos_2, tmpDigitList_2, tmpStatus_2,
1781                            currency);
1782    if (result) {
1783        if (tmpPos_2.getIndex() > maxPosIndex) {
1784            maxPosIndex = tmpPos_2.getIndex();
1785            for (int32_t i = 0; i < fgStatusLength; ++i) {
1786                status[i] = tmpStatus_2[i];
1787            }
1788            digits = tmpDigitList_2;
1789        }
1790        found = true;
1791    } else {
1792            maxErrorPos = (tmpPos_2.getErrorIndex() > maxErrorPos) ?
1793                          tmpPos_2.getErrorIndex() : maxErrorPos;
1794    }
1795
1796    if (!found) {
1797        //parsePosition.setIndex(origPos);
1798        parsePosition.setErrorIndex(maxErrorPos);
1799    } else {
1800        parsePosition.setIndex(maxPosIndex);
1801        parsePosition.setErrorIndex(-1);
1802    }
1803    return found;
1804}
1805
1806
1807/**
1808 * Parse the given text into a number.  The text is parsed beginning at
1809 * parsePosition, until an unparseable character is seen.
1810 * @param text the string to parse.
1811 * @param negPrefix negative prefix.
1812 * @param negSuffix negative suffix.
1813 * @param posPrefix positive prefix.
1814 * @param posSuffix positive suffix.
1815 * @param currencyParsing whether it is currency parsing or not.
1816 * @param type the currency type to parse against, LONG_NAME only or not.
1817 * @param parsePosition The position at which to being parsing.  Upon
1818 * return, the first unparsed character.
1819 * @param digits the DigitList to set to the parsed value.
1820 * @param status output param containing boolean status flags indicating
1821 * whether the value was infinite and whether it was positive.
1822 * @param currency return value for parsed currency, for generic
1823 * currency parsing mode, or NULL for normal parsing. In generic
1824 * currency parsing mode, any currency is parsed, not just the
1825 * currency that this formatter is set to.
1826 */
1827UBool DecimalFormat::subparse(const UnicodeString& text,
1828                              const UnicodeString* negPrefix,
1829                              const UnicodeString* negSuffix,
1830                              const UnicodeString* posPrefix,
1831                              const UnicodeString* posSuffix,
1832                              UBool currencyParsing,
1833                              int8_t type,
1834                              ParsePosition& parsePosition,
1835                              DigitList& digits, UBool* status,
1836                              UChar* currency) const
1837{
1838    //  The parsing process builds up the number as char string, in the neutral format that
1839    //  will be acceptable to the decNumber library, then at the end passes that string
1840    //  off for conversion to a decNumber.
1841    UErrorCode err = U_ZERO_ERROR;
1842    CharString parsedNum;
1843    digits.setToZero();
1844
1845    int32_t position = parsePosition.getIndex();
1846    int32_t oldStart = position;
1847    UBool strictParse = !isLenient();
1848
1849    // Match padding before prefix
1850    if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) {
1851        position = skipPadding(text, position);
1852    }
1853
1854    // Match positive and negative prefixes; prefer longest match.
1855    int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, currencyParsing, type, currency);
1856    int32_t negMatch = compareAffix(text, position, TRUE,  TRUE, negPrefix, currencyParsing, type, currency);
1857    if (posMatch >= 0 && negMatch >= 0) {
1858        if (posMatch > negMatch) {
1859            negMatch = -1;
1860        } else if (negMatch > posMatch) {
1861            posMatch = -1;
1862        }
1863    }
1864    if (posMatch >= 0) {
1865        position += posMatch;
1866        parsedNum.append('+', err);
1867    } else if (negMatch >= 0) {
1868        position += negMatch;
1869        parsedNum.append('-', err);
1870    } else if (strictParse){
1871        parsePosition.setErrorIndex(position);
1872        return FALSE;
1873    }
1874
1875    // Match padding before prefix
1876    if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) {
1877        position = skipPadding(text, position);
1878    }
1879
1880    if (! strictParse) {
1881        position = skipUWhiteSpace(text, position);
1882    }
1883
1884    // process digits or Inf, find decimal position
1885    const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
1886    int32_t infLen = (text.compare(position, inf->length(), *inf)
1887        ? 0 : inf->length());
1888    position += infLen; // infLen is non-zero when it does equal to infinity
1889    status[fgStatusInfinite] = infLen != 0;
1890
1891    if (infLen != 0) {
1892        parsedNum.append("Infinity", err);
1893    } else {
1894        // We now have a string of digits, possibly with grouping symbols,
1895        // and decimal points.  We want to process these into a DigitList.
1896        // We don't want to put a bunch of leading zeros into the DigitList
1897        // though, so we keep track of the location of the decimal point,
1898        // put only significant digits into the DigitList, and adjust the
1899        // exponent as needed.
1900
1901        UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
1902
1903        UBool strictFail = FALSE; // did we exit with a strict parse failure?
1904        int32_t lastGroup = -1; // where did we last see a grouping separator?
1905        int32_t digitStart = position;
1906        int32_t gs2 = fGroupingSize2 == 0 ? fGroupingSize : fGroupingSize2;
1907
1908        const UnicodeString *decimalString;
1909        if (fCurrencySignCount > fgCurrencySignCountZero) {
1910            decimalString = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1911        } else {
1912            decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
1913        }
1914        UChar32 decimalChar = decimalString->char32At(0);
1915
1916        const UnicodeString *groupingString = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
1917        UChar32 groupingChar = groupingString->char32At(0);
1918        UBool sawDecimal = FALSE;
1919        UChar32 sawDecimalChar = 0xFFFF;
1920        UBool sawGrouping = FALSE;
1921        UChar32 sawGroupingChar = 0xFFFF;
1922        UBool sawDigit = FALSE;
1923        int32_t backup = -1;
1924        int32_t digit;
1925        int32_t textLength = text.length(); // One less pointer to follow
1926        int32_t decimalStringLength = decimalString->length();
1927        int32_t decimalCharLength   = U16_LENGTH(decimalChar);
1928        int32_t groupingStringLength = groupingString->length();
1929        int32_t groupingCharLength   = U16_LENGTH(groupingChar);
1930
1931        // equivalent grouping and decimal support
1932        const UnicodeSet *decimalSet = NULL;
1933        const UnicodeSet *groupingSet = NULL;
1934
1935        if (decimalCharLength == decimalStringLength) {
1936            decimalSet = DecimalFormatStaticSets::getSimilarDecimals(decimalChar, strictParse);
1937        }
1938
1939        if (groupingCharLength == groupingStringLength) {
1940            if (strictParse) {
1941                groupingSet = DecimalFormatStaticSets::gStaticSets->fStrictDefaultGroupingSeparators;
1942            } else {
1943                groupingSet = DecimalFormatStaticSets::gStaticSets->fDefaultGroupingSeparators;
1944            }
1945        }
1946
1947        // We need to test groupingChar and decimalChar separately from groupingSet and decimalSet, if the sets are even initialized.
1948        // If sawDecimal is TRUE, only consider sawDecimalChar and NOT decimalSet
1949        // If a character matches decimalSet, don't consider it to be a member of the groupingSet.
1950
1951        // We have to track digitCount ourselves, because digits.fCount will
1952        // pin when the maximum allowable digits is reached.
1953        int32_t digitCount = 0;
1954        int32_t integerDigitCount = 0;
1955
1956        for (; position < textLength; )
1957        {
1958            UChar32 ch = text.char32At(position);
1959
1960            /* We recognize all digit ranges, not only the Latin digit range
1961             * '0'..'9'.  We do so by using the Character.digit() method,
1962             * which converts a valid Unicode digit to the range 0..9.
1963             *
1964             * The character 'ch' may be a digit.  If so, place its value
1965             * from 0 to 9 in 'digit'.  First try using the locale digit,
1966             * which may or MAY NOT be a standard Unicode digit range.  If
1967             * this fails, try using the standard Unicode digit ranges by
1968             * calling Character.digit().  If this also fails, digit will
1969             * have a value outside the range 0..9.
1970             */
1971            digit = ch - zero;
1972            if (digit < 0 || digit > 9)
1973            {
1974                digit = u_charDigitValue(ch);
1975            }
1976
1977            // As a last resort, look through the localized digits if the zero digit
1978            // is not a "standard" Unicode digit.
1979            if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) {
1980                digit = 0;
1981                if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) {
1982                    break;
1983                }
1984                for (digit = 1 ; digit < 10 ; digit++ ) {
1985                    if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) {
1986                        break;
1987                    }
1988                }
1989            }
1990
1991            if (digit >= 0 && digit <= 9)
1992            {
1993                if (strictParse && backup != -1) {
1994                    // comma followed by digit, so group before comma is a
1995                    // secondary group.  If there was a group separator
1996                    // before that, the group must == the secondary group
1997                    // length, else it can be <= the the secondary group
1998                    // length.
1999                    if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||
2000                        (lastGroup == -1 && position - digitStart - 1 > gs2)) {
2001                        strictFail = TRUE;
2002                        break;
2003                    }
2004
2005                    lastGroup = backup;
2006                }
2007
2008                // Cancel out backup setting (see grouping handler below)
2009                backup = -1;
2010                sawDigit = TRUE;
2011
2012                // Note: this will append leading zeros
2013                parsedNum.append((char)(digit + '0'), err);
2014
2015                // count any digit that's not a leading zero
2016                if (digit > 0 || digitCount > 0 || sawDecimal) {
2017                    digitCount += 1;
2018
2019                    // count any integer digit that's not a leading zero
2020                    if (! sawDecimal) {
2021                        integerDigitCount += 1;
2022                    }
2023                }
2024
2025                position += U16_LENGTH(ch);
2026            }
2027            else if (groupingStringLength > 0 &&
2028                matchGrouping(groupingChar, sawGrouping, sawGroupingChar, groupingSet,
2029                            decimalChar, decimalSet,
2030                            ch) && isGroupingUsed())
2031            {
2032                if (sawDecimal) {
2033                    break;
2034                }
2035
2036                if (strictParse) {
2037                    if ((!sawDigit || backup != -1)) {
2038                        // leading group, or two group separators in a row
2039                        strictFail = TRUE;
2040                        break;
2041                    }
2042                }
2043
2044                // Ignore grouping characters, if we are using them, but require
2045                // that they be followed by a digit.  Otherwise we backup and
2046                // reprocess them.
2047                backup = position;
2048                position += groupingStringLength;
2049                sawGrouping=TRUE;
2050                // Once we see a grouping character, we only accept that grouping character from then on.
2051                sawGroupingChar=ch;
2052            }
2053            else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimalSet, ch))
2054            {
2055                if (strictParse) {
2056                    if (backup != -1 ||
2057                        (lastGroup != -1 && position - lastGroup != fGroupingSize + 1)) {
2058                        strictFail = TRUE;
2059                        break;
2060                    }
2061                }
2062
2063                // If we're only parsing integers, or if we ALREADY saw the
2064                // decimal, then don't parse this one.
2065                if (isParseIntegerOnly() || sawDecimal) {
2066                    break;
2067                }
2068
2069                parsedNum.append('.', err);
2070                position += decimalStringLength;
2071                sawDecimal = TRUE;
2072                // Once we see a decimal character, we only accept that decimal character from then on.
2073                sawDecimalChar=ch;
2074                // decimalSet is considered to consist of (ch,ch)
2075            }
2076            else {
2077                const UnicodeString *tmp;
2078                tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
2079                if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT))    // error code is set below if !sawDigit
2080                {
2081                    // Parse sign, if present
2082                    int32_t pos = position + tmp->length();
2083                    char exponentSign = '+';
2084
2085                    if (pos < textLength)
2086                    {
2087                        tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2088                        if (!text.compare(pos, tmp->length(), *tmp))
2089                        {
2090                            pos += tmp->length();
2091                        }
2092                        else {
2093                            tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2094                            if (!text.compare(pos, tmp->length(), *tmp))
2095                            {
2096                                exponentSign = '-';
2097                                pos += tmp->length();
2098                            }
2099                        }
2100                    }
2101
2102                    UBool sawExponentDigit = FALSE;
2103                    while (pos < textLength) {
2104                        ch = text[(int32_t)pos];
2105                        digit = ch - zero;
2106
2107                        if (digit < 0 || digit > 9) {
2108                            digit = u_charDigitValue(ch);
2109                        }
2110                        if (0 <= digit && digit <= 9) {
2111                            if (!sawExponentDigit) {
2112                                parsedNum.append('E', err);
2113                                parsedNum.append(exponentSign, err);
2114                                sawExponentDigit = TRUE;
2115                            }
2116                            ++pos;
2117                            parsedNum.append((char)(digit + '0'), err);
2118                        } else {
2119                            break;
2120                        }
2121                    }
2122
2123                    if (sawExponentDigit) {
2124                        position = pos; // Advance past the exponent
2125                    }
2126
2127                    break; // Whether we fail or succeed, we exit this loop
2128                }
2129                else {
2130                    break;
2131                }
2132            }
2133        }
2134
2135        if (backup != -1)
2136        {
2137            position = backup;
2138        }
2139
2140        if (strictParse && !sawDecimal) {
2141            if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) {
2142                strictFail = TRUE;
2143            }
2144        }
2145
2146        if (strictFail) {
2147            // only set with strictParse and a grouping separator error
2148
2149            parsePosition.setIndex(oldStart);
2150            parsePosition.setErrorIndex(position);
2151            return FALSE;
2152        }
2153
2154        // If there was no decimal point we have an integer
2155
2156        // If none of the text string was recognized.  For example, parse
2157        // "x" with pattern "#0.00" (return index and error index both 0)
2158        // parse "$" with pattern "$#0.00". (return index 0 and error index
2159        // 1).
2160        if (!sawDigit && digitCount == 0) {
2161            parsePosition.setIndex(oldStart);
2162            parsePosition.setErrorIndex(oldStart);
2163            return FALSE;
2164        }
2165    }
2166
2167    // Match padding before suffix
2168    if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) {
2169        position = skipPadding(text, position);
2170    }
2171
2172    int32_t posSuffixMatch = -1, negSuffixMatch = -1;
2173
2174    // Match positive and negative suffixes; prefer longest match.
2175    if (posMatch >= 0 || (!strictParse && negMatch < 0)) {
2176        posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, currencyParsing, type, currency);
2177    }
2178    if (negMatch >= 0) {
2179        negSuffixMatch = compareAffix(text, position, TRUE, FALSE, negSuffix, currencyParsing, type, currency);
2180    }
2181    if (posSuffixMatch >= 0 && negSuffixMatch >= 0) {
2182        if (posSuffixMatch > negSuffixMatch) {
2183            negSuffixMatch = -1;
2184        } else if (negSuffixMatch > posSuffixMatch) {
2185            posSuffixMatch = -1;
2186        }
2187    }
2188
2189    // Fail if neither or both
2190    if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) {
2191        parsePosition.setErrorIndex(position);
2192        return FALSE;
2193    }
2194
2195    position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0));
2196
2197    // Match padding before suffix
2198    if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) {
2199        position = skipPadding(text, position);
2200    }
2201
2202    parsePosition.setIndex(position);
2203
2204    parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0 && negSuffixMatch < 0)) ? '+' : '-';
2205
2206    if(parsePosition.getIndex() == oldStart)
2207    {
2208        parsePosition.setErrorIndex(position);
2209        return FALSE;
2210    }
2211    digits.set(parsedNum.toStringPiece(), err);
2212
2213    if (U_FAILURE(err)) {
2214        parsePosition.setErrorIndex(position);
2215        return FALSE;
2216    }
2217    return TRUE;
2218}
2219
2220/**
2221 * Starting at position, advance past a run of pad characters, if any.
2222 * Return the index of the first character after position that is not a pad
2223 * character.  Result is >= position.
2224 */
2225int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
2226    int32_t padLen = U16_LENGTH(fPad);
2227    while (position < text.length() &&
2228           text.char32At(position) == fPad) {
2229        position += padLen;
2230    }
2231    return position;
2232}
2233
2234/**
2235 * Return the length matched by the given affix, or -1 if none.
2236 * Runs of white space in the affix, match runs of white space in
2237 * the input.  Pattern white space and input white space are
2238 * determined differently; see code.
2239 * @param text input text
2240 * @param pos offset into input at which to begin matching
2241 * @param isNegative
2242 * @param isPrefix
2243 * @param affixPat affix pattern used for currency affix comparison.
2244 * @param currencyParsing whether it is currency parsing or not
2245 * @param type the currency type to parse against, LONG_NAME only or not.
2246 * @param currency return value for parsed currency, for generic
2247 * currency parsing mode, or null for normal parsing. In generic
2248 * currency parsing mode, any currency is parsed, not just the
2249 * currency that this formatter is set to.
2250 * @return length of input that matches, or -1 if match failure
2251 */
2252int32_t DecimalFormat::compareAffix(const UnicodeString& text,
2253                                    int32_t pos,
2254                                    UBool isNegative,
2255                                    UBool isPrefix,
2256                                    const UnicodeString* affixPat,
2257                                    UBool currencyParsing,
2258                                    int8_t type,
2259                                    UChar* currency) const
2260{
2261    const UnicodeString *patternToCompare;
2262    if (fCurrencyChoice != NULL || currency != NULL ||
2263        (fCurrencySignCount > fgCurrencySignCountZero && currencyParsing)) {
2264
2265        if (affixPat != NULL) {
2266            return compareComplexAffix(*affixPat, text, pos, type, currency);
2267        }
2268    }
2269
2270    if (isNegative) {
2271        if (isPrefix) {
2272            patternToCompare = &fNegativePrefix;
2273        }
2274        else {
2275            patternToCompare = &fNegativeSuffix;
2276        }
2277    }
2278    else {
2279        if (isPrefix) {
2280            patternToCompare = &fPositivePrefix;
2281        }
2282        else {
2283            patternToCompare = &fPositiveSuffix;
2284        }
2285    }
2286    return compareSimpleAffix(*patternToCompare, text, pos, isLenient());
2287}
2288
2289/**
2290 * Return the length matched by the given affix, or -1 if none.
2291 * Runs of white space in the affix, match runs of white space in
2292 * the input.  Pattern white space and input white space are
2293 * determined differently; see code.
2294 * @param affix pattern string, taken as a literal
2295 * @param input input text
2296 * @param pos offset into input at which to begin matching
2297 * @return length of input that matches, or -1 if match failure
2298 */
2299int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
2300                                          const UnicodeString& input,
2301                                          int32_t pos,
2302                                          UBool lenient) {
2303    UErrorCode status = U_ZERO_ERROR;
2304    int32_t start = pos;
2305    UChar32 affixChar = affix.char32At(0);
2306    int32_t affixLength = affix.length();
2307    int32_t inputLength = input.length();
2308    int32_t affixCharLength = U16_LENGTH(affixChar);
2309    UnicodeSet *affixSet;
2310
2311    DecimalFormatStaticSets::initSets(&status);
2312
2313    if (!lenient) {
2314        affixSet = DecimalFormatStaticSets::gStaticSets->fStrictDashEquivalents;
2315
2316        // If the affix is exactly one character long and that character
2317        // is in the dash set and the very next input character is also
2318        // in the dash set, return a match.
2319        if (affixCharLength == affixLength && affixSet->contains(affixChar))  {
2320            if (affixSet->contains(input.char32At(pos))) {
2321                return 1;
2322            }
2323        }
2324
2325        for (int32_t i = 0; i < affixLength; ) {
2326            UChar32 c = affix.char32At(i);
2327            int32_t len = U16_LENGTH(c);
2328            if (PatternProps::isWhiteSpace(c)) {
2329                // We may have a pattern like: \u200F \u0020
2330                //        and input text like: \u200F \u0020
2331                // Note that U+200F and U+0020 are Pattern_White_Space but only
2332                // U+0020 is UWhiteSpace.  So we have to first do a direct
2333                // match of the run of Pattern_White_Space in the pattern,
2334                // then match any extra characters.
2335                UBool literalMatch = FALSE;
2336                while (pos < inputLength &&
2337                       input.char32At(pos) == c) {
2338                    literalMatch = TRUE;
2339                    i += len;
2340                    pos += len;
2341                    if (i == affixLength) {
2342                        break;
2343                    }
2344                    c = affix.char32At(i);
2345                    len = U16_LENGTH(c);
2346                    if (!PatternProps::isWhiteSpace(c)) {
2347                        break;
2348                    }
2349                }
2350
2351                // Advance over run in pattern
2352                i = skipPatternWhiteSpace(affix, i);
2353
2354                // Advance over run in input text
2355                // Must see at least one white space char in input,
2356                // unless we've already matched some characters literally.
2357                int32_t s = pos;
2358                pos = skipUWhiteSpace(input, pos);
2359                if (pos == s && !literalMatch) {
2360                    return -1;
2361                }
2362
2363                // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
2364                // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
2365                // is also in the affix.
2366                i = skipUWhiteSpace(affix, i);
2367            } else {
2368                if (pos < inputLength &&
2369                    input.char32At(pos) == c) {
2370                    i += len;
2371                    pos += len;
2372                } else {
2373                    return -1;
2374                }
2375            }
2376        }
2377    } else {
2378        UBool match = FALSE;
2379
2380        affixSet = DecimalFormatStaticSets::gStaticSets->fDashEquivalents;
2381
2382        if (affixCharLength == affixLength && affixSet->contains(affixChar))  {
2383            pos = skipUWhiteSpace(input, pos);
2384
2385            if (affixSet->contains(input.char32At(pos))) {
2386                return pos - start + 1;
2387            }
2388        }
2389
2390        for (int32_t i = 0; i < affixLength; )
2391        {
2392            //i = skipRuleWhiteSpace(affix, i);
2393            i = skipUWhiteSpace(affix, i);
2394            pos = skipUWhiteSpace(input, pos);
2395
2396            if (i >= affixLength || pos >= inputLength) {
2397                break;
2398            }
2399
2400            UChar32 c = affix.char32At(i);
2401            int32_t len = U16_LENGTH(c);
2402
2403            if (input.char32At(pos) != c) {
2404                return -1;
2405            }
2406
2407            match = TRUE;
2408            i += len;
2409            pos += len;
2410        }
2411
2412        if (affixLength > 0 && ! match) {
2413            return -1;
2414        }
2415    }
2416    return pos - start;
2417}
2418
2419/**
2420 * Skip over a run of zero or more Pattern_White_Space characters at
2421 * pos in text.
2422 */
2423int32_t DecimalFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) {
2424    const UChar* s = text.getBuffer();
2425    return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s);
2426}
2427
2428/**
2429 * Skip over a run of zero or more isUWhiteSpace() characters at pos
2430 * in text.
2431 */
2432int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) {
2433    while (pos < text.length()) {
2434        UChar32 c = text.char32At(pos);
2435        if (!u_isUWhiteSpace(c)) {
2436            break;
2437        }
2438        pos += U16_LENGTH(c);
2439    }
2440    return pos;
2441}
2442
2443/**
2444 * Return the length matched by the given affix, or -1 if none.
2445 * @param affixPat pattern string
2446 * @param input input text
2447 * @param pos offset into input at which to begin matching
2448 * @param type the currency type to parse against, LONG_NAME only or not.
2449 * @param currency return value for parsed currency, for generic
2450 * currency parsing mode, or null for normal parsing. In generic
2451 * currency parsing mode, any currency is parsed, not just the
2452 * currency that this formatter is set to.
2453 * @return length of input that matches, or -1 if match failure
2454 */
2455int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat,
2456                                           const UnicodeString& text,
2457                                           int32_t pos,
2458                                           int8_t type,
2459                                           UChar* currency) const
2460{
2461    int32_t start = pos;
2462    U_ASSERT(currency != NULL ||
2463             (fCurrencyChoice != NULL && *getCurrency() != 0) ||
2464             fCurrencySignCount > fgCurrencySignCountZero);
2465
2466    for (int32_t i=0;
2467         i<affixPat.length() && pos >= 0; ) {
2468        UChar32 c = affixPat.char32At(i);
2469        i += U16_LENGTH(c);
2470
2471        if (c == kQuote) {
2472            U_ASSERT(i <= affixPat.length());
2473            c = affixPat.char32At(i);
2474            i += U16_LENGTH(c);
2475
2476            const UnicodeString* affix = NULL;
2477
2478            switch (c) {
2479            case kCurrencySign: {
2480                // since the currency names in choice format is saved
2481                // the same way as other currency names,
2482                // do not need to do currency choice parsing here.
2483                // the general currency parsing parse against all names,
2484                // including names in choice format.
2485                UBool intl = i<affixPat.length() &&
2486                    affixPat.char32At(i) == kCurrencySign;
2487                if (intl) {
2488                    ++i;
2489                }
2490                UBool plural = i<affixPat.length() &&
2491                    affixPat.char32At(i) == kCurrencySign;
2492                if (plural) {
2493                    ++i;
2494                    intl = FALSE;
2495                }
2496                // Parse generic currency -- anything for which we
2497                // have a display name, or any 3-letter ISO code.
2498                // Try to parse display name for our locale; first
2499                // determine our locale.
2500                const char* loc = fCurrencyPluralInfo->getLocale().getName();
2501                ParsePosition ppos(pos);
2502                UChar curr[4];
2503                UErrorCode ec = U_ZERO_ERROR;
2504                // Delegate parse of display name => ISO code to Currency
2505                uprv_parseCurrency(loc, text, ppos, type, curr, ec);
2506
2507                // If parse succeeds, populate currency[0]
2508                if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
2509                    if (currency) {
2510                        u_strcpy(currency, curr);
2511                    } else {
2512                        // The formatter is currency-style but the client has not requested
2513                        // the value of the parsed currency. In this case, if that value does
2514                        // not match the formatter's current value, then the parse fails.
2515                        UChar effectiveCurr[4];
2516                        getEffectiveCurrency(effectiveCurr, ec);
2517                        if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) {
2518                        	pos = -1;
2519                        	continue;
2520                        }
2521                    }
2522                    pos = ppos.getIndex();
2523                } else if (!isLenient()){
2524                    pos = -1;
2525                }
2526                continue;
2527            }
2528            case kPatternPercent:
2529                affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
2530                break;
2531            case kPatternPerMill:
2532                affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
2533                break;
2534            case kPatternPlus:
2535                affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2536                break;
2537            case kPatternMinus:
2538                affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2539                break;
2540            default:
2541                // fall through to affix!=0 test, which will fail
2542                break;
2543            }
2544
2545            if (affix != NULL) {
2546                pos = match(text, pos, *affix);
2547                continue;
2548            }
2549        }
2550
2551        pos = match(text, pos, c);
2552        if (PatternProps::isWhiteSpace(c)) {
2553            i = skipPatternWhiteSpace(affixPat, i);
2554        }
2555    }
2556    return pos - start;
2557}
2558
2559/**
2560 * Match a single character at text[pos] and return the index of the
2561 * next character upon success.  Return -1 on failure.  If
2562 * ch is a Pattern_White_Space then match a run of white space in text.
2563 */
2564int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) {
2565    if (PatternProps::isWhiteSpace(ch)) {
2566        // Advance over run of white space in input text
2567        // Must see at least one white space char in input
2568        int32_t s = pos;
2569        pos = skipPatternWhiteSpace(text, pos);
2570        if (pos == s) {
2571            return -1;
2572        }
2573        return pos;
2574    }
2575    return (pos >= 0 && text.char32At(pos) == ch) ?
2576        (pos + U16_LENGTH(ch)) : -1;
2577}
2578
2579/**
2580 * Match a string at text[pos] and return the index of the next
2581 * character upon success.  Return -1 on failure.  Match a run of
2582 * white space in str with a run of white space in text.
2583 */
2584int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) {
2585    for (int32_t i=0; i<str.length() && pos >= 0; ) {
2586        UChar32 ch = str.char32At(i);
2587        i += U16_LENGTH(ch);
2588        if (PatternProps::isWhiteSpace(ch)) {
2589            i = skipPatternWhiteSpace(str, i);
2590        }
2591        pos = match(text, pos, ch);
2592    }
2593    return pos;
2594}
2595
2596UBool DecimalFormat::matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol,
2597                         UnicodeSet *sset, UChar32 schar)
2598{
2599    if (sset != NULL) {
2600        return sset->contains(schar);
2601    }
2602
2603    return text.compare(position, length, symbol) == 0;
2604}
2605
2606UBool DecimalFormat::matchDecimal(UChar32 symbolChar,
2607                            UBool sawDecimal,  UChar32 sawDecimalChar,
2608                             const UnicodeSet *sset, UChar32 schar) {
2609   if(sawDecimal) {
2610       return schar==sawDecimalChar;
2611   } else if(schar==symbolChar) {
2612       return TRUE;
2613   } else if(sset!=NULL) {
2614        return sset->contains(schar);
2615   } else {
2616       return FALSE;
2617   }
2618}
2619
2620UBool DecimalFormat::matchGrouping(UChar32 groupingChar,
2621                            UBool sawGrouping, UChar32 sawGroupingChar,
2622                             const UnicodeSet *sset,
2623                             UChar32 decimalChar, const UnicodeSet *decimalSet,
2624                             UChar32 schar) {
2625    if(sawGrouping) {
2626        return schar==sawGroupingChar;  // previously found
2627    } else if(schar==groupingChar) {
2628        return TRUE; // char from symbols
2629    } else if(sset!=NULL) {
2630        return sset->contains(schar) &&  // in groupingSet but...
2631           ((decimalSet==NULL) || !decimalSet->contains(schar)); // Exclude decimalSet from groupingSet
2632    } else {
2633        return FALSE;
2634    }
2635}
2636
2637
2638
2639//------------------------------------------------------------------------------
2640// Gets the pointer to the localized decimal format symbols
2641
2642const DecimalFormatSymbols*
2643DecimalFormat::getDecimalFormatSymbols() const
2644{
2645    return fSymbols;
2646}
2647
2648//------------------------------------------------------------------------------
2649// De-owning the current localized symbols and adopt the new symbols.
2650
2651void
2652DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
2653{
2654    if (symbolsToAdopt == NULL) {
2655        return; // do not allow caller to set fSymbols to NULL
2656    }
2657
2658    UBool sameSymbols = FALSE;
2659    if (fSymbols != NULL) {
2660        sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) ==
2661            symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) &&
2662            getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) ==
2663            symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
2664        delete fSymbols;
2665    }
2666
2667    fSymbols = symbolsToAdopt;
2668    if (!sameSymbols) {
2669        // If the currency symbols are the same, there is no need to recalculate.
2670        setCurrencyForSymbols();
2671    }
2672    expandAffixes(NULL);
2673}
2674//------------------------------------------------------------------------------
2675// Setting the symbols is equlivalent to adopting a newly created localized
2676// symbols.
2677
2678void
2679DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
2680{
2681    adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
2682}
2683
2684
2685const CurrencyPluralInfo*
2686DecimalFormat::getCurrencyPluralInfo(void) const
2687{
2688    return fCurrencyPluralInfo;
2689}
2690
2691
2692void
2693DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt)
2694{
2695    if (toAdopt != NULL) {
2696        delete fCurrencyPluralInfo;
2697        fCurrencyPluralInfo = toAdopt;
2698        // re-set currency affix patterns and currency affixes.
2699        if (fCurrencySignCount > fgCurrencySignCountZero) {
2700            UErrorCode status = U_ZERO_ERROR;
2701            if (fAffixPatternsForCurrency) {
2702                deleteHashForAffixPattern();
2703            }
2704            setupCurrencyAffixPatterns(status);
2705            if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) {
2706                // only setup the affixes of the plural pattern.
2707                setupCurrencyAffixes(fFormatPattern, FALSE, TRUE, status);
2708            }
2709        }
2710    }
2711}
2712
2713void
2714DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info)
2715{
2716    adoptCurrencyPluralInfo(info.clone());
2717}
2718
2719
2720/**
2721 * Update the currency object to match the symbols.  This method
2722 * is used only when the caller has passed in a symbols object
2723 * that may not be the default object for its locale.
2724 */
2725void
2726DecimalFormat::setCurrencyForSymbols() {
2727    /*Bug 4212072
2728      Update the affix strings accroding to symbols in order to keep
2729      the affix strings up to date.
2730      [Richard/GCL]
2731    */
2732
2733    // With the introduction of the Currency object, the currency
2734    // symbols in the DFS object are ignored.  For backward
2735    // compatibility, we check any explicitly set DFS object.  If it
2736    // is a default symbols object for its locale, we change the
2737    // currency object to one for that locale.  If it is custom,
2738    // we set the currency to null.
2739    UErrorCode ec = U_ZERO_ERROR;
2740    const UChar* c = NULL;
2741    const char* loc = fSymbols->getLocale().getName();
2742    UChar intlCurrencySymbol[4];
2743    ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec);
2744    UnicodeString currencySymbol;
2745
2746    uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec);
2747    if (U_SUCCESS(ec)
2748        && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol
2749        && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == UnicodeString(intlCurrencySymbol))
2750    {
2751        // Trap an error in mapping locale to currency.  If we can't
2752        // map, then don't fail and set the currency to "".
2753        c = intlCurrencySymbol;
2754    }
2755    ec = U_ZERO_ERROR; // reset local error code!
2756    setCurrencyInternally(c, ec);
2757}
2758
2759
2760//------------------------------------------------------------------------------
2761// Gets the positive prefix of the number pattern.
2762
2763UnicodeString&
2764DecimalFormat::getPositivePrefix(UnicodeString& result) const
2765{
2766    result = fPositivePrefix;
2767    return result;
2768}
2769
2770//------------------------------------------------------------------------------
2771// Sets the positive prefix of the number pattern.
2772
2773void
2774DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
2775{
2776    fPositivePrefix = newValue;
2777    delete fPosPrefixPattern;
2778    fPosPrefixPattern = 0;
2779}
2780
2781//------------------------------------------------------------------------------
2782// Gets the negative prefix  of the number pattern.
2783
2784UnicodeString&
2785DecimalFormat::getNegativePrefix(UnicodeString& result) const
2786{
2787    result = fNegativePrefix;
2788    return result;
2789}
2790
2791//------------------------------------------------------------------------------
2792// Gets the negative prefix  of the number pattern.
2793
2794void
2795DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
2796{
2797    fNegativePrefix = newValue;
2798    delete fNegPrefixPattern;
2799    fNegPrefixPattern = 0;
2800}
2801
2802//------------------------------------------------------------------------------
2803// Gets the positive suffix of the number pattern.
2804
2805UnicodeString&
2806DecimalFormat::getPositiveSuffix(UnicodeString& result) const
2807{
2808    result = fPositiveSuffix;
2809    return result;
2810}
2811
2812//------------------------------------------------------------------------------
2813// Sets the positive suffix of the number pattern.
2814
2815void
2816DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
2817{
2818    fPositiveSuffix = newValue;
2819    delete fPosSuffixPattern;
2820    fPosSuffixPattern = 0;
2821}
2822
2823//------------------------------------------------------------------------------
2824// Gets the negative suffix of the number pattern.
2825
2826UnicodeString&
2827DecimalFormat::getNegativeSuffix(UnicodeString& result) const
2828{
2829    result = fNegativeSuffix;
2830    return result;
2831}
2832
2833//------------------------------------------------------------------------------
2834// Sets the negative suffix of the number pattern.
2835
2836void
2837DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
2838{
2839    fNegativeSuffix = newValue;
2840    delete fNegSuffixPattern;
2841    fNegSuffixPattern = 0;
2842}
2843
2844//------------------------------------------------------------------------------
2845// Gets the multiplier of the number pattern.
2846//   Multipliers are stored as decimal numbers (DigitLists) because that
2847//      is the most convenient for muliplying or dividing the numbers to be formatted.
2848//   A NULL multiplier implies one, and the scaling operations are skipped.
2849
2850int32_t
2851DecimalFormat::getMultiplier() const
2852{
2853    if (fMultiplier == NULL) {
2854        return 1;
2855    } else {
2856        return fMultiplier->getLong();
2857    }
2858}
2859
2860//------------------------------------------------------------------------------
2861// Sets the multiplier of the number pattern.
2862void
2863DecimalFormat::setMultiplier(int32_t newValue)
2864{
2865//  if (newValue == 0) {
2866//      throw new IllegalArgumentException("Bad multiplier: " + newValue);
2867//  }
2868    if (newValue == 0) {
2869        newValue = 1;     // one being the benign default value for a multiplier.
2870    }
2871    if (newValue == 1) {
2872        delete fMultiplier;
2873        fMultiplier = NULL;
2874    } else {
2875        if (fMultiplier == NULL) {
2876            fMultiplier = new DigitList;
2877        }
2878        if (fMultiplier != NULL) {
2879            fMultiplier->set(newValue);
2880        }
2881    }
2882}
2883
2884/**
2885 * Get the rounding increment.
2886 * @return A positive rounding increment, or 0.0 if rounding
2887 * is not in effect.
2888 * @see #setRoundingIncrement
2889 * @see #getRoundingMode
2890 * @see #setRoundingMode
2891 */
2892double DecimalFormat::getRoundingIncrement() const {
2893    if (fRoundingIncrement == NULL) {
2894        return 0.0;
2895    } else {
2896        return fRoundingIncrement->getDouble();
2897    }
2898}
2899
2900/**
2901 * Set the rounding increment.  This method also controls whether
2902 * rounding is enabled.
2903 * @param newValue A positive rounding increment, or 0.0 to disable rounding.
2904 * Negative increments are equivalent to 0.0.
2905 * @see #getRoundingIncrement
2906 * @see #getRoundingMode
2907 * @see #setRoundingMode
2908 */
2909void DecimalFormat::setRoundingIncrement(double newValue) {
2910    if (newValue > 0.0) {
2911        if (fRoundingIncrement == NULL) {
2912            fRoundingIncrement = new DigitList();
2913        }
2914        if (fRoundingIncrement != NULL) {
2915            fRoundingIncrement->set(newValue);
2916            return;
2917        }
2918    }
2919    // These statements are executed if newValue is less than 0.0
2920    // or fRoundingIncrement could not be created.
2921    delete fRoundingIncrement;
2922    fRoundingIncrement = NULL;
2923}
2924
2925/**
2926 * Get the rounding mode.
2927 * @return A rounding mode
2928 * @see #setRoundingIncrement
2929 * @see #getRoundingIncrement
2930 * @see #setRoundingMode
2931 */
2932DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const {
2933    return fRoundingMode;
2934}
2935
2936/**
2937 * Set the rounding mode.  This has no effect unless the rounding
2938 * increment is greater than zero.
2939 * @param roundingMode A rounding mode
2940 * @see #setRoundingIncrement
2941 * @see #getRoundingIncrement
2942 * @see #getRoundingMode
2943 */
2944void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
2945    fRoundingMode = roundingMode;
2946}
2947
2948/**
2949 * Get the width to which the output of <code>format()</code> is padded.
2950 * @return the format width, or zero if no padding is in effect
2951 * @see #setFormatWidth
2952 * @see #getPadCharacter
2953 * @see #setPadCharacter
2954 * @see #getPadPosition
2955 * @see #setPadPosition
2956 */
2957int32_t DecimalFormat::getFormatWidth() const {
2958    return fFormatWidth;
2959}
2960
2961/**
2962 * Set the width to which the output of <code>format()</code> is padded.
2963 * This method also controls whether padding is enabled.
2964 * @param width the width to which to pad the result of
2965 * <code>format()</code>, or zero to disable padding.  A negative
2966 * width is equivalent to 0.
2967 * @see #getFormatWidth
2968 * @see #getPadCharacter
2969 * @see #setPadCharacter
2970 * @see #getPadPosition
2971 * @see #setPadPosition
2972 */
2973void DecimalFormat::setFormatWidth(int32_t width) {
2974    fFormatWidth = (width > 0) ? width : 0;
2975}
2976
2977UnicodeString DecimalFormat::getPadCharacterString() const {
2978    return UnicodeString(fPad);
2979}
2980
2981void DecimalFormat::setPadCharacter(const UnicodeString &padChar) {
2982    if (padChar.length() > 0) {
2983        fPad = padChar.char32At(0);
2984    }
2985    else {
2986        fPad = kDefaultPad;
2987    }
2988}
2989
2990/**
2991 * Get the position at which padding will take place.  This is the location
2992 * at which padding will be inserted if the result of <code>format()</code>
2993 * is shorter than the format width.
2994 * @return the pad position, one of <code>kPadBeforePrefix</code>,
2995 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2996 * <code>kPadAfterSuffix</code>.
2997 * @see #setFormatWidth
2998 * @see #getFormatWidth
2999 * @see #setPadCharacter
3000 * @see #getPadCharacter
3001 * @see #setPadPosition
3002 * @see #kPadBeforePrefix
3003 * @see #kPadAfterPrefix
3004 * @see #kPadBeforeSuffix
3005 * @see #kPadAfterSuffix
3006 */
3007DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const {
3008    return fPadPosition;
3009}
3010
3011/**
3012 * <strong><font face=helvetica color=red>NEW</font></strong>
3013 * Set the position at which padding will take place.  This is the location
3014 * at which padding will be inserted if the result of <code>format()</code>
3015 * is shorter than the format width.  This has no effect unless padding is
3016 * enabled.
3017 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
3018 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
3019 * <code>kPadAfterSuffix</code>.
3020 * @see #setFormatWidth
3021 * @see #getFormatWidth
3022 * @see #setPadCharacter
3023 * @see #getPadCharacter
3024 * @see #getPadPosition
3025 * @see #kPadBeforePrefix
3026 * @see #kPadAfterPrefix
3027 * @see #kPadBeforeSuffix
3028 * @see #kPadAfterSuffix
3029 */
3030void DecimalFormat::setPadPosition(EPadPosition padPos) {
3031    fPadPosition = padPos;
3032}
3033
3034/**
3035 * Return whether or not scientific notation is used.
3036 * @return TRUE if this object formats and parses scientific notation
3037 * @see #setScientificNotation
3038 * @see #getMinimumExponentDigits
3039 * @see #setMinimumExponentDigits
3040 * @see #isExponentSignAlwaysShown
3041 * @see #setExponentSignAlwaysShown
3042 */
3043UBool DecimalFormat::isScientificNotation() {
3044    return fUseExponentialNotation;
3045}
3046
3047/**
3048 * Set whether or not scientific notation is used.
3049 * @param useScientific TRUE if this object formats and parses scientific
3050 * notation
3051 * @see #isScientificNotation
3052 * @see #getMinimumExponentDigits
3053 * @see #setMinimumExponentDigits
3054 * @see #isExponentSignAlwaysShown
3055 * @see #setExponentSignAlwaysShown
3056 */
3057void DecimalFormat::setScientificNotation(UBool useScientific) {
3058    fUseExponentialNotation = useScientific;
3059}
3060
3061/**
3062 * Return the minimum exponent digits that will be shown.
3063 * @return the minimum exponent digits that will be shown
3064 * @see #setScientificNotation
3065 * @see #isScientificNotation
3066 * @see #setMinimumExponentDigits
3067 * @see #isExponentSignAlwaysShown
3068 * @see #setExponentSignAlwaysShown
3069 */
3070int8_t DecimalFormat::getMinimumExponentDigits() const {
3071    return fMinExponentDigits;
3072}
3073
3074/**
3075 * Set the minimum exponent digits that will be shown.  This has no
3076 * effect unless scientific notation is in use.
3077 * @param minExpDig a value >= 1 indicating the fewest exponent digits
3078 * that will be shown.  Values less than 1 will be treated as 1.
3079 * @see #setScientificNotation
3080 * @see #isScientificNotation
3081 * @see #getMinimumExponentDigits
3082 * @see #isExponentSignAlwaysShown
3083 * @see #setExponentSignAlwaysShown
3084 */
3085void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
3086    fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
3087}
3088
3089/**
3090 * Return whether the exponent sign is always shown.
3091 * @return TRUE if the exponent is always prefixed with either the
3092 * localized minus sign or the localized plus sign, false if only negative
3093 * exponents are prefixed with the localized minus sign.
3094 * @see #setScientificNotation
3095 * @see #isScientificNotation
3096 * @see #setMinimumExponentDigits
3097 * @see #getMinimumExponentDigits
3098 * @see #setExponentSignAlwaysShown
3099 */
3100UBool DecimalFormat::isExponentSignAlwaysShown() {
3101    return fExponentSignAlwaysShown;
3102}
3103
3104/**
3105 * Set whether the exponent sign is always shown.  This has no effect
3106 * unless scientific notation is in use.
3107 * @param expSignAlways TRUE if the exponent is always prefixed with either
3108 * the localized minus sign or the localized plus sign, false if only
3109 * negative exponents are prefixed with the localized minus sign.
3110 * @see #setScientificNotation
3111 * @see #isScientificNotation
3112 * @see #setMinimumExponentDigits
3113 * @see #getMinimumExponentDigits
3114 * @see #isExponentSignAlwaysShown
3115 */
3116void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
3117    fExponentSignAlwaysShown = expSignAlways;
3118}
3119
3120//------------------------------------------------------------------------------
3121// Gets the grouping size of the number pattern.  For example, thousand or 10
3122// thousand groupings.
3123
3124int32_t
3125DecimalFormat::getGroupingSize() const
3126{
3127    return fGroupingSize;
3128}
3129
3130//------------------------------------------------------------------------------
3131// Gets the grouping size of the number pattern.
3132
3133void
3134DecimalFormat::setGroupingSize(int32_t newValue)
3135{
3136    fGroupingSize = newValue;
3137}
3138
3139//------------------------------------------------------------------------------
3140
3141int32_t
3142DecimalFormat::getSecondaryGroupingSize() const
3143{
3144    return fGroupingSize2;
3145}
3146
3147//------------------------------------------------------------------------------
3148
3149void
3150DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
3151{
3152    fGroupingSize2 = newValue;
3153}
3154
3155//------------------------------------------------------------------------------
3156// Checks if to show the decimal separator.
3157
3158UBool
3159DecimalFormat::isDecimalSeparatorAlwaysShown() const
3160{
3161    return fDecimalSeparatorAlwaysShown;
3162}
3163
3164//------------------------------------------------------------------------------
3165// Sets to always show the decimal separator.
3166
3167void
3168DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
3169{
3170    fDecimalSeparatorAlwaysShown = newValue;
3171}
3172
3173//------------------------------------------------------------------------------
3174// Emits the pattern of this DecimalFormat instance.
3175
3176UnicodeString&
3177DecimalFormat::toPattern(UnicodeString& result) const
3178{
3179    return toPattern(result, FALSE);
3180}
3181
3182//------------------------------------------------------------------------------
3183// Emits the localized pattern this DecimalFormat instance.
3184
3185UnicodeString&
3186DecimalFormat::toLocalizedPattern(UnicodeString& result) const
3187{
3188    return toPattern(result, TRUE);
3189}
3190
3191//------------------------------------------------------------------------------
3192/**
3193 * Expand the affix pattern strings into the expanded affix strings.  If any
3194 * affix pattern string is null, do not expand it.  This method should be
3195 * called any time the symbols or the affix patterns change in order to keep
3196 * the expanded affix strings up to date.
3197 * This method also will be called before formatting if format currency
3198 * plural names, since the plural name is not a static one, it is
3199 * based on the currency plural count, the affix will be known only
3200 * after the currency plural count is know.
3201 * In which case, the parameter
3202 * 'pluralCount' will be a non-null currency plural count.
3203 * In all other cases, the 'pluralCount' is null, which means it is not needed.
3204 */
3205void DecimalFormat::expandAffixes(const UnicodeString* pluralCount) {
3206    FieldPositionHandler none;
3207    if (fPosPrefixPattern != 0) {
3208      expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, none, FALSE, pluralCount);
3209    }
3210    if (fPosSuffixPattern != 0) {
3211      expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, none, FALSE, pluralCount);
3212    }
3213    if (fNegPrefixPattern != 0) {
3214      expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, none, FALSE, pluralCount);
3215    }
3216    if (fNegSuffixPattern != 0) {
3217      expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, none, FALSE, pluralCount);
3218    }
3219#ifdef FMT_DEBUG
3220    UnicodeString s;
3221    s.append("[")
3222        .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern)
3223        .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern)
3224        .append("]->[")
3225        .append(fPositivePrefix).append("|").append(fPositiveSuffix)
3226        .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix)
3227        .append("]\n");
3228    debugout(s);
3229#endif
3230}
3231
3232/**
3233 * Expand an affix pattern into an affix string.  All characters in the
3234 * pattern are literal unless prefixed by kQuote.  The following characters
3235 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
3236 * PATTERN_MINUS, and kCurrencySign.  If kCurrencySign is doubled (kQuote +
3237 * kCurrencySign + kCurrencySign), it is interpreted as an international
3238 * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as
3239 * currency plural long names, such as "US Dollars".
3240 * Any other character after a kQuote represents itself.
3241 * kQuote must be followed by another character; kQuote may not occur by
3242 * itself at the end of the pattern.
3243 *
3244 * This method is used in two distinct ways.  First, it is used to expand
3245 * the stored affix patterns into actual affixes.  For this usage, doFormat
3246 * must be false.  Second, it is used to expand the stored affix patterns
3247 * given a specific number (doFormat == true), for those rare cases in
3248 * which a currency format references a ChoiceFormat (e.g., en_IN display
3249 * name for INR).  The number itself is taken from digitList.
3250 *
3251 * When used in the first way, this method has a side effect: It sets
3252 * currencyChoice to a ChoiceFormat object, if the currency's display name
3253 * in this locale is a ChoiceFormat pattern (very rare).  It only does this
3254 * if currencyChoice is null to start with.
3255 *
3256 * @param pattern the non-null, fPossibly empty pattern
3257 * @param affix string to receive the expanded equivalent of pattern.
3258 * Previous contents are deleted.
3259 * @param doFormat if false, then the pattern will be expanded, and if a
3260 * currency symbol is encountered that expands to a ChoiceFormat, the
3261 * currencyChoice member variable will be initialized if it is null.  If
3262 * doFormat is true, then it is assumed that the currencyChoice has been
3263 * created, and it will be used to format the value in digitList.
3264 * @param pluralCount the plural count. It is only used for currency
3265 *                    plural format. In which case, it is the plural
3266 *                    count of the currency amount. For example,
3267 *                    in en_US, it is the singular "one", or the plural
3268 *                    "other". For all other cases, it is null, and
3269 *                    is not being used.
3270 */
3271void DecimalFormat::expandAffix(const UnicodeString& pattern,
3272                                UnicodeString& affix,
3273                                double number,
3274                                FieldPositionHandler& handler,
3275                                UBool doFormat,
3276                                const UnicodeString* pluralCount) const {
3277    affix.remove();
3278    for (int i=0; i<pattern.length(); ) {
3279        UChar32 c = pattern.char32At(i);
3280        i += U16_LENGTH(c);
3281        if (c == kQuote) {
3282            c = pattern.char32At(i);
3283            i += U16_LENGTH(c);
3284            int beginIdx = affix.length();
3285            switch (c) {
3286            case kCurrencySign: {
3287                // As of ICU 2.2 we use the currency object, and
3288                // ignore the currency symbols in the DFS, unless
3289                // we have a null currency object.  This occurs if
3290                // resurrecting a pre-2.2 object or if the user
3291                // sets a custom DFS.
3292                UBool intl = i<pattern.length() &&
3293                    pattern.char32At(i) == kCurrencySign;
3294                UBool plural = FALSE;
3295                if (intl) {
3296                    ++i;
3297                    plural = i<pattern.length() &&
3298                        pattern.char32At(i) == kCurrencySign;
3299                    if (plural) {
3300                        intl = FALSE;
3301                        ++i;
3302                    }
3303                }
3304                const UChar* currencyUChars = getCurrency();
3305                if (currencyUChars[0] != 0) {
3306                    UErrorCode ec = U_ZERO_ERROR;
3307                    if (plural && pluralCount != NULL) {
3308                        // plural name is only needed when pluralCount != null,
3309                        // which means when formatting currency plural names.
3310                        // For other cases, pluralCount == null,
3311                        // and plural names are not needed.
3312                        int32_t len;
3313                        CharString pluralCountChar;
3314                        pluralCountChar.appendInvariantChars(*pluralCount, ec);
3315                        UBool isChoiceFormat;
3316                        const UChar* s = ucurr_getPluralName(currencyUChars,
3317                            fSymbols != NULL ? fSymbols->getLocale().getName() :
3318                            Locale::getDefault().getName(), &isChoiceFormat,
3319                            pluralCountChar.data(), &len, &ec);
3320                        affix += UnicodeString(s, len);
3321                        handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3322                    } else if(intl) {
3323                        affix.append(currencyUChars, -1);
3324                        handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3325                    } else {
3326                        int32_t len;
3327                        UBool isChoiceFormat;
3328                        // If fSymbols is NULL, use default locale
3329                        const UChar* s = ucurr_getName(currencyUChars,
3330                            fSymbols != NULL ? fSymbols->getLocale().getName() : Locale::getDefault().getName(),
3331                            UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec);
3332                        if (isChoiceFormat) {
3333                            // Two modes here: If doFormat is false, we set up
3334                            // currencyChoice.  If doFormat is true, we use the
3335                            // previously created currencyChoice to format the
3336                            // value in digitList.
3337                            if (!doFormat) {
3338                                // If the currency is handled by a ChoiceFormat,
3339                                // then we're not going to use the expanded
3340                                // patterns.  Instantiate the ChoiceFormat and
3341                                // return.
3342                                if (fCurrencyChoice == NULL) {
3343                                    // TODO Replace double-check with proper thread-safe code
3344                                    ChoiceFormat* fmt = new ChoiceFormat(UnicodeString(s), ec);
3345                                    if (U_SUCCESS(ec)) {
3346                                        umtx_lock(NULL);
3347                                        if (fCurrencyChoice == NULL) {
3348                                            // Cast away const
3349                                            ((DecimalFormat*)this)->fCurrencyChoice = fmt;
3350                                            fmt = NULL;
3351                                        }
3352                                        umtx_unlock(NULL);
3353                                        delete fmt;
3354                                    }
3355                                }
3356                                // We could almost return null or "" here, since the
3357                                // expanded affixes are almost not used at all
3358                                // in this situation.  However, one method --
3359                                // toPattern() -- still does use the expanded
3360                                // affixes, in order to set up a padding
3361                                // pattern.  We use the CURRENCY_SIGN as a
3362                                // placeholder.
3363                                affix.append(kCurrencySign);
3364                            } else {
3365                                if (fCurrencyChoice != NULL) {
3366                                    FieldPosition pos(0); // ignored
3367                                    if (number < 0) {
3368                                        number = -number;
3369                                    }
3370                                    fCurrencyChoice->format(number, affix, pos);
3371                                } else {
3372                                    // We only arrive here if the currency choice
3373                                    // format in the locale data is INVALID.
3374                                    affix.append(currencyUChars, -1);
3375                                    handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3376                                }
3377                            }
3378                            continue;
3379                        }
3380                        affix += UnicodeString(s, len);
3381                        handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3382                    }
3383                } else {
3384                    if(intl) {
3385                        affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
3386                    } else {
3387                        affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
3388                    }
3389                    handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3390                }
3391                break;
3392            }
3393            case kPatternPercent:
3394                affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3395                handler.addAttribute(kPercentField, beginIdx, affix.length());
3396                break;
3397            case kPatternPerMill:
3398                affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3399                handler.addAttribute(kPermillField, beginIdx, affix.length());
3400                break;
3401            case kPatternPlus:
3402                affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3403                handler.addAttribute(kSignField, beginIdx, affix.length());
3404                break;
3405            case kPatternMinus:
3406                affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3407                handler.addAttribute(kSignField, beginIdx, affix.length());
3408                break;
3409            default:
3410                affix.append(c);
3411                break;
3412            }
3413        }
3414        else {
3415            affix.append(c);
3416        }
3417    }
3418}
3419
3420/**
3421 * Append an affix to the given StringBuffer.
3422 * @param buf buffer to append to
3423 * @param isNegative
3424 * @param isPrefix
3425 */
3426int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number,
3427                                   FieldPositionHandler& handler,
3428                                   UBool isNegative, UBool isPrefix) const {
3429    // plural format precedes choice format
3430    if (fCurrencyChoice != 0 &&
3431        fCurrencySignCount != fgCurrencySignCountInPluralFormat) {
3432        const UnicodeString* affixPat;
3433        if (isPrefix) {
3434            affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern;
3435        } else {
3436            affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern;
3437        }
3438        if (affixPat) {
3439            UnicodeString affixBuf;
3440            expandAffix(*affixPat, affixBuf, number, handler, TRUE, NULL);
3441            buf.append(affixBuf);
3442            return affixBuf.length();
3443        }
3444        // else someone called a function that reset the pattern.
3445    }
3446
3447    const UnicodeString* affix;
3448    if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) {
3449        UnicodeString pluralCount = fCurrencyPluralInfo->getPluralRules()->select(number);
3450        AffixesForCurrency* oneSet;
3451        if (fStyle == UNUM_CURRENCY_PLURAL) {
3452            oneSet = (AffixesForCurrency*)fPluralAffixesForCurrency->get(pluralCount);
3453        } else {
3454            oneSet = (AffixesForCurrency*)fAffixesForCurrency->get(pluralCount);
3455        }
3456        if (isPrefix) {
3457            affix = isNegative ? &oneSet->negPrefixForCurrency :
3458                                 &oneSet->posPrefixForCurrency;
3459        } else {
3460            affix = isNegative ? &oneSet->negSuffixForCurrency :
3461                                 &oneSet->posSuffixForCurrency;
3462        }
3463    } else {
3464        if (isPrefix) {
3465            affix = isNegative ? &fNegativePrefix : &fPositivePrefix;
3466        } else {
3467            affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix;
3468        }
3469    }
3470
3471    int32_t begin = (int) buf.length();
3472
3473    buf.append(*affix);
3474
3475    if (handler.isRecording()) {
3476      int32_t offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
3477      if (offset > -1) {
3478        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
3479        handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length());
3480      }
3481
3482      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
3483      if (offset > -1) {
3484        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
3485        handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length());
3486      }
3487
3488      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
3489      if (offset > -1) {
3490        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3491        handler.addAttribute(kSignField, begin + offset, begin + offset + aff.length());
3492      }
3493
3494      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
3495      if (offset > -1) {
3496        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3497        handler.addAttribute(kPercentField, begin + offset, begin + offset + aff.length());
3498      }
3499
3500      offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
3501      if (offset > -1) {
3502        UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3503        handler.addAttribute(kPermillField, begin + offset, begin + offset + aff.length());
3504      }
3505    }
3506    return affix->length();
3507}
3508
3509/**
3510 * Appends an affix pattern to the given StringBuffer, quoting special
3511 * characters as needed.  Uses the internal affix pattern, if that exists,
3512 * or the literal affix, if the internal affix pattern is null.  The
3513 * appended string will generate the same affix pattern (or literal affix)
3514 * when passed to toPattern().
3515 *
3516 * @param appendTo the affix string is appended to this
3517 * @param affixPattern a pattern such as fPosPrefixPattern; may be null
3518 * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
3519 * Ignored unless affixPattern is null.  If affixPattern is null, then
3520 * expAffix is appended as a literal affix.
3521 * @param localized true if the appended pattern should contain localized
3522 * pattern characters; otherwise, non-localized pattern chars are appended
3523 */
3524void DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
3525                                       const UnicodeString* affixPattern,
3526                                       const UnicodeString& expAffix,
3527                                       UBool localized) const {
3528    if (affixPattern == 0) {
3529        appendAffixPattern(appendTo, expAffix, localized);
3530    } else {
3531        int i;
3532        for (int pos=0; pos<affixPattern->length(); pos=i) {
3533            i = affixPattern->indexOf(kQuote, pos);
3534            if (i < 0) {
3535                UnicodeString s;
3536                affixPattern->extractBetween(pos, affixPattern->length(), s);
3537                appendAffixPattern(appendTo, s, localized);
3538                break;
3539            }
3540            if (i > pos) {
3541                UnicodeString s;
3542                affixPattern->extractBetween(pos, i, s);
3543                appendAffixPattern(appendTo, s, localized);
3544            }
3545            UChar32 c = affixPattern->char32At(++i);
3546            ++i;
3547            if (c == kQuote) {
3548                appendTo.append(c).append(c);
3549                // Fall through and append another kQuote below
3550            } else if (c == kCurrencySign &&
3551                       i<affixPattern->length() &&
3552                       affixPattern->char32At(i) == kCurrencySign) {
3553                ++i;
3554                appendTo.append(c).append(c);
3555            } else if (localized) {
3556                switch (c) {
3557                case kPatternPercent:
3558                    appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3559                    break;
3560                case kPatternPerMill:
3561                    appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3562                    break;
3563                case kPatternPlus:
3564                    appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3565                    break;
3566                case kPatternMinus:
3567                    appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3568                    break;
3569                default:
3570                    appendTo.append(c);
3571                }
3572            } else {
3573                appendTo.append(c);
3574            }
3575        }
3576    }
3577}
3578
3579/**
3580 * Append an affix to the given StringBuffer, using quotes if
3581 * there are special characters.  Single quotes themselves must be
3582 * escaped in either case.
3583 */
3584void
3585DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
3586                                  const UnicodeString& affix,
3587                                  UBool localized) const {
3588    UBool needQuote;
3589    if(localized) {
3590        needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0
3591            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0
3592            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0
3593            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0
3594            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0
3595            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0
3596            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0
3597            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0
3598            || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0
3599            || affix.indexOf(kCurrencySign) >= 0;
3600    }
3601    else {
3602        needQuote = affix.indexOf(kPatternZeroDigit) >= 0
3603            || affix.indexOf(kPatternGroupingSeparator) >= 0
3604            || affix.indexOf(kPatternDecimalSeparator) >= 0
3605            || affix.indexOf(kPatternPercent) >= 0
3606            || affix.indexOf(kPatternPerMill) >= 0
3607            || affix.indexOf(kPatternDigit) >= 0
3608            || affix.indexOf(kPatternSeparator) >= 0
3609            || affix.indexOf(kPatternExponent) >= 0
3610            || affix.indexOf(kPatternPlus) >= 0
3611            || affix.indexOf(kPatternMinus) >= 0
3612            || affix.indexOf(kCurrencySign) >= 0;
3613    }
3614    if (needQuote)
3615        appendTo += (UChar)0x0027 /*'\''*/;
3616    if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0)
3617        appendTo += affix;
3618    else {
3619        for (int32_t j = 0; j < affix.length(); ) {
3620            UChar32 c = affix.char32At(j);
3621            j += U16_LENGTH(c);
3622            appendTo += c;
3623            if (c == 0x0027 /*'\''*/)
3624                appendTo += c;
3625        }
3626    }
3627    if (needQuote)
3628        appendTo += (UChar)0x0027 /*'\''*/;
3629}
3630
3631//------------------------------------------------------------------------------
3632
3633UnicodeString&
3634DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
3635{
3636    if (fStyle == UNUM_CURRENCY_PLURAL) {
3637        // the prefix or suffix pattern might not be defined yet,
3638        // so they can not be synthesized,
3639        // instead, get them directly.
3640        // but it might not be the actual pattern used in formatting.
3641        // the actual pattern used in formatting depends on the
3642        // formatted number's plural count.
3643        result = fFormatPattern;
3644        return result;
3645    }
3646    result.remove();
3647    UChar32 zero, sigDigit = kPatternSignificantDigit;
3648    UnicodeString digit, group;
3649    int32_t i;
3650    int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
3651    UnicodeString roundingDigits;
3652    int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
3653    UnicodeString padSpec;
3654    UBool useSigDig = areSignificantDigitsUsed();
3655
3656    if (localized) {
3657        digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
3658        group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
3659        zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
3660        if (useSigDig) {
3661            sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
3662        }
3663    }
3664    else {
3665        digit.append((UChar)kPatternDigit);
3666        group.append((UChar)kPatternGroupingSeparator);
3667        zero = (UChar32)kPatternZeroDigit;
3668    }
3669    if (fFormatWidth > 0) {
3670        if (localized) {
3671            padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
3672        }
3673        else {
3674            padSpec.append((UChar)kPatternPadEscape);
3675        }
3676        padSpec.append(fPad);
3677    }
3678    if (fRoundingIncrement != NULL) {
3679        for(i=0; i<fRoundingIncrement->getCount(); ++i) {
3680          roundingDigits.append(zero+(fRoundingIncrement->getDigitValue(i))); // Convert to Unicode digit
3681        }
3682        roundingDecimalPos = fRoundingIncrement->getDecimalAt();
3683    }
3684    for (int32_t part=0; part<2; ++part) {
3685        if (padPos == kPadBeforePrefix) {
3686            result.append(padSpec);
3687        }
3688        appendAffixPattern(result,
3689                    (part==0 ? fPosPrefixPattern : fNegPrefixPattern),
3690                    (part==0 ? fPositivePrefix : fNegativePrefix),
3691                    localized);
3692        if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) {
3693            result.append(padSpec);
3694        }
3695        int32_t sub0Start = result.length();
3696        int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0;
3697        if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) {
3698            g += fGroupingSize2;
3699        }
3700        int32_t maxDig = 0, minDig = 0, maxSigDig = 0;
3701        if (useSigDig) {
3702            minDig = getMinimumSignificantDigits();
3703            maxDig = maxSigDig = getMaximumSignificantDigits();
3704        } else {
3705            minDig = getMinimumIntegerDigits();
3706            maxDig = getMaximumIntegerDigits();
3707        }
3708        if (fUseExponentialNotation) {
3709            if (maxDig > kMaxScientificIntegerDigits) {
3710                maxDig = 1;
3711            }
3712        } else if (useSigDig) {
3713            maxDig = _max(maxDig, g+1);
3714        } else {
3715            maxDig = _max(_max(g, getMinimumIntegerDigits()),
3716                          roundingDecimalPos) + 1;
3717        }
3718        for (i = maxDig; i > 0; --i) {
3719            if (!fUseExponentialNotation && i<maxDig &&
3720                isGroupingPosition(i)) {
3721                result.append(group);
3722            }
3723            if (useSigDig) {
3724                //  #@,@###   (maxSigDig == 5, minSigDig == 2)
3725                //  65 4321   (1-based pos, count from the right)
3726                // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
3727                // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
3728                if (maxSigDig >= i && i > (maxSigDig - minDig)) {
3729                    result.append(sigDigit);
3730                } else {
3731                    result.append(digit);
3732                }
3733            } else {
3734                if (! roundingDigits.isEmpty()) {
3735                    int32_t pos = roundingDecimalPos - i;
3736                    if (pos >= 0 && pos < roundingDigits.length()) {
3737                        result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
3738                        continue;
3739                    }
3740                }
3741                if (i<=minDig) {
3742                    result.append(zero);
3743                } else {
3744                    result.append(digit);
3745                }
3746            }
3747        }
3748        if (!useSigDig) {
3749            if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
3750                if (localized) {
3751                    result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
3752                }
3753                else {
3754                    result.append((UChar)kPatternDecimalSeparator);
3755                }
3756            }
3757            int32_t pos = roundingDecimalPos;
3758            for (i = 0; i < getMaximumFractionDigits(); ++i) {
3759                if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) {
3760                    if (pos < 0) {
3761                        result.append(zero);
3762                    }
3763                    else {
3764                        result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
3765                    }
3766                    ++pos;
3767                    continue;
3768                }
3769                if (i<getMinimumFractionDigits()) {
3770                    result.append(zero);
3771                }
3772                else {
3773                    result.append(digit);
3774                }
3775            }
3776        }
3777        if (fUseExponentialNotation) {
3778            if (localized) {
3779                result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
3780            }
3781            else {
3782                result.append((UChar)kPatternExponent);
3783            }
3784            if (fExponentSignAlwaysShown) {
3785                if (localized) {
3786                    result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3787                }
3788                else {
3789                    result.append((UChar)kPatternPlus);
3790                }
3791            }
3792            for (i=0; i<fMinExponentDigits; ++i) {
3793                result.append(zero);
3794            }
3795        }
3796        if (! padSpec.isEmpty() && !fUseExponentialNotation) {
3797            int32_t add = fFormatWidth - result.length() + sub0Start
3798                - ((part == 0)
3799                   ? fPositivePrefix.length() + fPositiveSuffix.length()
3800                   : fNegativePrefix.length() + fNegativeSuffix.length());
3801            while (add > 0) {
3802                result.insert(sub0Start, digit);
3803                ++maxDig;
3804                --add;
3805                // Only add a grouping separator if we have at least
3806                // 2 additional characters to be added, so we don't
3807                // end up with ",###".
3808                if (add>1 && isGroupingPosition(maxDig)) {
3809                    result.insert(sub0Start, group);
3810                    --add;
3811                }
3812            }
3813        }
3814        if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) {
3815            result.append(padSpec);
3816        }
3817        if (part == 0) {
3818            appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized);
3819            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
3820                result.append(padSpec);
3821            }
3822            UBool isDefault = FALSE;
3823            if ((fNegSuffixPattern == fPosSuffixPattern && // both null
3824                 fNegativeSuffix == fPositiveSuffix)
3825                || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 &&
3826                    *fNegSuffixPattern == *fPosSuffixPattern))
3827            {
3828                if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL)
3829                {
3830                    int32_t length = fPosPrefixPattern->length();
3831                    isDefault = fNegPrefixPattern->length() == (length+2) &&
3832                        (*fNegPrefixPattern)[(int32_t)0] == kQuote &&
3833                        (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus &&
3834                        fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0;
3835                }
3836                if (!isDefault &&
3837                    fNegPrefixPattern == NULL && fPosPrefixPattern == NULL)
3838                {
3839                    int32_t length = fPositivePrefix.length();
3840                    isDefault = fNegativePrefix.length() == (length+1) &&
3841                        fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
3842                        fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
3843                }
3844            }
3845            if (isDefault) {
3846                break; // Don't output default negative subpattern
3847            } else {
3848                if (localized) {
3849                    result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
3850                }
3851                else {
3852                    result.append((UChar)kPatternSeparator);
3853                }
3854            }
3855        } else {
3856            appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized);
3857            if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
3858                result.append(padSpec);
3859            }
3860        }
3861    }
3862
3863    return result;
3864}
3865
3866//------------------------------------------------------------------------------
3867
3868void
3869DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
3870{
3871    UParseError parseError;
3872    applyPattern(pattern, FALSE, parseError, status);
3873}
3874
3875//------------------------------------------------------------------------------
3876
3877void
3878DecimalFormat::applyPattern(const UnicodeString& pattern,
3879                            UParseError& parseError,
3880                            UErrorCode& status)
3881{
3882    applyPattern(pattern, FALSE, parseError, status);
3883}
3884//------------------------------------------------------------------------------
3885
3886void
3887DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
3888{
3889    UParseError parseError;
3890    applyPattern(pattern, TRUE,parseError,status);
3891}
3892
3893//------------------------------------------------------------------------------
3894
3895void
3896DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
3897                                     UParseError& parseError,
3898                                     UErrorCode& status)
3899{
3900    applyPattern(pattern, TRUE,parseError,status);
3901}
3902
3903//------------------------------------------------------------------------------
3904
3905void
3906DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern,
3907                                              UBool localized,
3908                                              UParseError& parseError,
3909                                              UErrorCode& status)
3910{
3911    if (U_FAILURE(status))
3912    {
3913        return;
3914    }
3915    // Clear error struct
3916    parseError.offset = -1;
3917    parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
3918
3919    // Set the significant pattern symbols
3920    UChar32 zeroDigit               = kPatternZeroDigit; // '0'
3921    UChar32 sigDigit                = kPatternSignificantDigit; // '@'
3922    UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator);
3923    UnicodeString decimalSeparator  ((UChar)kPatternDecimalSeparator);
3924    UnicodeString percent           ((UChar)kPatternPercent);
3925    UnicodeString perMill           ((UChar)kPatternPerMill);
3926    UnicodeString digit             ((UChar)kPatternDigit); // '#'
3927    UnicodeString separator         ((UChar)kPatternSeparator);
3928    UnicodeString exponent          ((UChar)kPatternExponent);
3929    UnicodeString plus              ((UChar)kPatternPlus);
3930    UnicodeString minus             ((UChar)kPatternMinus);
3931    UnicodeString padEscape         ((UChar)kPatternPadEscape);
3932    // Substitute with the localized symbols if necessary
3933    if (localized) {
3934        zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
3935        sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
3936        groupingSeparator.  remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
3937        decimalSeparator.   remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
3938        percent.            remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
3939        perMill.            remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
3940        digit.              remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
3941        separator.          remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
3942        exponent.           remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol));
3943        plus.               remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol));
3944        minus.              remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
3945        padEscape.          remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
3946    }
3947    UChar nineDigit = (UChar)(zeroDigit + 9);
3948    int32_t digitLen = digit.length();
3949    int32_t groupSepLen = groupingSeparator.length();
3950    int32_t decimalSepLen = decimalSeparator.length();
3951
3952    int32_t pos = 0;
3953    int32_t patLen = pattern.length();
3954    // Part 0 is the positive pattern.  Part 1, if present, is the negative
3955    // pattern.
3956    for (int32_t part=0; part<2 && pos<patLen; ++part) {
3957        // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
3958        // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
3959        // between the prefix and suffix, and consists of pattern
3960        // characters.  In the prefix and suffix, percent, perMill, and
3961        // currency symbols are recognized and translated.
3962        int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
3963
3964        // It's important that we don't change any fields of this object
3965        // prematurely.  We set the following variables for the multiplier,
3966        // grouping, etc., and then only change the actual object fields if
3967        // everything parses correctly.  This also lets us register
3968        // the data from part 0 and ignore the part 1, except for the
3969        // prefix and suffix.
3970        UnicodeString prefix;
3971        UnicodeString suffix;
3972        int32_t decimalPos = -1;
3973        int32_t multiplier = 1;
3974        int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
3975        int8_t groupingCount = -1;
3976        int8_t groupingCount2 = -1;
3977        int32_t padPos = -1;
3978        UChar32 padChar = 0;
3979        int32_t roundingPos = -1;
3980        DigitList roundingInc;
3981        int8_t expDigits = -1;
3982        UBool expSignAlways = FALSE;
3983
3984        // The affix is either the prefix or the suffix.
3985        UnicodeString* affix = &prefix;
3986
3987        int32_t start = pos;
3988        UBool isPartDone = FALSE;
3989        UChar32 ch;
3990
3991        for (; !isPartDone && pos < patLen; ) {
3992            // Todo: account for surrogate pairs
3993            ch = pattern.char32At(pos);
3994            switch (subpart) {
3995            case 0: // Pattern proper subpart (between prefix & suffix)
3996                // Process the digits, decimal, and grouping characters.  We
3997                // record five pieces of information.  We expect the digits
3998                // to occur in the pattern ####00.00####, and we record the
3999                // number of left digits, zero (central) digits, and right
4000                // digits.  The position of the last grouping character is
4001                // recorded (should be somewhere within the first two blocks
4002                // of characters), as is the position of the decimal point,
4003                // if any (should be in the zero digits).  If there is no
4004                // decimal point, then there should be no right digits.
4005                if (pattern.compare(pos, digitLen, digit) == 0) {
4006                    if (zeroDigitCount > 0 || sigDigitCount > 0) {
4007                        ++digitRightCount;
4008                    } else {
4009                        ++digitLeftCount;
4010                    }
4011                    if (groupingCount >= 0 && decimalPos < 0) {
4012                        ++groupingCount;
4013                    }
4014                    pos += digitLen;
4015                } else if ((ch >= zeroDigit && ch <= nineDigit) ||
4016                           ch == sigDigit) {
4017                    if (digitRightCount > 0) {
4018                        // Unexpected '0'
4019                        debug("Unexpected '0'")
4020                        status = U_UNEXPECTED_TOKEN;
4021                        syntaxError(pattern,pos,parseError);
4022                        return;
4023                    }
4024                    if (ch == sigDigit) {
4025                        ++sigDigitCount;
4026                    } else {
4027                        ++zeroDigitCount;
4028                        if (ch != zeroDigit && roundingPos < 0) {
4029                            roundingPos = digitLeftCount + zeroDigitCount;
4030                        }
4031                        if (roundingPos >= 0) {
4032                            roundingInc.append((char)(ch - zeroDigit + '0'));
4033                        }
4034                    }
4035                    if (groupingCount >= 0 && decimalPos < 0) {
4036                        ++groupingCount;
4037                    }
4038                    pos += U16_LENGTH(ch);
4039                } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
4040                    if (decimalPos >= 0) {
4041                        // Grouping separator after decimal
4042                        debug("Grouping separator after decimal")
4043                        status = U_UNEXPECTED_TOKEN;
4044                        syntaxError(pattern,pos,parseError);
4045                        return;
4046                    }
4047                    groupingCount2 = groupingCount;
4048                    groupingCount = 0;
4049                    pos += groupSepLen;
4050                } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
4051                    if (decimalPos >= 0) {
4052                        // Multiple decimal separators
4053                        debug("Multiple decimal separators")
4054                        status = U_MULTIPLE_DECIMAL_SEPARATORS;
4055                        syntaxError(pattern,pos,parseError);
4056                        return;
4057                    }
4058                    // Intentionally incorporate the digitRightCount,
4059                    // even though it is illegal for this to be > 0
4060                    // at this point.  We check pattern syntax below.
4061                    decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
4062                    pos += decimalSepLen;
4063                } else {
4064                    if (pattern.compare(pos, exponent.length(), exponent) == 0) {
4065                        if (expDigits >= 0) {
4066                            // Multiple exponential symbols
4067                            debug("Multiple exponential symbols")
4068                            status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
4069                            syntaxError(pattern,pos,parseError);
4070                            return;
4071                        }
4072                        if (groupingCount >= 0) {
4073                            // Grouping separator in exponential pattern
4074                            debug("Grouping separator in exponential pattern")
4075                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
4076                            syntaxError(pattern,pos,parseError);
4077                            return;
4078                        }
4079                        pos += exponent.length();
4080                        // Check for positive prefix
4081                        if (pos < patLen
4082                            && pattern.compare(pos, plus.length(), plus) == 0) {
4083                            expSignAlways = TRUE;
4084                            pos += plus.length();
4085                        }
4086                        // Use lookahead to parse out the exponential part of the
4087                        // pattern, then jump into suffix subpart.
4088                        expDigits = 0;
4089                        while (pos < patLen &&
4090                               pattern.char32At(pos) == zeroDigit) {
4091                            ++expDigits;
4092                            pos += U16_LENGTH(zeroDigit);
4093                        }
4094
4095                        // 1. Require at least one mantissa pattern digit
4096                        // 2. Disallow "#+ @" in mantissa
4097                        // 3. Require at least one exponent pattern digit
4098                        if (((digitLeftCount + zeroDigitCount) < 1 &&
4099                             (sigDigitCount + digitRightCount) < 1) ||
4100                            (sigDigitCount > 0 && digitLeftCount > 0) ||
4101                            expDigits < 1) {
4102                            // Malformed exponential pattern
4103                            debug("Malformed exponential pattern")
4104                            status = U_MALFORMED_EXPONENTIAL_PATTERN;
4105                            syntaxError(pattern,pos,parseError);
4106                            return;
4107                        }
4108                    }
4109                    // Transition to suffix subpart
4110                    subpart = 2; // suffix subpart
4111                    affix = &suffix;
4112                    sub0Limit = pos;
4113                    continue;
4114                }
4115                break;
4116            case 1: // Prefix subpart
4117            case 2: // Suffix subpart
4118                // Process the prefix / suffix characters
4119                // Process unquoted characters seen in prefix or suffix
4120                // subpart.
4121
4122                // Several syntax characters implicitly begins the
4123                // next subpart if we are in the prefix; otherwise
4124                // they are illegal if unquoted.
4125                if (!pattern.compare(pos, digitLen, digit) ||
4126                    !pattern.compare(pos, groupSepLen, groupingSeparator) ||
4127                    !pattern.compare(pos, decimalSepLen, decimalSeparator) ||
4128                    (ch >= zeroDigit && ch <= nineDigit) ||
4129                    ch == sigDigit) {
4130                    if (subpart == 1) { // prefix subpart
4131                        subpart = 0; // pattern proper subpart
4132                        sub0Start = pos; // Reprocess this character
4133                        continue;
4134                    } else {
4135                        status = U_UNQUOTED_SPECIAL;
4136                        syntaxError(pattern,pos,parseError);
4137                        return;
4138                    }
4139                } else if (ch == kCurrencySign) {
4140                    affix->append(kQuote); // Encode currency
4141                    // Use lookahead to determine if the currency sign is
4142                    // doubled or not.
4143                    U_ASSERT(U16_LENGTH(kCurrencySign) == 1);
4144                    if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) {
4145                        affix->append(kCurrencySign);
4146                        ++pos; // Skip over the doubled character
4147                        if ((pos+1) < pattern.length() &&
4148                            pattern[pos+1] == kCurrencySign) {
4149                            affix->append(kCurrencySign);
4150                            ++pos; // Skip over the doubled character
4151                            fCurrencySignCount = fgCurrencySignCountInPluralFormat;
4152                        } else {
4153                            fCurrencySignCount = fgCurrencySignCountInISOFormat;
4154                        }
4155                    } else {
4156                        fCurrencySignCount = fgCurrencySignCountInSymbolFormat;
4157                    }
4158                    // Fall through to append(ch)
4159                } else if (ch == kQuote) {
4160                    // A quote outside quotes indicates either the opening
4161                    // quote or two quotes, which is a quote literal.  That is,
4162                    // we have the first quote in 'do' or o''clock.
4163                    U_ASSERT(U16_LENGTH(kQuote) == 1);
4164                    ++pos;
4165                    if (pos < pattern.length() && pattern[pos] == kQuote) {
4166                        affix->append(kQuote); // Encode quote
4167                        // Fall through to append(ch)
4168                    } else {
4169                        subpart += 2; // open quote
4170                        continue;
4171                    }
4172                } else if (pattern.compare(pos, separator.length(), separator) == 0) {
4173                    // Don't allow separators in the prefix, and don't allow
4174                    // separators in the second pattern (part == 1).
4175                    if (subpart == 1 || part == 1) {
4176                        // Unexpected separator
4177                        debug("Unexpected separator")
4178                        status = U_UNEXPECTED_TOKEN;
4179                        syntaxError(pattern,pos,parseError);
4180                        return;
4181                    }
4182                    sub2Limit = pos;
4183                    isPartDone = TRUE; // Go to next part
4184                    pos += separator.length();
4185                    break;
4186                } else if (pattern.compare(pos, percent.length(), percent) == 0) {
4187                    // Next handle characters which are appended directly.
4188                    if (multiplier != 1) {
4189                        // Too many percent/perMill characters
4190                        debug("Too many percent characters")
4191                        status = U_MULTIPLE_PERCENT_SYMBOLS;
4192                        syntaxError(pattern,pos,parseError);
4193                        return;
4194                    }
4195                    affix->append(kQuote); // Encode percent/perMill
4196                    affix->append(kPatternPercent); // Use unlocalized pattern char
4197                    multiplier = 100;
4198                    pos += percent.length();
4199                    break;
4200                } else if (pattern.compare(pos, perMill.length(), perMill) == 0) {
4201                    // Next handle characters which are appended directly.
4202                    if (multiplier != 1) {
4203                        // Too many percent/perMill characters
4204                        debug("Too many perMill characters")
4205                        status = U_MULTIPLE_PERMILL_SYMBOLS;
4206                        syntaxError(pattern,pos,parseError);
4207                        return;
4208                    }
4209                    affix->append(kQuote); // Encode percent/perMill
4210                    affix->append(kPatternPerMill); // Use unlocalized pattern char
4211                    multiplier = 1000;
4212                    pos += perMill.length();
4213                    break;
4214                } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) {
4215                    if (padPos >= 0 ||               // Multiple pad specifiers
4216                        (pos+1) == pattern.length()) { // Nothing after padEscape
4217                        debug("Multiple pad specifiers")
4218                        status = U_MULTIPLE_PAD_SPECIFIERS;
4219                        syntaxError(pattern,pos,parseError);
4220                        return;
4221                    }
4222                    padPos = pos;
4223                    pos += padEscape.length();
4224                    padChar = pattern.char32At(pos);
4225                    pos += U16_LENGTH(padChar);
4226                    break;
4227                } else if (pattern.compare(pos, minus.length(), minus) == 0) {
4228                    affix->append(kQuote); // Encode minus
4229                    affix->append(kPatternMinus);
4230                    pos += minus.length();
4231                    break;
4232                } else if (pattern.compare(pos, plus.length(), plus) == 0) {
4233                    affix->append(kQuote); // Encode plus
4234                    affix->append(kPatternPlus);
4235                    pos += plus.length();
4236                    break;
4237                }
4238                // Unquoted, non-special characters fall through to here, as
4239                // well as other code which needs to append something to the
4240                // affix.
4241                affix->append(ch);
4242                pos += U16_LENGTH(ch);
4243                break;
4244            case 3: // Prefix subpart, in quote
4245            case 4: // Suffix subpart, in quote
4246                // A quote within quotes indicates either the closing
4247                // quote or two quotes, which is a quote literal.  That is,
4248                // we have the second quote in 'do' or 'don''t'.
4249                if (ch == kQuote) {
4250                    ++pos;
4251                    if (pos < pattern.length() && pattern[pos] == kQuote) {
4252                        affix->append(kQuote); // Encode quote
4253                        // Fall through to append(ch)
4254                    } else {
4255                        subpart -= 2; // close quote
4256                        continue;
4257                    }
4258                }
4259                affix->append(ch);
4260                pos += U16_LENGTH(ch);
4261                break;
4262            }
4263        }
4264
4265        if (sub0Limit == 0) {
4266            sub0Limit = pattern.length();
4267        }
4268
4269        if (sub2Limit == 0) {
4270            sub2Limit = pattern.length();
4271        }
4272
4273        /* Handle patterns with no '0' pattern character.  These patterns
4274         * are legal, but must be recodified to make sense.  "##.###" ->
4275         * "#0.###".  ".###" -> ".0##".
4276         *
4277         * We allow patterns of the form "####" to produce a zeroDigitCount
4278         * of zero (got that?); although this seems like it might make it
4279         * possible for format() to produce empty strings, format() checks
4280         * for this condition and outputs a zero digit in this situation.
4281         * Having a zeroDigitCount of zero yields a minimum integer digits
4282         * of zero, which allows proper round-trip patterns.  We don't want
4283         * "#" to become "#0" when toPattern() is called (even though that's
4284         * what it really is, semantically).
4285         */
4286        if (zeroDigitCount == 0 && sigDigitCount == 0 &&
4287            digitLeftCount > 0 && decimalPos >= 0) {
4288            // Handle "###.###" and "###." and ".###"
4289            int n = decimalPos;
4290            if (n == 0)
4291                ++n; // Handle ".###"
4292            digitRightCount = digitLeftCount - n;
4293            digitLeftCount = n - 1;
4294            zeroDigitCount = 1;
4295        }
4296
4297        // Do syntax checking on the digits, decimal points, and quotes.
4298        if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
4299            (decimalPos >= 0 &&
4300             (sigDigitCount > 0 ||
4301              decimalPos < digitLeftCount ||
4302              decimalPos > (digitLeftCount + zeroDigitCount))) ||
4303            groupingCount == 0 || groupingCount2 == 0 ||
4304            (sigDigitCount > 0 && zeroDigitCount > 0) ||
4305            subpart > 2)
4306        { // subpart > 2 == unmatched quote
4307            debug("Syntax error")
4308            status = U_PATTERN_SYNTAX_ERROR;
4309            syntaxError(pattern,pos,parseError);
4310            return;
4311        }
4312
4313        // Make sure pad is at legal position before or after affix.
4314        if (padPos >= 0) {
4315            if (padPos == start) {
4316                padPos = kPadBeforePrefix;
4317            } else if (padPos+2 == sub0Start) {
4318                padPos = kPadAfterPrefix;
4319            } else if (padPos == sub0Limit) {
4320                padPos = kPadBeforeSuffix;
4321            } else if (padPos+2 == sub2Limit) {
4322                padPos = kPadAfterSuffix;
4323            } else {
4324                // Illegal pad position
4325                debug("Illegal pad position")
4326                status = U_ILLEGAL_PAD_POSITION;
4327                syntaxError(pattern,pos,parseError);
4328                return;
4329            }
4330        }
4331
4332        if (part == 0) {
4333            delete fPosPrefixPattern;
4334            delete fPosSuffixPattern;
4335            delete fNegPrefixPattern;
4336            delete fNegSuffixPattern;
4337            fPosPrefixPattern = new UnicodeString(prefix);
4338            /* test for NULL */
4339            if (fPosPrefixPattern == 0) {
4340                status = U_MEMORY_ALLOCATION_ERROR;
4341                return;
4342            }
4343            fPosSuffixPattern = new UnicodeString(suffix);
4344            /* test for NULL */
4345            if (fPosSuffixPattern == 0) {
4346                status = U_MEMORY_ALLOCATION_ERROR;
4347                delete fPosPrefixPattern;
4348                return;
4349            }
4350            fNegPrefixPattern = 0;
4351            fNegSuffixPattern = 0;
4352
4353            fUseExponentialNotation = (expDigits >= 0);
4354            if (fUseExponentialNotation) {
4355                fMinExponentDigits = expDigits;
4356            }
4357            fExponentSignAlwaysShown = expSignAlways;
4358            int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
4359            // The effectiveDecimalPos is the position the decimal is at or
4360            // would be at if there is no decimal.  Note that if
4361            // decimalPos<0, then digitTotalCount == digitLeftCount +
4362            // zeroDigitCount.
4363            int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
4364            UBool isSigDig = (sigDigitCount > 0);
4365            setSignificantDigitsUsed(isSigDig);
4366            if (isSigDig) {
4367                setMinimumSignificantDigits(sigDigitCount);
4368                setMaximumSignificantDigits(sigDigitCount + digitRightCount);
4369            } else {
4370                int32_t minInt = effectiveDecimalPos - digitLeftCount;
4371                setMinimumIntegerDigits(minInt);
4372                setMaximumIntegerDigits(fUseExponentialNotation
4373                    ? digitLeftCount + getMinimumIntegerDigits()
4374                    : kDoubleIntegerDigits);
4375                setMaximumFractionDigits(decimalPos >= 0
4376                    ? (digitTotalCount - decimalPos) : 0);
4377                setMinimumFractionDigits(decimalPos >= 0
4378                    ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
4379            }
4380            setGroupingUsed(groupingCount > 0);
4381            fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
4382            fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
4383                ? groupingCount2 : 0;
4384            setMultiplier(multiplier);
4385            setDecimalSeparatorAlwaysShown(decimalPos == 0
4386                    || decimalPos == digitTotalCount);
4387            if (padPos >= 0) {
4388                fPadPosition = (EPadPosition) padPos;
4389                // To compute the format width, first set up sub0Limit -
4390                // sub0Start.  Add in prefix/suffix length later.
4391
4392                // fFormatWidth = prefix.length() + suffix.length() +
4393                //    sub0Limit - sub0Start;
4394                fFormatWidth = sub0Limit - sub0Start;
4395                fPad = padChar;
4396            } else {
4397                fFormatWidth = 0;
4398            }
4399            if (roundingPos >= 0) {
4400                roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos);
4401                if (fRoundingIncrement != NULL) {
4402                    *fRoundingIncrement = roundingInc;
4403                } else {
4404                    fRoundingIncrement = new DigitList(roundingInc);
4405                    /* test for NULL */
4406                    if (fRoundingIncrement == NULL) {
4407                        status = U_MEMORY_ALLOCATION_ERROR;
4408                        delete fPosPrefixPattern;
4409                        delete fPosSuffixPattern;
4410                        return;
4411                    }
4412                }
4413                fRoundingIncrement->getDouble();   // forces caching of double in the DigitList,
4414                                                   //    makes getting it thread safe.
4415                fRoundingMode = kRoundHalfEven;
4416            } else {
4417                setRoundingIncrement(0.0);
4418            }
4419        } else {
4420            fNegPrefixPattern = new UnicodeString(prefix);
4421            /* test for NULL */
4422            if (fNegPrefixPattern == 0) {
4423                status = U_MEMORY_ALLOCATION_ERROR;
4424                return;
4425            }
4426            fNegSuffixPattern = new UnicodeString(suffix);
4427            /* test for NULL */
4428            if (fNegSuffixPattern == 0) {
4429                delete fNegPrefixPattern;
4430                status = U_MEMORY_ALLOCATION_ERROR;
4431                return;
4432            }
4433        }
4434    }
4435
4436    if (pattern.length() == 0) {
4437        delete fNegPrefixPattern;
4438        delete fNegSuffixPattern;
4439        fNegPrefixPattern = NULL;
4440        fNegSuffixPattern = NULL;
4441        if (fPosPrefixPattern != NULL) {
4442            fPosPrefixPattern->remove();
4443        } else {
4444            fPosPrefixPattern = new UnicodeString();
4445            /* test for NULL */
4446            if (fPosPrefixPattern == 0) {
4447                status = U_MEMORY_ALLOCATION_ERROR;
4448                return;
4449            }
4450        }
4451        if (fPosSuffixPattern != NULL) {
4452            fPosSuffixPattern->remove();
4453        } else {
4454            fPosSuffixPattern = new UnicodeString();
4455            /* test for NULL */
4456            if (fPosSuffixPattern == 0) {
4457                delete fPosPrefixPattern;
4458                status = U_MEMORY_ALLOCATION_ERROR;
4459                return;
4460            }
4461        }
4462
4463        setMinimumIntegerDigits(0);
4464        setMaximumIntegerDigits(kDoubleIntegerDigits);
4465        setMinimumFractionDigits(0);
4466        setMaximumFractionDigits(kDoubleFractionDigits);
4467
4468        fUseExponentialNotation = FALSE;
4469        fCurrencySignCount = 0;
4470        setGroupingUsed(FALSE);
4471        fGroupingSize = 0;
4472        fGroupingSize2 = 0;
4473        setMultiplier(1);
4474        setDecimalSeparatorAlwaysShown(FALSE);
4475        fFormatWidth = 0;
4476        setRoundingIncrement(0.0);
4477    }
4478
4479    // If there was no negative pattern, or if the negative pattern is
4480    // identical to the positive pattern, then prepend the minus sign to the
4481    // positive pattern to form the negative pattern.
4482    if (fNegPrefixPattern == NULL ||
4483        (*fNegPrefixPattern == *fPosPrefixPattern
4484         && *fNegSuffixPattern == *fPosSuffixPattern)) {
4485        _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern);
4486        if (fNegPrefixPattern == NULL) {
4487            fNegPrefixPattern = new UnicodeString();
4488            /* test for NULL */
4489            if (fNegPrefixPattern == 0) {
4490                status = U_MEMORY_ALLOCATION_ERROR;
4491                return;
4492            }
4493        } else {
4494            fNegPrefixPattern->remove();
4495        }
4496        fNegPrefixPattern->append(kQuote).append(kPatternMinus)
4497            .append(*fPosPrefixPattern);
4498    }
4499#ifdef FMT_DEBUG
4500    UnicodeString s;
4501    s.append("\"").append(pattern).append("\"->");
4502    debugout(s);
4503#endif
4504
4505    // save the pattern
4506    fFormatPattern = pattern;
4507}
4508
4509
4510void
4511DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) {
4512    expandAffixes(pluralCount);
4513    if (fFormatWidth > 0) {
4514        // Finish computing format width (see above)
4515            // TODO: how to handle fFormatWidth,
4516            // need to save in f(Plural)AffixesForCurrecy?
4517            fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length();
4518    }
4519}
4520
4521
4522void
4523DecimalFormat::applyPattern(const UnicodeString& pattern,
4524                            UBool localized,
4525                            UParseError& parseError,
4526                            UErrorCode& status)
4527{
4528    // do the following re-set first. since they change private data by
4529    // apply pattern again.
4530    if (pattern.indexOf(kCurrencySign) != -1) {
4531        if (fCurrencyPluralInfo == NULL) {
4532            // initialize currencyPluralInfo if needed
4533            fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
4534        }
4535        if (fAffixPatternsForCurrency == NULL) {
4536            setupCurrencyAffixPatterns(status);
4537        }
4538        if (pattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) {
4539            // only setup the affixes of the current pattern.
4540            setupCurrencyAffixes(pattern, TRUE, FALSE, status);
4541        }
4542    }
4543    applyPatternWithoutExpandAffix(pattern, localized, parseError, status);
4544    expandAffixAdjustWidth(NULL);
4545}
4546
4547
4548void
4549DecimalFormat::applyPatternInternally(const UnicodeString& pluralCount,
4550                                      const UnicodeString& pattern,
4551                                      UBool localized,
4552                                      UParseError& parseError,
4553                                      UErrorCode& status) {
4554    applyPatternWithoutExpandAffix(pattern, localized, parseError, status);
4555    expandAffixAdjustWidth(&pluralCount);
4556}
4557
4558
4559/**
4560 * Sets the maximum number of digits allowed in the integer portion of a
4561 * number. This override limits the integer digit count to 309.
4562 * @see NumberFormat#setMaximumIntegerDigits
4563 */
4564void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
4565    NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
4566}
4567
4568/**
4569 * Sets the minimum number of digits allowed in the integer portion of a
4570 * number. This override limits the integer digit count to 309.
4571 * @see NumberFormat#setMinimumIntegerDigits
4572 */
4573void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
4574    NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
4575}
4576
4577/**
4578 * Sets the maximum number of digits allowed in the fraction portion of a
4579 * number. This override limits the fraction digit count to 340.
4580 * @see NumberFormat#setMaximumFractionDigits
4581 */
4582void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
4583    NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits));
4584}
4585
4586/**
4587 * Sets the minimum number of digits allowed in the fraction portion of a
4588 * number. This override limits the fraction digit count to 340.
4589 * @see NumberFormat#setMinimumFractionDigits
4590 */
4591void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
4592    NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits));
4593}
4594
4595int32_t DecimalFormat::getMinimumSignificantDigits() const {
4596    return fMinSignificantDigits;
4597}
4598
4599int32_t DecimalFormat::getMaximumSignificantDigits() const {
4600    return fMaxSignificantDigits;
4601}
4602
4603void DecimalFormat::setMinimumSignificantDigits(int32_t min) {
4604    if (min < 1) {
4605        min = 1;
4606    }
4607    // pin max sig dig to >= min
4608    int32_t max = _max(fMaxSignificantDigits, min);
4609    fMinSignificantDigits = min;
4610    fMaxSignificantDigits = max;
4611}
4612
4613void DecimalFormat::setMaximumSignificantDigits(int32_t max) {
4614    if (max < 1) {
4615        max = 1;
4616    }
4617    // pin min sig dig to 1..max
4618    U_ASSERT(fMinSignificantDigits >= 1);
4619    int32_t min = _min(fMinSignificantDigits, max);
4620    fMinSignificantDigits = min;
4621    fMaxSignificantDigits = max;
4622}
4623
4624UBool DecimalFormat::areSignificantDigitsUsed() const {
4625    return fUseSignificantDigits;
4626}
4627
4628void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
4629    fUseSignificantDigits = useSignificantDigits;
4630}
4631
4632void DecimalFormat::setCurrencyInternally(const UChar* theCurrency,
4633                                          UErrorCode& ec) {
4634    // If we are a currency format, then modify our affixes to
4635    // encode the currency symbol for the given currency in our
4636    // locale, and adjust the decimal digits and rounding for the
4637    // given currency.
4638
4639    // Note: The code is ordered so that this object is *not changed*
4640    // until we are sure we are going to succeed.
4641
4642    // NULL or empty currency is *legal* and indicates no currency.
4643    UBool isCurr = (theCurrency && *theCurrency);
4644
4645    double rounding = 0.0;
4646    int32_t frac = 0;
4647    if (fCurrencySignCount > fgCurrencySignCountZero && isCurr) {
4648        rounding = ucurr_getRoundingIncrement(theCurrency, &ec);
4649        frac = ucurr_getDefaultFractionDigits(theCurrency, &ec);
4650    }
4651
4652    NumberFormat::setCurrency(theCurrency, ec);
4653    if (U_FAILURE(ec)) return;
4654
4655    if (fCurrencySignCount > fgCurrencySignCountZero) {
4656        // NULL or empty currency is *legal* and indicates no currency.
4657        if (isCurr) {
4658            setRoundingIncrement(rounding);
4659            setMinimumFractionDigits(frac);
4660            setMaximumFractionDigits(frac);
4661        }
4662        expandAffixes(NULL);
4663    }
4664}
4665
4666void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
4667    // set the currency before compute affixes to get the right currency names
4668    NumberFormat::setCurrency(theCurrency, ec);
4669    if (fFormatPattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) {
4670        UnicodeString savedPtn = fFormatPattern;
4671        setupCurrencyAffixes(fFormatPattern, TRUE, TRUE, ec);
4672        UParseError parseErr;
4673        applyPattern(savedPtn, FALSE, parseErr, ec);
4674    }
4675    // set the currency after apply pattern to get the correct rounding/fraction
4676    setCurrencyInternally(theCurrency, ec);
4677}
4678
4679// Deprecated variant with no UErrorCode parameter
4680void DecimalFormat::setCurrency(const UChar* theCurrency) {
4681    UErrorCode ec = U_ZERO_ERROR;
4682    setCurrency(theCurrency, ec);
4683}
4684
4685void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
4686    if (fSymbols == NULL) {
4687        ec = U_MEMORY_ALLOCATION_ERROR;
4688        return;
4689    }
4690    ec = U_ZERO_ERROR;
4691    const UChar* c = getCurrency();
4692    if (*c == 0) {
4693        const UnicodeString &intl =
4694            fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
4695        c = intl.getBuffer(); // ok for intl to go out of scope
4696    }
4697    u_strncpy(result, c, 3);
4698    result[3] = 0;
4699}
4700
4701/**
4702 * Return the number of fraction digits to display, or the total
4703 * number of digits for significant digit formats and exponential
4704 * formats.
4705 */
4706int32_t
4707DecimalFormat::precision() const {
4708    if (areSignificantDigitsUsed()) {
4709        return getMaximumSignificantDigits();
4710    } else if (fUseExponentialNotation) {
4711        return getMinimumIntegerDigits() + getMaximumFractionDigits();
4712    } else {
4713        return getMaximumFractionDigits();
4714    }
4715}
4716
4717
4718// TODO: template algorithm
4719Hashtable*
4720DecimalFormat::initHashForAffix(UErrorCode& status) {
4721    if ( U_FAILURE(status) ) {
4722        return NULL;
4723    }
4724    Hashtable* hTable;
4725    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
4726        status = U_MEMORY_ALLOCATION_ERROR;
4727        return NULL;
4728    }
4729    if ( U_FAILURE(status) ) {
4730        delete hTable;
4731        return NULL;
4732    }
4733    hTable->setValueComparator(decimfmtAffixValueComparator);
4734    return hTable;
4735}
4736
4737Hashtable*
4738DecimalFormat::initHashForAffixPattern(UErrorCode& status) {
4739    if ( U_FAILURE(status) ) {
4740        return NULL;
4741    }
4742    Hashtable* hTable;
4743    if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
4744        status = U_MEMORY_ALLOCATION_ERROR;
4745        return NULL;
4746    }
4747    if ( U_FAILURE(status) ) {
4748        delete hTable;
4749        return NULL;
4750    }
4751    hTable->setValueComparator(decimfmtAffixPatternValueComparator);
4752    return hTable;
4753}
4754
4755void
4756DecimalFormat::deleteHashForAffix(Hashtable*& table)
4757{
4758    if ( table == NULL ) {
4759        return;
4760    }
4761    int32_t pos = -1;
4762    const UHashElement* element = NULL;
4763    while ( (element = table->nextElement(pos)) != NULL ) {
4764        const UHashTok valueTok = element->value;
4765        const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer;
4766        delete value;
4767    }
4768    delete table;
4769    table = NULL;
4770}
4771
4772
4773
4774void
4775DecimalFormat::deleteHashForAffixPattern()
4776{
4777    if ( fAffixPatternsForCurrency == NULL ) {
4778        return;
4779    }
4780    int32_t pos = -1;
4781    const UHashElement* element = NULL;
4782    while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
4783        const UHashTok valueTok = element->value;
4784        const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
4785        delete value;
4786    }
4787    delete fAffixPatternsForCurrency;
4788    fAffixPatternsForCurrency = NULL;
4789}
4790
4791
4792void
4793DecimalFormat::copyHashForAffixPattern(const Hashtable* source,
4794                                       Hashtable* target,
4795                                       UErrorCode& status) {
4796    if ( U_FAILURE(status) ) {
4797        return;
4798    }
4799    int32_t pos = -1;
4800    const UHashElement* element = NULL;
4801    if ( source ) {
4802        while ( (element = source->nextElement(pos)) != NULL ) {
4803            const UHashTok keyTok = element->key;
4804            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
4805            const UHashTok valueTok = element->value;
4806            const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
4807            AffixPatternsForCurrency* copy = new AffixPatternsForCurrency(
4808                value->negPrefixPatternForCurrency,
4809                value->negSuffixPatternForCurrency,
4810                value->posPrefixPatternForCurrency,
4811                value->posSuffixPatternForCurrency,
4812                value->patternType);
4813            target->put(UnicodeString(*key), copy, status);
4814            if ( U_FAILURE(status) ) {
4815                return;
4816            }
4817        }
4818    }
4819}
4820
4821
4822
4823void
4824DecimalFormat::copyHashForAffix(const Hashtable* source,
4825                                Hashtable* target,
4826                                UErrorCode& status) {
4827    if ( U_FAILURE(status) ) {
4828        return;
4829    }
4830    int32_t pos = -1;
4831    const UHashElement* element = NULL;
4832    if ( source ) {
4833        while ( (element = source->nextElement(pos)) != NULL ) {
4834            const UHashTok keyTok = element->key;
4835            const UnicodeString* key = (UnicodeString*)keyTok.pointer;
4836
4837            const UHashTok valueTok = element->value;
4838            const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer;
4839            AffixesForCurrency* copy = new AffixesForCurrency(
4840                value->negPrefixForCurrency,
4841                value->negSuffixForCurrency,
4842                value->posPrefixForCurrency,
4843                value->posSuffixForCurrency);
4844            target->put(UnicodeString(*key), copy, status);
4845            if ( U_FAILURE(status) ) {
4846                return;
4847            }
4848        }
4849    }
4850}
4851
4852U_NAMESPACE_END
4853
4854#endif /* #if !UCONFIG_NO_FORMATTING */
4855
4856//eof
4857