Home | History | Annotate | Download | only in i18n
      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 
     71 U_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  */
     79 struct 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  */
    107 struct 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 
    130 U_CDECL_BEGIN
    131 
    132 /**
    133  * @internal ICU 4.2
    134  */
    135 static UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2);
    136 
    137 /**
    138  * @internal ICU 4.2
    139  */
    140 static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2);
    141 
    142 
    143 static UBool
    144 U_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 
    156 static UBool
    157 U_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 
    173 U_CDECL_END
    174 
    175 
    176 //#define FMT_DEBUG
    177 
    178 #ifdef FMT_DEBUG
    179 #include <stdio.h>
    180 static 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 
    197 UOBJECT_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 
    223 const int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
    224 const int32_t DecimalFormat::kDoubleFractionDigits = 340;
    225 
    226 const 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  */
    232 const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used
    233 static const char fgNumberElements[]="NumberElements";
    234 static const char fgLatn[]="latn";
    235 static const char fgPatterns[]="patterns";
    236 static const char fgDecimalFormat[]="decimalFormat";
    237 static const char fgCurrencyFormat[]="currencyFormat";
    238 static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
    239 
    240 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
    241 inline 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 
    246 DecimalFormat::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 
    256 DecimalFormat::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 
    268 DecimalFormat::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 
    278 DecimalFormat::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 
    293 DecimalFormat::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 
    306 DecimalFormat::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.
    320 void
    321 DecimalFormat::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 
    356 void
    357 DecimalFormat::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 
    477 void
    478 DecimalFormat::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 
    540 void
    541 DecimalFormat::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 
    606 DecimalFormat::~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 
    625 DecimalFormat::DecimalFormat(const DecimalFormat &source) :
    626     NumberFormat(source) {
    627     init();
    628     *this = source;
    629 }
    630 
    631 //------------------------------------------------------------------------------
    632 // assignment operator
    633 
    634 static 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 
    645 DecimalFormat&
    646 DecimalFormat::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 
    722 UBool
    723 DecimalFormat::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 
    914 Format*
    915 DecimalFormat::clone() const
    916 {
    917     return new DecimalFormat(*this);
    918 }
    919 
    920 //------------------------------------------------------------------------------
    921 
    922 UnicodeString&
    923 DecimalFormat::format(int32_t number,
    924                       UnicodeString& appendTo,
    925                       FieldPosition& fieldPosition) const
    926 {
    927     return format((int64_t)number, appendTo, fieldPosition);
    928 }
    929 
    930 UnicodeString&
    931 DecimalFormat::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 
    941 UnicodeString&
    942 DecimalFormat::format(int64_t number,
    943                       UnicodeString& appendTo,
    944                       FieldPosition& fieldPosition) const
    945 {
    946     FieldPositionOnlyHandler handler(fieldPosition);
    947     return _format(number, appendTo, handler);
    948 }
    949 
    950 UnicodeString&
    951 DecimalFormat::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 
    960 UnicodeString&
    961 DecimalFormat::_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 
    973 UnicodeString&
    974 DecimalFormat::format(  double number,
    975                         UnicodeString& appendTo,
    976                         FieldPosition& fieldPosition) const
    977 {
    978     FieldPositionOnlyHandler handler(fieldPosition);
    979     return _format(number, appendTo, handler);
    980 }
    981 
    982 UnicodeString&
    983 DecimalFormat::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 
    992 UnicodeString&
    993 DecimalFormat::_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 
   1022 UnicodeString&
   1023 DecimalFormat::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 
   1039 UnicodeString&
   1040 DecimalFormat::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 
   1051 UnicodeString&
   1052 DecimalFormat::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 
   1063 UnicodeString&
   1064 DecimalFormat::_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 
   1149 UnicodeString&
   1150 DecimalFormat::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  */
   1168 UBool 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  */
   1186 UnicodeString&
   1187 DecimalFormat::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  */
   1518 void 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 
   1553 void
   1554 DecimalFormat::parse(const UnicodeString& text,
   1555                      Formattable& result,
   1556                      UErrorCode& status) const
   1557 {
   1558     NumberFormat::parse(text, result, status);
   1559 }
   1560 
   1561 void
   1562 DecimalFormat::parse(const UnicodeString& text,
   1563                      Formattable& result,
   1564                      ParsePosition& parsePosition) const {
   1565     parse(text, result, parsePosition, FALSE);
   1566 }
   1567 
   1568 Formattable& 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  */
   1587 void 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 
   1690 UBool
   1691 DecimalFormat::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  */
   1827 UBool 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  */
   2225 int32_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  */
   2252 int32_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  */
   2299 int32_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  */
   2423 int32_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  */
   2432 int32_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  */
   2455 int32_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  */
   2564 int32_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  */
   2584 int32_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 
   2596 UBool 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 
   2606 UBool 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 
   2620 UBool 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 
   2642 const DecimalFormatSymbols*
   2643 DecimalFormat::getDecimalFormatSymbols() const
   2644 {
   2645     return fSymbols;
   2646 }
   2647 
   2648 //------------------------------------------------------------------------------
   2649 // De-owning the current localized symbols and adopt the new symbols.
   2650 
   2651 void
   2652 DecimalFormat::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 
   2678 void
   2679 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
   2680 {
   2681     adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
   2682 }
   2683 
   2684 
   2685 const CurrencyPluralInfo*
   2686 DecimalFormat::getCurrencyPluralInfo(void) const
   2687 {
   2688     return fCurrencyPluralInfo;
   2689 }
   2690 
   2691 
   2692 void
   2693 DecimalFormat::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 
   2713 void
   2714 DecimalFormat::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  */
   2725 void
   2726 DecimalFormat::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 
   2763 UnicodeString&
   2764 DecimalFormat::getPositivePrefix(UnicodeString& result) const
   2765 {
   2766     result = fPositivePrefix;
   2767     return result;
   2768 }
   2769 
   2770 //------------------------------------------------------------------------------
   2771 // Sets the positive prefix of the number pattern.
   2772 
   2773 void
   2774 DecimalFormat::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 
   2784 UnicodeString&
   2785 DecimalFormat::getNegativePrefix(UnicodeString& result) const
   2786 {
   2787     result = fNegativePrefix;
   2788     return result;
   2789 }
   2790 
   2791 //------------------------------------------------------------------------------
   2792 // Gets the negative prefix  of the number pattern.
   2793 
   2794 void
   2795 DecimalFormat::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 
   2805 UnicodeString&
   2806 DecimalFormat::getPositiveSuffix(UnicodeString& result) const
   2807 {
   2808     result = fPositiveSuffix;
   2809     return result;
   2810 }
   2811 
   2812 //------------------------------------------------------------------------------
   2813 // Sets the positive suffix of the number pattern.
   2814 
   2815 void
   2816 DecimalFormat::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 
   2826 UnicodeString&
   2827 DecimalFormat::getNegativeSuffix(UnicodeString& result) const
   2828 {
   2829     result = fNegativeSuffix;
   2830     return result;
   2831 }
   2832 
   2833 //------------------------------------------------------------------------------
   2834 // Sets the negative suffix of the number pattern.
   2835 
   2836 void
   2837 DecimalFormat::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 
   2850 int32_t
   2851 DecimalFormat::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.
   2862 void
   2863 DecimalFormat::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  */
   2892 double 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  */
   2909 void 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  */
   2932 DecimalFormat::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  */
   2944 void 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  */
   2957 int32_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  */
   2973 void DecimalFormat::setFormatWidth(int32_t width) {
   2974     fFormatWidth = (width > 0) ? width : 0;
   2975 }
   2976 
   2977 UnicodeString DecimalFormat::getPadCharacterString() const {
   2978     return UnicodeString(fPad);
   2979 }
   2980 
   2981 void 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  */
   3007 DecimalFormat::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  */
   3030 void 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  */
   3043 UBool 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  */
   3057 void 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  */
   3070 int8_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  */
   3085 void 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  */
   3100 UBool 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  */
   3116 void 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 
   3124 int32_t
   3125 DecimalFormat::getGroupingSize() const
   3126 {
   3127     return fGroupingSize;
   3128 }
   3129 
   3130 //------------------------------------------------------------------------------
   3131 // Gets the grouping size of the number pattern.
   3132 
   3133 void
   3134 DecimalFormat::setGroupingSize(int32_t newValue)
   3135 {
   3136     fGroupingSize = newValue;
   3137 }
   3138 
   3139 //------------------------------------------------------------------------------
   3140 
   3141 int32_t
   3142 DecimalFormat::getSecondaryGroupingSize() const
   3143 {
   3144     return fGroupingSize2;
   3145 }
   3146 
   3147 //------------------------------------------------------------------------------
   3148 
   3149 void
   3150 DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
   3151 {
   3152     fGroupingSize2 = newValue;
   3153 }
   3154 
   3155 //------------------------------------------------------------------------------
   3156 // Checks if to show the decimal separator.
   3157 
   3158 UBool
   3159 DecimalFormat::isDecimalSeparatorAlwaysShown() const
   3160 {
   3161     return fDecimalSeparatorAlwaysShown;
   3162 }
   3163 
   3164 //------------------------------------------------------------------------------
   3165 // Sets to always show the decimal separator.
   3166 
   3167 void
   3168 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
   3169 {
   3170     fDecimalSeparatorAlwaysShown = newValue;
   3171 }
   3172 
   3173 //------------------------------------------------------------------------------
   3174 // Emits the pattern of this DecimalFormat instance.
   3175 
   3176 UnicodeString&
   3177 DecimalFormat::toPattern(UnicodeString& result) const
   3178 {
   3179     return toPattern(result, FALSE);
   3180 }
   3181 
   3182 //------------------------------------------------------------------------------
   3183 // Emits the localized pattern this DecimalFormat instance.
   3184 
   3185 UnicodeString&
   3186 DecimalFormat::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  */
   3205 void 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  */
   3271 void 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  */
   3426 int32_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  */
   3524 void 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  */
   3584 void
   3585 DecimalFormat::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 
   3633 UnicodeString&
   3634 DecimalFormat::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 
   3868 void
   3869 DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
   3870 {
   3871     UParseError parseError;
   3872     applyPattern(pattern, FALSE, parseError, status);
   3873 }
   3874 
   3875 //------------------------------------------------------------------------------
   3876 
   3877 void
   3878 DecimalFormat::applyPattern(const UnicodeString& pattern,
   3879                             UParseError& parseError,
   3880                             UErrorCode& status)
   3881 {
   3882     applyPattern(pattern, FALSE, parseError, status);
   3883 }
   3884 //------------------------------------------------------------------------------
   3885 
   3886 void
   3887 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
   3888 {
   3889     UParseError parseError;
   3890     applyPattern(pattern, TRUE,parseError,status);
   3891 }
   3892 
   3893 //------------------------------------------------------------------------------
   3894 
   3895 void
   3896 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
   3897                                      UParseError& parseError,
   3898                                      UErrorCode& status)
   3899 {
   3900     applyPattern(pattern, TRUE,parseError,status);
   3901 }
   3902 
   3903 //------------------------------------------------------------------------------
   3904 
   3905 void
   3906 DecimalFormat::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 
   4510 void
   4511 DecimalFormat::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 
   4522 void
   4523 DecimalFormat::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 
   4548 void
   4549 DecimalFormat::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  */
   4564 void 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  */
   4573 void 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  */
   4582 void 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  */
   4591 void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
   4592     NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits));
   4593 }
   4594 
   4595 int32_t DecimalFormat::getMinimumSignificantDigits() const {
   4596     return fMinSignificantDigits;
   4597 }
   4598 
   4599 int32_t DecimalFormat::getMaximumSignificantDigits() const {
   4600     return fMaxSignificantDigits;
   4601 }
   4602 
   4603 void 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 
   4613 void 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 
   4624 UBool DecimalFormat::areSignificantDigitsUsed() const {
   4625     return fUseSignificantDigits;
   4626 }
   4627 
   4628 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
   4629     fUseSignificantDigits = useSignificantDigits;
   4630 }
   4631 
   4632 void 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 
   4666 void 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
   4680 void DecimalFormat::setCurrency(const UChar* theCurrency) {
   4681     UErrorCode ec = U_ZERO_ERROR;
   4682     setCurrency(theCurrency, ec);
   4683 }
   4684 
   4685 void 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  */
   4706 int32_t
   4707 DecimalFormat::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
   4719 Hashtable*
   4720 DecimalFormat::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 
   4737 Hashtable*
   4738 DecimalFormat::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 
   4755 void
   4756 DecimalFormat::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 
   4774 void
   4775 DecimalFormat::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 
   4792 void
   4793 DecimalFormat::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 
   4823 void
   4824 DecimalFormat::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 
   4852 U_NAMESPACE_END
   4853 
   4854 #endif /* #if !UCONFIG_NO_FORMATTING */
   4855 
   4856 //eof
   4857