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