Home | History | Annotate | Download | only in i18n
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *******************************************************************************
      5 * Copyright (C) 1997-2015, International Business Machines Corporation and    *
      6 * others. All Rights Reserved.                                                *
      7 *******************************************************************************
      8 *
      9 * File DECIMFMT.CPP
     10 *
     11 * Modification History:
     12 *
     13 *   Date        Name        Description
     14 *   02/19/97    aliu        Converted from java.
     15 *   03/20/97    clhuang     Implemented with new APIs.
     16 *   03/31/97    aliu        Moved isLONG_MIN to DigitList, and fixed it.
     17 *   04/3/97     aliu        Rewrote parsing and formatting completely, and
     18 *                           cleaned up and debugged.  Actually works now.
     19 *                           Implemented NAN and INF handling, for both parsing
     20 *                           and formatting.  Extensive testing & debugging.
     21 *   04/10/97    aliu        Modified to compile on AIX.
     22 *   04/16/97    aliu        Rewrote to use DigitList, which has been resurrected.
     23 *                           Changed DigitCount to int per code review.
     24 *   07/09/97    helena      Made ParsePosition into a class.
     25 *   08/26/97    aliu        Extensive changes to applyPattern; completely
     26 *                           rewritten from the Java.
     27 *   09/09/97    aliu        Ported over support for exponential formats.
     28 *   07/20/98    stephen     JDK 1.2 sync up.
     29 *                             Various instances of '0' replaced with 'NULL'
     30 *                             Check for grouping size in subFormat()
     31 *                             Brought subParse() in line with Java 1.2
     32 *                             Added method appendAffix()
     33 *   08/24/1998  srl         Removed Mutex calls. This is not a thread safe class!
     34 *   02/22/99    stephen     Removed character literals for EBCDIC safety
     35 *   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
     36 *   06/28/99    stephen     Fixed bugs in toPattern().
     37 *   06/29/99    stephen     Fixed operator= to copy fFormatWidth, fPad,
     38 *                             fPadPosition
     39 ********************************************************************************
     40 */
     41 
     42 #include "unicode/utypes.h"
     43 
     44 #if !UCONFIG_NO_FORMATTING
     45 
     46 #include "unicode/uniset.h"
     47 #include "unicode/currpinf.h"
     48 #include "unicode/plurrule.h"
     49 #include "unicode/utf16.h"
     50 #include "unicode/numsys.h"
     51 #include "unicode/localpointer.h"
     52 #include "unicode/ustring.h"
     53 #include "uresimp.h"
     54 #include "ucurrimp.h"
     55 #include "charstr.h"
     56 #include "patternprops.h"
     57 #include "cstring.h"
     58 #include "uassert.h"
     59 #include "hash.h"
     60 #include "decfmtst.h"
     61 #include "plurrule_impl.h"
     62 #include "decimalformatpattern.h"
     63 #include "fmtableimp.h"
     64 #include "decimfmtimpl.h"
     65 #include "visibledigits.h"
     66 
     67 /*
     68  * On certain platforms, round is a macro defined in math.h
     69  * This undefine is to avoid conflict between the macro and
     70  * the function defined below.
     71  */
     72 #ifdef round
     73 #undef round
     74 #endif
     75 
     76 
     77 U_NAMESPACE_BEGIN
     78 
     79 #ifdef FMT_DEBUG
     80 #include <stdio.h>
     81 static void _debugout(const char *f, int l, const UnicodeString& s) {
     82     char buf[2000];
     83     s.extract((int32_t) 0, s.length(), buf, "utf-8");
     84     printf("%s:%d: %s\n", f,l, buf);
     85 }
     86 #define debugout(x) _debugout(__FILE__,__LINE__,x)
     87 #define debug(x) printf("%s:%d: %s\n", __FILE__,__LINE__, x);
     88 static const UnicodeString dbg_null("<NULL>","");
     89 #define DEREFSTR(x)   ((x!=NULL)?(*x):(dbg_null))
     90 #else
     91 #define debugout(x)
     92 #define debug(x)
     93 #endif
     94 
     95 
     96 /* For currency parsing purose,
     97  * Need to remember all prefix patterns and suffix patterns of
     98  * every currency format pattern,
     99  * including the pattern of default currecny style
    100  * and plural currency style. And the patterns are set through applyPattern.
    101  */
    102 struct AffixPatternsForCurrency : public UMemory {
    103 	// negative prefix pattern
    104 	UnicodeString negPrefixPatternForCurrency;
    105 	// negative suffix pattern
    106 	UnicodeString negSuffixPatternForCurrency;
    107 	// positive prefix pattern
    108 	UnicodeString posPrefixPatternForCurrency;
    109 	// positive suffix pattern
    110 	UnicodeString posSuffixPatternForCurrency;
    111 	int8_t patternType;
    112 
    113 	AffixPatternsForCurrency(const UnicodeString& negPrefix,
    114 							 const UnicodeString& negSuffix,
    115 							 const UnicodeString& posPrefix,
    116 							 const UnicodeString& posSuffix,
    117 							 int8_t type) {
    118 		negPrefixPatternForCurrency = negPrefix;
    119 		negSuffixPatternForCurrency = negSuffix;
    120 		posPrefixPatternForCurrency = posPrefix;
    121 		posSuffixPatternForCurrency = posSuffix;
    122 		patternType = type;
    123 	}
    124 #ifdef FMT_DEBUG
    125   void dump() const  {
    126     debugout( UnicodeString("AffixPatternsForCurrency( -=\"") +
    127               negPrefixPatternForCurrency + (UnicodeString)"\"/\"" +
    128               negSuffixPatternForCurrency + (UnicodeString)"\" +=\"" +
    129               posPrefixPatternForCurrency + (UnicodeString)"\"/\"" +
    130               posSuffixPatternForCurrency + (UnicodeString)"\" )");
    131   }
    132 #endif
    133 };
    134 
    135 /* affix for currency formatting when the currency sign in the pattern
    136  * equals to 3, such as the pattern contains 3 currency sign or
    137  * the formatter style is currency plural format style.
    138  */
    139 struct AffixesForCurrency : public UMemory {
    140 	// negative prefix
    141 	UnicodeString negPrefixForCurrency;
    142 	// negative suffix
    143 	UnicodeString negSuffixForCurrency;
    144 	// positive prefix
    145 	UnicodeString posPrefixForCurrency;
    146 	// positive suffix
    147 	UnicodeString posSuffixForCurrency;
    148 
    149 	int32_t formatWidth;
    150 
    151 	AffixesForCurrency(const UnicodeString& negPrefix,
    152 					   const UnicodeString& negSuffix,
    153 					   const UnicodeString& posPrefix,
    154 					   const UnicodeString& posSuffix) {
    155 		negPrefixForCurrency = negPrefix;
    156 		negSuffixForCurrency = negSuffix;
    157 		posPrefixForCurrency = posPrefix;
    158 		posSuffixForCurrency = posSuffix;
    159 	}
    160 #ifdef FMT_DEBUG
    161   void dump() const {
    162     debugout( UnicodeString("AffixesForCurrency( -=\"") +
    163               negPrefixForCurrency + (UnicodeString)"\"/\"" +
    164               negSuffixForCurrency + (UnicodeString)"\" +=\"" +
    165               posPrefixForCurrency + (UnicodeString)"\"/\"" +
    166               posSuffixForCurrency + (UnicodeString)"\" )");
    167   }
    168 #endif
    169 };
    170 
    171 U_CDECL_BEGIN
    172 
    173 /**
    174  * @internal ICU 4.2
    175  */
    176 static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2);
    177 
    178 
    179 static UBool
    180 U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) {
    181     const AffixPatternsForCurrency* affix_1 =
    182         (AffixPatternsForCurrency*)val1.pointer;
    183     const AffixPatternsForCurrency* affix_2 =
    184         (AffixPatternsForCurrency*)val2.pointer;
    185     return affix_1->negPrefixPatternForCurrency ==
    186            affix_2->negPrefixPatternForCurrency &&
    187            affix_1->negSuffixPatternForCurrency ==
    188            affix_2->negSuffixPatternForCurrency &&
    189            affix_1->posPrefixPatternForCurrency ==
    190            affix_2->posPrefixPatternForCurrency &&
    191            affix_1->posSuffixPatternForCurrency ==
    192            affix_2->posSuffixPatternForCurrency &&
    193            affix_1->patternType == affix_2->patternType;
    194 }
    195 
    196 U_CDECL_END
    197 
    198 
    199 
    200 
    201 // *****************************************************************************
    202 // class DecimalFormat
    203 // *****************************************************************************
    204 
    205 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
    206 
    207 // Constants for characters used in programmatic (unlocalized) patterns.
    208 #define kPatternZeroDigit            ((UChar)0x0030) /*'0'*/
    209 #define kPatternSignificantDigit     ((UChar)0x0040) /*'@'*/
    210 #define kPatternGroupingSeparator    ((UChar)0x002C) /*','*/
    211 #define kPatternDecimalSeparator     ((UChar)0x002E) /*'.'*/
    212 #define kPatternPerMill              ((UChar)0x2030)
    213 #define kPatternPercent              ((UChar)0x0025) /*'%'*/
    214 #define kPatternDigit                ((UChar)0x0023) /*'#'*/
    215 #define kPatternSeparator            ((UChar)0x003B) /*';'*/
    216 #define kPatternExponent             ((UChar)0x0045) /*'E'*/
    217 #define kPatternPlus                 ((UChar)0x002B) /*'+'*/
    218 #define kPatternMinus                ((UChar)0x002D) /*'-'*/
    219 #define kPatternPadEscape            ((UChar)0x002A) /*'*'*/
    220 #define kQuote                       ((UChar)0x0027) /*'\''*/
    221 /**
    222  * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
    223  * is used in patterns and substitued with either the currency symbol,
    224  * or if it is doubled, with the international currency symbol.  If the
    225  * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
    226  * replaced with the monetary decimal separator.
    227  */
    228 #define kCurrencySign                ((UChar)0x00A4)
    229 #define kDefaultPad                  ((UChar)0x0020) /* */
    230 
    231 const int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
    232 const int32_t DecimalFormat::kDoubleFractionDigits = 340;
    233 
    234 const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
    235 
    236 /**
    237  * These are the tags we expect to see in normal resource bundle files associated
    238  * with a locale.
    239  */
    240 const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used
    241 static const char fgNumberElements[]="NumberElements";
    242 static const char fgLatn[]="latn";
    243 static const char fgPatterns[]="patterns";
    244 static const char fgDecimalFormat[]="decimalFormat";
    245 static const char fgCurrencyFormat[]="currencyFormat";
    246 
    247 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
    248 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
    249 
    250 //------------------------------------------------------------------------------
    251 // Constructs a DecimalFormat instance in the default locale.
    252 
    253 DecimalFormat::DecimalFormat(UErrorCode& status) {
    254     init();
    255     UParseError parseError;
    256     construct(status, parseError);
    257 }
    258 
    259 //------------------------------------------------------------------------------
    260 // Constructs a DecimalFormat instance with the specified number format
    261 // pattern in the default locale.
    262 
    263 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
    264                              UErrorCode& status) {
    265     init();
    266     UParseError parseError;
    267     construct(status, parseError, &pattern);
    268 }
    269 
    270 //------------------------------------------------------------------------------
    271 // Constructs a DecimalFormat instance with the specified number format
    272 // pattern and the number format symbols in the default locale.  The
    273 // created instance owns the symbols.
    274 
    275 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
    276                              DecimalFormatSymbols* symbolsToAdopt,
    277                              UErrorCode& status) {
    278     init();
    279     UParseError parseError;
    280     if (symbolsToAdopt == NULL)
    281         status = U_ILLEGAL_ARGUMENT_ERROR;
    282     construct(status, parseError, &pattern, symbolsToAdopt);
    283 }
    284 
    285 DecimalFormat::DecimalFormat(  const UnicodeString& pattern,
    286                     DecimalFormatSymbols* symbolsToAdopt,
    287                     UParseError& parseErr,
    288                     UErrorCode& status) {
    289     init();
    290     if (symbolsToAdopt == NULL)
    291         status = U_ILLEGAL_ARGUMENT_ERROR;
    292     construct(status,parseErr, &pattern, symbolsToAdopt);
    293 }
    294 
    295 //------------------------------------------------------------------------------
    296 // Constructs a DecimalFormat instance with the specified number format
    297 // pattern and the number format symbols in the default locale.  The
    298 // created instance owns the clone of the symbols.
    299 
    300 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
    301                              const DecimalFormatSymbols& symbols,
    302                              UErrorCode& status) {
    303     init();
    304     UParseError parseError;
    305     construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
    306 }
    307 
    308 //------------------------------------------------------------------------------
    309 // Constructs a DecimalFormat instance with the specified number format
    310 // pattern, the number format symbols, and the number format style.
    311 // The created instance owns the clone of the symbols.
    312 
    313 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
    314                              DecimalFormatSymbols* symbolsToAdopt,
    315                              UNumberFormatStyle style,
    316                              UErrorCode& status) {
    317     init();
    318     fStyle = style;
    319     UParseError parseError;
    320     construct(status, parseError, &pattern, symbolsToAdopt);
    321 }
    322 
    323 //-----------------------------------------------------------------------------
    324 // Common DecimalFormat initialization.
    325 //    Put all fields of an uninitialized object into a known state.
    326 //    Common code, shared by all constructors.
    327 //    Can not fail. Leave the object in good enough shape that the destructor
    328 //    or assignment operator can run successfully.
    329 void
    330 DecimalFormat::init() {
    331     fBoolFlags.clear();
    332     fStyle = UNUM_DECIMAL;
    333     fAffixPatternsForCurrency = NULL;
    334     fCurrencyPluralInfo = NULL;
    335 #if UCONFIG_HAVE_PARSEALLINPUT
    336     fParseAllInput = UNUM_MAYBE;
    337 #endif
    338 
    339     fStaticSets = NULL;
    340     fImpl = NULL;
    341 }
    342 
    343 //------------------------------------------------------------------------------
    344 // Constructs a DecimalFormat instance with the specified number format
    345 // pattern and the number format symbols in the desired locale.  The
    346 // created instance owns the symbols.
    347 
    348 void
    349 DecimalFormat::construct(UErrorCode&            status,
    350                          UParseError&           parseErr,
    351                          const UnicodeString*   pattern,
    352                          DecimalFormatSymbols*  symbolsToAdopt)
    353 {
    354     LocalPointer<DecimalFormatSymbols> adoptedSymbols(symbolsToAdopt);
    355     if (U_FAILURE(status))
    356         return;
    357 
    358     if (adoptedSymbols.isNull())
    359     {
    360         adoptedSymbols.adoptInstead(
    361                 new DecimalFormatSymbols(Locale::getDefault(), status));
    362         if (adoptedSymbols.isNull() && U_SUCCESS(status)) {
    363             status = U_MEMORY_ALLOCATION_ERROR;
    364         }
    365         if (U_FAILURE(status)) {
    366             return;
    367         }
    368     }
    369     fStaticSets = DecimalFormatStaticSets::getStaticSets(status);
    370     if (U_FAILURE(status)) {
    371         return;
    372     }
    373 
    374     UnicodeString str;
    375     // Uses the default locale's number format pattern if there isn't
    376     // one specified.
    377     if (pattern == NULL)
    378     {
    379         UErrorCode nsStatus = U_ZERO_ERROR;
    380         LocalPointer<NumberingSystem> ns(
    381                 NumberingSystem::createInstance(nsStatus));
    382         if (U_FAILURE(nsStatus)) {
    383             status = nsStatus;
    384             return;
    385         }
    386 
    387         int32_t len = 0;
    388         UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &status);
    389 
    390         UResourceBundle *resource = ures_getByKeyWithFallback(top, fgNumberElements, NULL, &status);
    391         resource = ures_getByKeyWithFallback(resource, ns->getName(), resource, &status);
    392         resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
    393         const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
    394         if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(fgLatn,ns->getName())) {
    395             status = U_ZERO_ERROR;
    396             resource = ures_getByKeyWithFallback(top, fgNumberElements, resource, &status);
    397             resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status);
    398             resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status);
    399             resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status);
    400         }
    401         str.setTo(TRUE, resStr, len);
    402         pattern = &str;
    403         ures_close(resource);
    404         ures_close(top);
    405     }
    406 
    407     fImpl = new DecimalFormatImpl(this, *pattern, adoptedSymbols.getAlias(), parseErr, status);
    408     if (fImpl) {
    409         adoptedSymbols.orphan();
    410     } else if (U_SUCCESS(status)) {
    411         status = U_MEMORY_ALLOCATION_ERROR;
    412     }
    413     if (U_FAILURE(status)) {
    414         return;
    415     }
    416 
    417     if (U_FAILURE(status))
    418     {
    419         return;
    420     }
    421 
    422     const UnicodeString* patternUsed;
    423     UnicodeString currencyPluralPatternForOther;
    424     // apply pattern
    425     if (fStyle == UNUM_CURRENCY_PLURAL) {
    426         fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status);
    427         if (U_FAILURE(status)) {
    428             return;
    429         }
    430 
    431         // the pattern used in format is not fixed until formatting,
    432         // in which, the number is known and
    433         // will be used to pick the right pattern based on plural count.
    434         // Here, set the pattern as the pattern of plural count == "other".
    435         // For most locale, the patterns are probably the same for all
    436         // plural count. If not, the right pattern need to be re-applied
    437         // during format.
    438         fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5), currencyPluralPatternForOther);
    439         // TODO(refactor): Revisit, we are setting the pattern twice.
    440         fImpl->applyPatternFavorCurrencyPrecision(
    441                 currencyPluralPatternForOther, status);
    442         patternUsed = &currencyPluralPatternForOther;
    443 
    444     } else {
    445         patternUsed = pattern;
    446     }
    447 
    448     if (patternUsed->indexOf(kCurrencySign) != -1) {
    449         // initialize for currency, not only for plural format,
    450         // but also for mix parsing
    451         handleCurrencySignInPattern(status);
    452     }
    453 }
    454 
    455 void
    456 DecimalFormat::handleCurrencySignInPattern(UErrorCode& status) {
    457     // initialize for currency, not only for plural format,
    458     // but also for mix parsing
    459     if (U_FAILURE(status)) {
    460         return;
    461     }
    462     if (fCurrencyPluralInfo == NULL) {
    463        fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status);
    464        if (U_FAILURE(status)) {
    465            return;
    466        }
    467     }
    468     // need it for mix parsing
    469     if (fAffixPatternsForCurrency == NULL) {
    470         setupCurrencyAffixPatterns(status);
    471     }
    472 }
    473 
    474 static void
    475 applyPatternWithNoSideEffects(
    476         const UnicodeString& pattern,
    477         UParseError& parseError,
    478         UnicodeString &negPrefix,
    479         UnicodeString &negSuffix,
    480         UnicodeString &posPrefix,
    481         UnicodeString &posSuffix,
    482         UErrorCode& status) {
    483         if (U_FAILURE(status))
    484     {
    485         return;
    486     }
    487     DecimalFormatPatternParser patternParser;
    488     DecimalFormatPattern out;
    489     patternParser.applyPatternWithoutExpandAffix(
    490         pattern,
    491         out,
    492         parseError,
    493         status);
    494     if (U_FAILURE(status)) {
    495       return;
    496     }
    497     negPrefix = out.fNegPrefixPattern;
    498     negSuffix = out.fNegSuffixPattern;
    499     posPrefix = out.fPosPrefixPattern;
    500     posSuffix = out.fPosSuffixPattern;
    501 }
    502 
    503 void
    504 DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) {
    505     if (U_FAILURE(status)) {
    506         return;
    507     }
    508     UParseError parseErr;
    509     fAffixPatternsForCurrency = initHashForAffixPattern(status);
    510     if (U_FAILURE(status)) {
    511         return;
    512     }
    513 
    514     NumberingSystem *ns = NumberingSystem::createInstance(fImpl->fSymbols->getLocale(),status);
    515     if (U_FAILURE(status)) {
    516         return;
    517     }
    518 
    519     // Save the default currency patterns of this locale.
    520     // Here, chose onlyApplyPatternWithoutExpandAffix without
    521     // expanding the affix patterns into affixes.
    522     UnicodeString currencyPattern;
    523     UErrorCode error = U_ZERO_ERROR;
    524 
    525     UResourceBundle *resource = ures_open(NULL, fImpl->fSymbols->getLocale().getName(), &error);
    526     UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberElements, NULL, &error);
    527     resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &error);
    528     resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
    529     int32_t patLen = 0;
    530     const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,  &patLen, &error);
    531     if ( error == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),fgLatn)) {
    532         error = U_ZERO_ERROR;
    533         resource = ures_getByKeyWithFallback(numElements, fgLatn, resource, &error);
    534         resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error);
    535         patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat,  &patLen, &error);
    536     }
    537     ures_close(numElements);
    538     ures_close(resource);
    539     delete ns;
    540 
    541     if (U_SUCCESS(error)) {
    542         UnicodeString negPrefix;
    543         UnicodeString negSuffix;
    544         UnicodeString posPrefix;
    545         UnicodeString posSuffix;
    546         applyPatternWithNoSideEffects(UnicodeString(patResStr, patLen),
    547                                        parseErr,
    548                 negPrefix, negSuffix, posPrefix, posSuffix,  status);
    549         AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
    550                                                     negPrefix,
    551                                                     negSuffix,
    552                                                     posPrefix,
    553                                                     posSuffix,
    554                                                     UCURR_SYMBOL_NAME);
    555         fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, status);
    556     }
    557 
    558     // save the unique currency plural patterns of this locale.
    559     Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern;
    560     const UHashElement* element = NULL;
    561     int32_t pos = UHASH_FIRST;
    562     Hashtable pluralPatternSet;
    563     while ((element = pluralPtn->nextElement(pos)) != NULL) {
    564         const UHashTok valueTok = element->value;
    565         const UnicodeString* value = (UnicodeString*)valueTok.pointer;
    566         const UHashTok keyTok = element->key;
    567         const UnicodeString* key = (UnicodeString*)keyTok.pointer;
    568         if (pluralPatternSet.geti(*value) != 1) {
    569             UnicodeString negPrefix;
    570             UnicodeString negSuffix;
    571             UnicodeString posPrefix;
    572             UnicodeString posSuffix;
    573             pluralPatternSet.puti(*value, 1, status);
    574             applyPatternWithNoSideEffects(
    575                     *value, parseErr,
    576                     negPrefix, negSuffix, posPrefix, posSuffix, status);
    577             AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
    578                                                     negPrefix,
    579                                                     negSuffix,
    580                                                     posPrefix,
    581                                                     posSuffix,
    582                                                     UCURR_LONG_NAME);
    583             fAffixPatternsForCurrency->put(*key, affixPtn, status);
    584         }
    585     }
    586 }
    587 
    588 
    589 //------------------------------------------------------------------------------
    590 
    591 DecimalFormat::~DecimalFormat()
    592 {
    593     deleteHashForAffixPattern();
    594     delete fCurrencyPluralInfo;
    595     delete fImpl;
    596 }
    597 
    598 //------------------------------------------------------------------------------
    599 // copy constructor
    600 
    601 DecimalFormat::DecimalFormat(const DecimalFormat &source) :
    602     NumberFormat(source) {
    603     init();
    604     *this = source;
    605 }
    606 
    607 //------------------------------------------------------------------------------
    608 // assignment operator
    609 
    610 template <class T>
    611 static void _clone_ptr(T** pdest, const T* source) {
    612     delete *pdest;
    613     if (source == NULL) {
    614         *pdest = NULL;
    615     } else {
    616         *pdest = static_cast<T*>(source->clone());
    617     }
    618 }
    619 
    620 DecimalFormat&
    621 DecimalFormat::operator=(const DecimalFormat& rhs)
    622 {
    623     if(this != &rhs) {
    624         UErrorCode status = U_ZERO_ERROR;
    625         NumberFormat::operator=(rhs);
    626         if (fImpl == NULL) {
    627             fImpl = new DecimalFormatImpl(this, *rhs.fImpl, status);
    628         } else {
    629             fImpl->assign(*rhs.fImpl, status);
    630         }
    631         fStaticSets     = DecimalFormatStaticSets::getStaticSets(status);
    632         fStyle = rhs.fStyle;
    633         _clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo);
    634         deleteHashForAffixPattern();
    635         if (rhs.fAffixPatternsForCurrency) {
    636             UErrorCode status = U_ZERO_ERROR;
    637             fAffixPatternsForCurrency = initHashForAffixPattern(status);
    638             copyHashForAffixPattern(rhs.fAffixPatternsForCurrency,
    639                                     fAffixPatternsForCurrency, status);
    640         }
    641     }
    642 
    643     return *this;
    644 }
    645 
    646 //------------------------------------------------------------------------------
    647 
    648 UBool
    649 DecimalFormat::operator==(const Format& that) const
    650 {
    651     if (this == &that)
    652         return TRUE;
    653 
    654     // NumberFormat::operator== guarantees this cast is safe
    655     const DecimalFormat* other = (DecimalFormat*)&that;
    656 
    657     return (
    658         NumberFormat::operator==(that) &&
    659         fBoolFlags.getAll() == other->fBoolFlags.getAll() &&
    660         *fImpl == *other->fImpl);
    661 
    662 }
    663 
    664 //------------------------------------------------------------------------------
    665 
    666 Format*
    667 DecimalFormat::clone() const
    668 {
    669     return new DecimalFormat(*this);
    670 }
    671 
    672 
    673 FixedDecimal
    674 DecimalFormat::getFixedDecimal(double number, UErrorCode &status) const {
    675     VisibleDigitsWithExponent digits;
    676     initVisibleDigitsWithExponent(number, digits, status);
    677     if (U_FAILURE(status)) {
    678         return FixedDecimal();
    679     }
    680     return FixedDecimal(digits.getMantissa());
    681 }
    682 
    683 VisibleDigitsWithExponent &
    684 DecimalFormat::initVisibleDigitsWithExponent(
    685         double number,
    686         VisibleDigitsWithExponent &digits,
    687         UErrorCode &status) const {
    688     return fImpl->initVisibleDigitsWithExponent(number, digits, status);
    689 }
    690 
    691 FixedDecimal
    692 DecimalFormat::getFixedDecimal(const Formattable &number, UErrorCode &status) const {
    693     VisibleDigitsWithExponent digits;
    694     initVisibleDigitsWithExponent(number, digits, status);
    695     if (U_FAILURE(status)) {
    696         return FixedDecimal();
    697     }
    698     return FixedDecimal(digits.getMantissa());
    699 }
    700 
    701 VisibleDigitsWithExponent &
    702 DecimalFormat::initVisibleDigitsWithExponent(
    703         const Formattable &number,
    704         VisibleDigitsWithExponent &digits,
    705         UErrorCode &status) const {
    706     if (U_FAILURE(status)) {
    707         return digits;
    708     }
    709     if (!number.isNumeric()) {
    710         status = U_ILLEGAL_ARGUMENT_ERROR;
    711         return digits;
    712     }
    713 
    714     DigitList *dl = number.getDigitList();
    715     if (dl != NULL) {
    716         DigitList dlCopy(*dl);
    717         return fImpl->initVisibleDigitsWithExponent(
    718                 dlCopy, digits, status);
    719     }
    720 
    721     Formattable::Type type = number.getType();
    722     if (type == Formattable::kDouble || type == Formattable::kLong) {
    723         return fImpl->initVisibleDigitsWithExponent(
    724                 number.getDouble(status), digits, status);
    725     }
    726     return fImpl->initVisibleDigitsWithExponent(
    727             number.getInt64(), digits, status);
    728 }
    729 
    730 
    731 // Create a fixed decimal from a DigitList.
    732 //    The digit list may be modified.
    733 //    Internal function only.
    734 FixedDecimal
    735 DecimalFormat::getFixedDecimal(DigitList &number, UErrorCode &status) const {
    736     VisibleDigitsWithExponent digits;
    737     initVisibleDigitsWithExponent(number, digits, status);
    738     if (U_FAILURE(status)) {
    739         return FixedDecimal();
    740     }
    741     return FixedDecimal(digits.getMantissa());
    742 }
    743 
    744 VisibleDigitsWithExponent &
    745 DecimalFormat::initVisibleDigitsWithExponent(
    746         DigitList &number,
    747         VisibleDigitsWithExponent &digits,
    748         UErrorCode &status) const {
    749     return fImpl->initVisibleDigitsWithExponent(
    750             number, digits, status);
    751 }
    752 
    753 
    754 //------------------------------------------------------------------------------
    755 
    756 UnicodeString&
    757 DecimalFormat::format(int32_t number,
    758                       UnicodeString& appendTo,
    759                       FieldPosition& fieldPosition) const
    760 {
    761     UErrorCode status = U_ZERO_ERROR;
    762     return fImpl->format(number, appendTo, fieldPosition, status);
    763 }
    764 
    765 UnicodeString&
    766 DecimalFormat::format(int32_t number,
    767                       UnicodeString& appendTo,
    768                       FieldPosition& fieldPosition,
    769                       UErrorCode& status) const
    770 {
    771     return fImpl->format(number, appendTo, fieldPosition, status);
    772 }
    773 
    774 UnicodeString&
    775 DecimalFormat::format(int32_t number,
    776                       UnicodeString& appendTo,
    777                       FieldPositionIterator* posIter,
    778                       UErrorCode& status) const
    779 {
    780     return fImpl->format(number, appendTo, posIter, status);
    781 }
    782 
    783 
    784 //------------------------------------------------------------------------------
    785 
    786 UnicodeString&
    787 DecimalFormat::format(int64_t number,
    788                       UnicodeString& appendTo,
    789                       FieldPosition& fieldPosition) const
    790 {
    791     UErrorCode status = U_ZERO_ERROR; /* ignored */
    792     return fImpl->format(number, appendTo, fieldPosition, status);
    793 }
    794 
    795 UnicodeString&
    796 DecimalFormat::format(int64_t number,
    797                       UnicodeString& appendTo,
    798                       FieldPosition& fieldPosition,
    799                       UErrorCode& status) const
    800 {
    801     return fImpl->format(number, appendTo, fieldPosition, status);
    802 }
    803 
    804 UnicodeString&
    805 DecimalFormat::format(int64_t number,
    806                       UnicodeString& appendTo,
    807                       FieldPositionIterator* posIter,
    808                       UErrorCode& status) const
    809 {
    810     return fImpl->format(number, appendTo, posIter, status);
    811 }
    812 
    813 //------------------------------------------------------------------------------
    814 
    815 UnicodeString&
    816 DecimalFormat::format(  double number,
    817                         UnicodeString& appendTo,
    818                         FieldPosition& fieldPosition) const
    819 {
    820     UErrorCode status = U_ZERO_ERROR; /* ignored */
    821     return fImpl->format(number, appendTo, fieldPosition, status);
    822 }
    823 
    824 UnicodeString&
    825 DecimalFormat::format(  double number,
    826                         UnicodeString& appendTo,
    827                         FieldPosition& fieldPosition,
    828                         UErrorCode& status) const
    829 {
    830     return fImpl->format(number, appendTo, fieldPosition, status);
    831 }
    832 
    833 UnicodeString&
    834 DecimalFormat::format(  double number,
    835                         UnicodeString& appendTo,
    836                         FieldPositionIterator* posIter,
    837                         UErrorCode& status) const
    838 {
    839     return fImpl->format(number, appendTo, posIter, status);
    840 }
    841 
    842 //------------------------------------------------------------------------------
    843 
    844 
    845 UnicodeString&
    846 DecimalFormat::format(StringPiece number,
    847                       UnicodeString &toAppendTo,
    848                       FieldPositionIterator *posIter,
    849                       UErrorCode &status) const
    850 {
    851   return fImpl->format(number, toAppendTo, posIter, status);
    852 }
    853 
    854 
    855 UnicodeString&
    856 DecimalFormat::format(const DigitList &number,
    857                       UnicodeString &appendTo,
    858                       FieldPositionIterator *posIter,
    859                       UErrorCode &status) const {
    860     return fImpl->format(number, appendTo, posIter, status);
    861 }
    862 
    863 
    864 UnicodeString&
    865 DecimalFormat::format(const DigitList &number,
    866                      UnicodeString& appendTo,
    867                      FieldPosition& pos,
    868                      UErrorCode &status) const {
    869     return fImpl->format(number, appendTo, pos, status);
    870 }
    871 
    872 UnicodeString&
    873 DecimalFormat::format(const VisibleDigitsWithExponent &number,
    874                       UnicodeString &appendTo,
    875                       FieldPositionIterator *posIter,
    876                       UErrorCode &status) const {
    877     return fImpl->format(number, appendTo, posIter, status);
    878 }
    879 
    880 
    881 UnicodeString&
    882 DecimalFormat::format(const VisibleDigitsWithExponent &number,
    883                      UnicodeString& appendTo,
    884                      FieldPosition& pos,
    885                      UErrorCode &status) const {
    886     return fImpl->format(number, appendTo, pos, status);
    887 }
    888 
    889 DigitList&
    890 DecimalFormat::_round(const DigitList& number, DigitList& adjustedNum, UBool& isNegative, UErrorCode& status) const {
    891     adjustedNum = number;
    892     fImpl->round(adjustedNum, status);
    893     isNegative = !adjustedNum.isPositive();
    894     return adjustedNum;
    895 }
    896 
    897 void
    898 DecimalFormat::parse(const UnicodeString& text,
    899                      Formattable& result,
    900                      ParsePosition& parsePosition) const {
    901     parse(text, result, parsePosition, NULL);
    902 }
    903 
    904 CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text,
    905                                              ParsePosition& pos) const {
    906     Formattable parseResult;
    907     int32_t start = pos.getIndex();
    908     UChar curbuf[4] = {};
    909     parse(text, parseResult, pos, curbuf);
    910     if (pos.getIndex() != start) {
    911         UErrorCode ec = U_ZERO_ERROR;
    912         LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curbuf, ec), ec);
    913         if (U_FAILURE(ec)) {
    914             pos.setIndex(start); // indicate failure
    915         } else {
    916             return currAmt.orphan();
    917         }
    918     }
    919     return NULL;
    920 }
    921 
    922 /**
    923  * Parses the given text as a number, optionally providing a currency amount.
    924  * @param text the string to parse
    925  * @param result output parameter for the numeric result.
    926  * @param parsePosition input-output position; on input, the
    927  * position within text to match; must have 0 <= pos.getIndex() <
    928  * text.length(); on output, the position after the last matched
    929  * character. If the parse fails, the position in unchanged upon
    930  * output.
    931  * @param currency if non-NULL, it should point to a 4-UChar buffer.
    932  * In this case the text is parsed as a currency format, and the
    933  * ISO 4217 code for the parsed currency is put into the buffer.
    934  * Otherwise the text is parsed as a non-currency format.
    935  */
    936 void DecimalFormat::parse(const UnicodeString& text,
    937                           Formattable& result,
    938                           ParsePosition& parsePosition,
    939                           UChar* currency) const {
    940     int32_t startIdx, backup;
    941     int32_t i = startIdx = backup = parsePosition.getIndex();
    942 
    943     // clear any old contents in the result.  In particular, clears any DigitList
    944     //   that it may be holding.
    945     result.setLong(0);
    946     if (currency != NULL) {
    947         for (int32_t ci=0; ci<4; ci++) {
    948             currency[ci] = 0;
    949         }
    950     }
    951 
    952     // Handle NaN as a special case:
    953     int32_t formatWidth = fImpl->getOldFormatWidth();
    954 
    955     // Skip padding characters, if around prefix
    956     if (formatWidth > 0 && (
    957             fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix ||
    958             fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix)) {
    959         i = skipPadding(text, i);
    960     }
    961 
    962     if (isLenient()) {
    963         // skip any leading whitespace
    964         i = backup = skipUWhiteSpace(text, i);
    965     }
    966 
    967     // If the text is composed of the representation of NaN, returns NaN.length
    968     const UnicodeString *nan = &fImpl->getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
    969     int32_t nanLen = (text.compare(i, nan->length(), *nan)
    970                       ? 0 : nan->length());
    971     if (nanLen) {
    972         i += nanLen;
    973         if (formatWidth > 0 && (fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix || fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix)) {
    974             i = skipPadding(text, i);
    975         }
    976         parsePosition.setIndex(i);
    977         result.setDouble(uprv_getNaN());
    978         return;
    979     }
    980 
    981     // NaN parse failed; start over
    982     i = backup;
    983     parsePosition.setIndex(i);
    984 
    985     // status is used to record whether a number is infinite.
    986     UBool status[fgStatusLength];
    987 
    988     DigitList *digits = result.getInternalDigitList(); // get one from the stack buffer
    989     if (digits == NULL) {
    990         return;    // no way to report error from here.
    991     }
    992 
    993     if (fImpl->fMonetary) {
    994         if (!parseForCurrency(text, parsePosition, *digits,
    995                               status, currency)) {
    996           return;
    997         }
    998     } else {
    999         if (!subparse(text,
   1000                       &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(),
   1001                       &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(),
   1002                       &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(),
   1003                       &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(),
   1004                       FALSE, UCURR_SYMBOL_NAME,
   1005                       parsePosition, *digits, status, currency)) {
   1006             debug("!subparse(...) - rewind");
   1007             parsePosition.setIndex(startIdx);
   1008             return;
   1009         }
   1010     }
   1011 
   1012     // Handle infinity
   1013     if (status[fgStatusInfinite]) {
   1014         double inf = uprv_getInfinity();
   1015         result.setDouble(digits->isPositive() ? inf : -inf);
   1016         // TODO:  set the dl to infinity, and let it fall into the code below.
   1017     }
   1018 
   1019     else {
   1020 
   1021         if (!fImpl->fMultiplier.isZero()) {
   1022             UErrorCode ec = U_ZERO_ERROR;
   1023             digits->div(fImpl->fMultiplier, ec);
   1024         }
   1025 
   1026         if (fImpl->fScale != 0) {
   1027             DigitList ten;
   1028             ten.set((int32_t)10);
   1029             if (fImpl->fScale > 0) {
   1030                 for (int32_t i = fImpl->fScale; i > 0; i--) {
   1031                     UErrorCode ec = U_ZERO_ERROR;
   1032                     digits->div(ten,ec);
   1033                 }
   1034             } else {
   1035                 for (int32_t i = fImpl->fScale; i < 0; i++) {
   1036                     UErrorCode ec = U_ZERO_ERROR;
   1037                     digits->mult(ten,ec);
   1038                 }
   1039             }
   1040         }
   1041 
   1042         // Negative zero special case:
   1043         //    if parsing integerOnly, change to +0, which goes into an int32 in a Formattable.
   1044         //    if not parsing integerOnly, leave as -0, which a double can represent.
   1045         if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) {
   1046             digits->setPositive(TRUE);
   1047         }
   1048         result.adoptDigitList(digits);
   1049     }
   1050 }
   1051 
   1052 
   1053 
   1054 UBool
   1055 DecimalFormat::parseForCurrency(const UnicodeString& text,
   1056                                 ParsePosition& parsePosition,
   1057                                 DigitList& digits,
   1058                                 UBool* status,
   1059                                 UChar* currency) const {
   1060     UnicodeString positivePrefix;
   1061     UnicodeString positiveSuffix;
   1062     UnicodeString negativePrefix;
   1063     UnicodeString negativeSuffix;
   1064     fImpl->fPositivePrefixPattern.toString(positivePrefix);
   1065     fImpl->fPositiveSuffixPattern.toString(positiveSuffix);
   1066     fImpl->fNegativePrefixPattern.toString(negativePrefix);
   1067     fImpl->fNegativeSuffixPattern.toString(negativeSuffix);
   1068 
   1069     int origPos = parsePosition.getIndex();
   1070     int maxPosIndex = origPos;
   1071     int maxErrorPos = -1;
   1072     // First, parse against current pattern.
   1073     // Since current pattern could be set by applyPattern(),
   1074     // it could be an arbitrary pattern, and it may not be the one
   1075     // defined in current locale.
   1076     UBool tmpStatus[fgStatusLength];
   1077     ParsePosition tmpPos(origPos);
   1078     DigitList tmpDigitList;
   1079     UBool found;
   1080     if (fStyle == UNUM_CURRENCY_PLURAL) {
   1081         found = subparse(text,
   1082                          &negativePrefix, &negativeSuffix,
   1083                          &positivePrefix, &positiveSuffix,
   1084                          TRUE, UCURR_LONG_NAME,
   1085                          tmpPos, tmpDigitList, tmpStatus, currency);
   1086     } else {
   1087         found = subparse(text,
   1088                          &negativePrefix, &negativeSuffix,
   1089                          &positivePrefix, &positiveSuffix,
   1090                          TRUE, UCURR_SYMBOL_NAME,
   1091                          tmpPos, tmpDigitList, tmpStatus, currency);
   1092     }
   1093     if (found) {
   1094         if (tmpPos.getIndex() > maxPosIndex) {
   1095             maxPosIndex = tmpPos.getIndex();
   1096             for (int32_t i = 0; i < fgStatusLength; ++i) {
   1097                 status[i] = tmpStatus[i];
   1098             }
   1099             digits = tmpDigitList;
   1100         }
   1101     } else {
   1102         maxErrorPos = tmpPos.getErrorIndex();
   1103     }
   1104     // Then, parse against affix patterns.
   1105     // Those are currency patterns and currency plural patterns.
   1106     int32_t pos = UHASH_FIRST;
   1107     const UHashElement* element = NULL;
   1108     while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
   1109         const UHashTok valueTok = element->value;
   1110         const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)valueTok.pointer;
   1111         UBool tmpStatus[fgStatusLength];
   1112         ParsePosition tmpPos(origPos);
   1113         DigitList tmpDigitList;
   1114 
   1115 #ifdef FMT_DEBUG
   1116         debug("trying affix for currency..");
   1117         affixPtn->dump();
   1118 #endif
   1119 
   1120         UBool result = subparse(text,
   1121                                 &affixPtn->negPrefixPatternForCurrency,
   1122                                 &affixPtn->negSuffixPatternForCurrency,
   1123                                 &affixPtn->posPrefixPatternForCurrency,
   1124                                 &affixPtn->posSuffixPatternForCurrency,
   1125                                 TRUE, affixPtn->patternType,
   1126                                 tmpPos, tmpDigitList, tmpStatus, currency);
   1127         if (result) {
   1128             found = true;
   1129             if (tmpPos.getIndex() > maxPosIndex) {
   1130                 maxPosIndex = tmpPos.getIndex();
   1131                 for (int32_t i = 0; i < fgStatusLength; ++i) {
   1132                     status[i] = tmpStatus[i];
   1133                 }
   1134                 digits = tmpDigitList;
   1135             }
   1136         } else {
   1137             maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
   1138                           tmpPos.getErrorIndex() : maxErrorPos;
   1139         }
   1140     }
   1141     // Finally, parse against simple affix to find the match.
   1142     // For example, in TestMonster suite,
   1143     // if the to-be-parsed text is "-\u00A40,00".
   1144     // complexAffixCompare will not find match,
   1145     // since there is no ISO code matches "\u00A4",
   1146     // and the parse stops at "\u00A4".
   1147     // We will just use simple affix comparison (look for exact match)
   1148     // to pass it.
   1149     //
   1150     // TODO: We should parse against simple affix first when
   1151     // output currency is not requested. After the complex currency
   1152     // parsing implementation was introduced, the default currency
   1153     // instance parsing slowed down because of the new code flow.
   1154     // I filed #10312 - Yoshito
   1155     UBool tmpStatus_2[fgStatusLength];
   1156     ParsePosition tmpPos_2(origPos);
   1157     DigitList tmpDigitList_2;
   1158 
   1159     // Disable complex currency parsing and try it again.
   1160     UBool result = subparse(text,
   1161                             &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(),
   1162                             &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(),
   1163                             &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(),
   1164                             &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(),
   1165                             FALSE /* disable complex currency parsing */, UCURR_SYMBOL_NAME,
   1166                             tmpPos_2, tmpDigitList_2, tmpStatus_2,
   1167                             currency);
   1168     if (result) {
   1169         if (tmpPos_2.getIndex() > maxPosIndex) {
   1170             maxPosIndex = tmpPos_2.getIndex();
   1171             for (int32_t i = 0; i < fgStatusLength; ++i) {
   1172                 status[i] = tmpStatus_2[i];
   1173             }
   1174             digits = tmpDigitList_2;
   1175         }
   1176         found = true;
   1177     } else {
   1178             maxErrorPos = (tmpPos_2.getErrorIndex() > maxErrorPos) ?
   1179                           tmpPos_2.getErrorIndex() : maxErrorPos;
   1180     }
   1181 
   1182     if (!found) {
   1183         //parsePosition.setIndex(origPos);
   1184         parsePosition.setErrorIndex(maxErrorPos);
   1185     } else {
   1186         parsePosition.setIndex(maxPosIndex);
   1187         parsePosition.setErrorIndex(-1);
   1188     }
   1189     return found;
   1190 }
   1191 
   1192 
   1193 /**
   1194  * Parse the given text into a number.  The text is parsed beginning at
   1195  * parsePosition, until an unparseable character is seen.
   1196  * @param text the string to parse.
   1197  * @param negPrefix negative prefix.
   1198  * @param negSuffix negative suffix.
   1199  * @param posPrefix positive prefix.
   1200  * @param posSuffix positive suffix.
   1201  * @param complexCurrencyParsing whether it is complex currency parsing or not.
   1202  * @param type the currency type to parse against, LONG_NAME only or not.
   1203  * @param parsePosition The position at which to being parsing.  Upon
   1204  * return, the first unparsed character.
   1205  * @param digits the DigitList to set to the parsed value.
   1206  * @param status output param containing boolean status flags indicating
   1207  * whether the value was infinite and whether it was positive.
   1208  * @param currency return value for parsed currency, for generic
   1209  * currency parsing mode, or NULL for normal parsing. In generic
   1210  * currency parsing mode, any currency is parsed, not just the
   1211  * currency that this formatter is set to.
   1212  */
   1213 UBool DecimalFormat::subparse(const UnicodeString& text,
   1214                               const UnicodeString* negPrefix,
   1215                               const UnicodeString* negSuffix,
   1216                               const UnicodeString* posPrefix,
   1217                               const UnicodeString* posSuffix,
   1218                               UBool complexCurrencyParsing,
   1219                               int8_t type,
   1220                               ParsePosition& parsePosition,
   1221                               DigitList& digits, UBool* status,
   1222                               UChar* currency) const
   1223 {
   1224     //  The parsing process builds up the number as char string, in the neutral format that
   1225     //  will be acceptable to the decNumber library, then at the end passes that string
   1226     //  off for conversion to a decNumber.
   1227     UErrorCode err = U_ZERO_ERROR;
   1228     CharString parsedNum;
   1229     digits.setToZero();
   1230 
   1231     int32_t position = parsePosition.getIndex();
   1232     int32_t oldStart = position;
   1233     int32_t textLength = text.length(); // One less pointer to follow
   1234     UBool strictParse = !isLenient();
   1235     UChar32 zero = fImpl->getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
   1236     const UnicodeString *groupingString = &fImpl->getConstSymbol(
   1237             !fImpl->fMonetary ?
   1238             DecimalFormatSymbols::kGroupingSeparatorSymbol : DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
   1239     UChar32 groupingChar = groupingString->char32At(0);
   1240     int32_t groupingStringLength = groupingString->length();
   1241     int32_t groupingCharLength   = U16_LENGTH(groupingChar);
   1242     UBool   groupingUsed = isGroupingUsed();
   1243 #ifdef FMT_DEBUG
   1244     UChar dbgbuf[300];
   1245     UnicodeString s(dbgbuf,0,300);;
   1246     s.append((UnicodeString)"PARSE \"").append(text.tempSubString(position)).append((UnicodeString)"\" " );
   1247 #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 ")); }
   1248     DBGAPPD(negPrefix);
   1249     DBGAPPD(negSuffix);
   1250     DBGAPPD(posPrefix);
   1251     DBGAPPD(posSuffix);
   1252     debugout(s);
   1253 #endif
   1254 
   1255     UBool fastParseOk = false; /* TRUE iff fast parse is OK */
   1256     // UBool fastParseHadDecimal = FALSE; /* true if fast parse saw a decimal point. */
   1257     if((fImpl->isParseFastpath()) && !fImpl->fMonetary &&
   1258        text.length()>0 &&
   1259        text.length()<32 &&
   1260        (posPrefix==NULL||posPrefix->isEmpty()) &&
   1261        (posSuffix==NULL||posSuffix->isEmpty()) &&
   1262        //            (negPrefix==NULL||negPrefix->isEmpty()) &&
   1263        //            (negSuffix==NULL||(negSuffix->isEmpty()) ) &&
   1264        TRUE) {  // optimized path
   1265       int j=position;
   1266       int l=text.length();
   1267       int digitCount=0;
   1268       UChar32 ch = text.char32At(j);
   1269       const UnicodeString *decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
   1270       UChar32 decimalChar = 0;
   1271       UBool intOnly = FALSE;
   1272       UChar32 lookForGroup = (groupingUsed&&intOnly&&strictParse)?groupingChar:0;
   1273 
   1274       int32_t decimalCount = decimalString->countChar32(0,3);
   1275       if(isParseIntegerOnly()) {
   1276         decimalChar = 0; // not allowed
   1277         intOnly = TRUE; // Don't look for decimals.
   1278       } else if(decimalCount==1) {
   1279         decimalChar = decimalString->char32At(0); // Look for this decimal
   1280       } else if(decimalCount==0) {
   1281         decimalChar=0; // NO decimal set
   1282       } else {
   1283         j=l+1;//Set counter to end of line, so that we break. Unknown decimal situation.
   1284       }
   1285 
   1286 #ifdef FMT_DEBUG
   1287       printf("Preparing to do fastpath parse: decimalChar=U+%04X, groupingChar=U+%04X, first ch=U+%04X intOnly=%c strictParse=%c\n",
   1288         decimalChar, groupingChar, ch,
   1289         (intOnly)?'y':'n',
   1290         (strictParse)?'y':'n');
   1291 #endif
   1292       if(ch==0x002D) { // '-'
   1293         j=l+1;//=break - negative number.
   1294 
   1295         /*
   1296           parsedNum.append('-',err);
   1297           j+=U16_LENGTH(ch);
   1298           if(j<l) ch = text.char32At(j);
   1299         */
   1300       } else {
   1301         parsedNum.append('+',err);
   1302       }
   1303       while(j<l) {
   1304         int32_t digit = ch - zero;
   1305         if(digit >=0 && digit <= 9) {
   1306           parsedNum.append((char)(digit + '0'), err);
   1307           if((digitCount>0) || digit!=0 || j==(l-1)) {
   1308             digitCount++;
   1309           }
   1310         } else if(ch == 0) { // break out
   1311           digitCount=-1;
   1312           break;
   1313         } else if(ch == decimalChar) {
   1314           parsedNum.append((char)('.'), err);
   1315           decimalChar=0; // no more decimals.
   1316           // fastParseHadDecimal=TRUE;
   1317         } else if(ch == lookForGroup) {
   1318           // ignore grouping char. No decimals, so it has to be an ignorable grouping sep
   1319         } else if(intOnly && (lookForGroup!=0) && !u_isdigit(ch)) {
   1320           // parsing integer only and can fall through
   1321         } else {
   1322           digitCount=-1; // fail - fall through to slow parse
   1323           break;
   1324         }
   1325         j+=U16_LENGTH(ch);
   1326         ch = text.char32At(j); // for next
   1327       }
   1328       if(
   1329          ((j==l)||intOnly) // end OR only parsing integer
   1330          && (digitCount>0)) { // and have at least one digit
   1331         fastParseOk=true; // Fast parse OK!
   1332 
   1333 #ifdef SKIP_OPT
   1334         debug("SKIP_OPT");
   1335         /* for testing, try it the slow way. also */
   1336         fastParseOk=false;
   1337         parsedNum.clear();
   1338 #else
   1339         parsePosition.setIndex(position=j);
   1340         status[fgStatusInfinite]=false;
   1341 #endif
   1342       } else {
   1343         // was not OK. reset, retry
   1344 #ifdef FMT_DEBUG
   1345         printf("Fall through: j=%d, l=%d, digitCount=%d\n", j, l, digitCount);
   1346 #endif
   1347         parsedNum.clear();
   1348       }
   1349     } else {
   1350 #ifdef FMT_DEBUG
   1351       printf("Could not fastpath parse. ");
   1352       printf("text.length()=%d ", text.length());
   1353       printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix);
   1354 
   1355       printf("\n");
   1356 #endif
   1357     }
   1358 
   1359   UnicodeString formatPattern;
   1360   toPattern(formatPattern);
   1361 
   1362   if(!fastParseOk
   1363 #if UCONFIG_HAVE_PARSEALLINPUT
   1364      && fParseAllInput!=UNUM_YES
   1365 #endif
   1366      )
   1367   {
   1368     int32_t formatWidth = fImpl->getOldFormatWidth();
   1369     // Match padding before prefix
   1370     if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
   1371         position = skipPadding(text, position);
   1372     }
   1373 
   1374     // Match positive and negative prefixes; prefer longest match.
   1375     int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, complexCurrencyParsing, type, currency);
   1376     int32_t negMatch = compareAffix(text, position, TRUE,  TRUE, negPrefix, complexCurrencyParsing, type, currency);
   1377     if (posMatch >= 0 && negMatch >= 0) {
   1378         if (posMatch > negMatch) {
   1379             negMatch = -1;
   1380         } else if (negMatch > posMatch) {
   1381             posMatch = -1;
   1382         }
   1383     }
   1384     if (posMatch >= 0) {
   1385         position += posMatch;
   1386         parsedNum.append('+', err);
   1387     } else if (negMatch >= 0) {
   1388         position += negMatch;
   1389         parsedNum.append('-', err);
   1390     } else if (strictParse){
   1391         parsePosition.setErrorIndex(position);
   1392         return FALSE;
   1393     } else {
   1394         // Temporary set positive. This might be changed after checking suffix
   1395         parsedNum.append('+', err);
   1396     }
   1397 
   1398     // Match padding before prefix
   1399     if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
   1400         position = skipPadding(text, position);
   1401     }
   1402 
   1403     if (! strictParse) {
   1404         position = skipUWhiteSpace(text, position);
   1405     }
   1406 
   1407     // process digits or Inf, find decimal position
   1408     const UnicodeString *inf = &fImpl->getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
   1409     int32_t infLen = (text.compare(position, inf->length(), *inf)
   1410         ? 0 : inf->length());
   1411     position += infLen; // infLen is non-zero when it does equal to infinity
   1412     status[fgStatusInfinite] = infLen != 0;
   1413 
   1414     if (infLen != 0) {
   1415         parsedNum.append("Infinity", err);
   1416     } else {
   1417         // We now have a string of digits, possibly with grouping symbols,
   1418         // and decimal points.  We want to process these into a DigitList.
   1419         // We don't want to put a bunch of leading zeros into the DigitList
   1420         // though, so we keep track of the location of the decimal point,
   1421         // put only significant digits into the DigitList, and adjust the
   1422         // exponent as needed.
   1423 
   1424 
   1425         UBool strictFail = FALSE; // did we exit with a strict parse failure?
   1426         int32_t lastGroup = -1; // after which digit index did we last see a grouping separator?
   1427         int32_t currGroup = -1; // for temporary storage the digit index of the current grouping separator
   1428         int32_t gs2 = fImpl->fEffGrouping.fGrouping2 == 0 ? fImpl->fEffGrouping.fGrouping : fImpl->fEffGrouping.fGrouping2;
   1429 
   1430         const UnicodeString *decimalString;
   1431         if (fImpl->fMonetary) {
   1432             decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
   1433         } else {
   1434             decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
   1435         }
   1436         UChar32 decimalChar = decimalString->char32At(0);
   1437         int32_t decimalStringLength = decimalString->length();
   1438         int32_t decimalCharLength   = U16_LENGTH(decimalChar);
   1439 
   1440         UBool sawDecimal = FALSE;
   1441         UChar32 sawDecimalChar = 0xFFFF;
   1442         UBool sawGrouping = FALSE;
   1443         UChar32 sawGroupingChar = 0xFFFF;
   1444         UBool sawDigit = FALSE;
   1445         int32_t backup = -1;
   1446         int32_t digit;
   1447 
   1448         // equivalent grouping and decimal support
   1449         const UnicodeSet *decimalSet = NULL;
   1450         const UnicodeSet *groupingSet = NULL;
   1451 
   1452         if (decimalCharLength == decimalStringLength) {
   1453             decimalSet = DecimalFormatStaticSets::getSimilarDecimals(decimalChar, strictParse);
   1454         }
   1455 
   1456         if (groupingCharLength == groupingStringLength) {
   1457             if (strictParse) {
   1458                 groupingSet = fStaticSets->fStrictDefaultGroupingSeparators;
   1459             } else {
   1460                 groupingSet = fStaticSets->fDefaultGroupingSeparators;
   1461             }
   1462         }
   1463 
   1464         // We need to test groupingChar and decimalChar separately from groupingSet and decimalSet, if the sets are even initialized.
   1465         // If sawDecimal is TRUE, only consider sawDecimalChar and NOT decimalSet
   1466         // If a character matches decimalSet, don't consider it to be a member of the groupingSet.
   1467 
   1468         // We have to track digitCount ourselves, because digits.fCount will
   1469         // pin when the maximum allowable digits is reached.
   1470         int32_t digitCount = 0;
   1471         int32_t integerDigitCount = 0;
   1472 
   1473         for (; position < textLength; )
   1474         {
   1475             UChar32 ch = text.char32At(position);
   1476 
   1477             /* We recognize all digit ranges, not only the Latin digit range
   1478              * '0'..'9'.  We do so by using the Character.digit() method,
   1479              * which converts a valid Unicode digit to the range 0..9.
   1480              *
   1481              * The character 'ch' may be a digit.  If so, place its value
   1482              * from 0 to 9 in 'digit'.  First try using the locale digit,
   1483              * which may or MAY NOT be a standard Unicode digit range.  If
   1484              * this fails, try using the standard Unicode digit ranges by
   1485              * calling Character.digit().  If this also fails, digit will
   1486              * have a value outside the range 0..9.
   1487              */
   1488             digit = ch - zero;
   1489             if (digit < 0 || digit > 9)
   1490             {
   1491                 digit = u_charDigitValue(ch);
   1492             }
   1493 
   1494             // As a last resort, look through the localized digits if the zero digit
   1495             // is not a "standard" Unicode digit.
   1496             if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) {
   1497                 digit = 0;
   1498                 if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) {
   1499                     break;
   1500                 }
   1501                 for (digit = 1 ; digit < 10 ; digit++ ) {
   1502                     if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) {
   1503                         break;
   1504                     }
   1505                 }
   1506             }
   1507 
   1508             if (digit >= 0 && digit <= 9)
   1509             {
   1510                 if (strictParse && backup != -1) {
   1511                     // comma followed by digit, so group before comma is a
   1512                     // secondary group.  If there was a group separator
   1513                     // before that, the group must == the secondary group
   1514                     // length, else it can be <= the the secondary group
   1515                     // length.
   1516                     if ((lastGroup != -1 && currGroup - lastGroup != gs2) ||
   1517                         (lastGroup == -1 && digitCount - 1 > gs2)) {
   1518                         strictFail = TRUE;
   1519                         break;
   1520                     }
   1521 
   1522                     lastGroup = currGroup;
   1523                 }
   1524 
   1525                 // Cancel out backup setting (see grouping handler below)
   1526                 currGroup = -1;
   1527                 backup = -1;
   1528                 sawDigit = TRUE;
   1529 
   1530                 // Note: this will append leading zeros
   1531                 parsedNum.append((char)(digit + '0'), err);
   1532 
   1533                 // count any digit that's not a leading zero
   1534                 if (digit > 0 || digitCount > 0 || sawDecimal) {
   1535                     digitCount += 1;
   1536 
   1537                     // count any integer digit that's not a leading zero
   1538                     if (! sawDecimal) {
   1539                         integerDigitCount += 1;
   1540                     }
   1541                 }
   1542 
   1543                 position += U16_LENGTH(ch);
   1544             }
   1545             else if (groupingStringLength > 0 &&
   1546                 matchGrouping(groupingChar, sawGrouping, sawGroupingChar, groupingSet,
   1547                             decimalChar, decimalSet,
   1548                             ch) && groupingUsed)
   1549             {
   1550                 if (sawDecimal) {
   1551                     break;
   1552                 }
   1553 
   1554                 if (strictParse) {
   1555                     if ((!sawDigit || backup != -1)) {
   1556                         // leading group, or two group separators in a row
   1557                         strictFail = TRUE;
   1558                         break;
   1559                     }
   1560                 }
   1561 
   1562                 // Ignore grouping characters, if we are using them, but require
   1563                 // that they be followed by a digit.  Otherwise we backup and
   1564                 // reprocess them.
   1565                 currGroup = digitCount;
   1566                 backup = position;
   1567                 position += groupingStringLength;
   1568                 sawGrouping=TRUE;
   1569                 // Once we see a grouping character, we only accept that grouping character from then on.
   1570                 sawGroupingChar=ch;
   1571             }
   1572             else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimalSet, ch))
   1573             {
   1574                 if (strictParse) {
   1575                     if (backup != -1 ||
   1576                         (lastGroup != -1 && digitCount - lastGroup != fImpl->fEffGrouping.fGrouping)) {
   1577                         strictFail = TRUE;
   1578                         break;
   1579                     }
   1580                 }
   1581 
   1582                 // If we're only parsing integers, or if we ALREADY saw the
   1583                 // decimal, then don't parse this one.
   1584                 if (isParseIntegerOnly() || sawDecimal) {
   1585                     break;
   1586                 }
   1587 
   1588                 parsedNum.append('.', err);
   1589                 position += decimalStringLength;
   1590                 sawDecimal = TRUE;
   1591                 // Once we see a decimal character, we only accept that decimal character from then on.
   1592                 sawDecimalChar=ch;
   1593                 // decimalSet is considered to consist of (ch,ch)
   1594             }
   1595             else {
   1596 
   1597                 if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't parse if this is set unless..
   1598                    isScientificNotation()) { // .. it's an exponent format - ignore setting and parse anyways
   1599                     const UnicodeString *tmp;
   1600                     tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
   1601                     // TODO: CASE
   1602                     if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT))    // error code is set below if !sawDigit
   1603                     {
   1604                         // Parse sign, if present
   1605                         int32_t pos = position + tmp->length();
   1606                         char exponentSign = '+';
   1607 
   1608                         if (pos < textLength)
   1609                         {
   1610                             tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
   1611                             if (!text.compare(pos, tmp->length(), *tmp))
   1612                             {
   1613                                 pos += tmp->length();
   1614                             }
   1615                             else {
   1616                                 tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
   1617                                 if (!text.compare(pos, tmp->length(), *tmp))
   1618                                 {
   1619                                     exponentSign = '-';
   1620                                     pos += tmp->length();
   1621                                 }
   1622                             }
   1623                         }
   1624 
   1625                         UBool sawExponentDigit = FALSE;
   1626                         while (pos < textLength) {
   1627                             ch = text.char32At(pos);
   1628                             digit = ch - zero;
   1629 
   1630                             if (digit < 0 || digit > 9) {
   1631                                 digit = u_charDigitValue(ch);
   1632                             }
   1633                             if (0 <= digit && digit <= 9) {
   1634                                 if (!sawExponentDigit) {
   1635                                     parsedNum.append('E', err);
   1636                                     parsedNum.append(exponentSign, err);
   1637                                     sawExponentDigit = TRUE;
   1638                                 }
   1639                                 pos += U16_LENGTH(ch);
   1640                                 parsedNum.append((char)(digit + '0'), err);
   1641                             } else {
   1642                                 break;
   1643                             }
   1644                         }
   1645 
   1646                         if (sawExponentDigit) {
   1647                             position = pos; // Advance past the exponent
   1648                         }
   1649 
   1650                         break; // Whether we fail or succeed, we exit this loop
   1651                     } else {
   1652                         break;
   1653                     }
   1654                 } else { // not parsing exponent
   1655                     break;
   1656               }
   1657             }
   1658         }
   1659 
   1660         // if we didn't see a decimal and it is required, check to see if the pattern had one
   1661         if(!sawDecimal && isDecimalPatternMatchRequired())
   1662         {
   1663             if(formatPattern.indexOf(kPatternDecimalSeparator) != -1)
   1664             {
   1665                 parsePosition.setIndex(oldStart);
   1666                 parsePosition.setErrorIndex(position);
   1667                 debug("decimal point match required fail!");
   1668                 return FALSE;
   1669             }
   1670         }
   1671 
   1672         if (backup != -1)
   1673         {
   1674             position = backup;
   1675         }
   1676 
   1677         if (strictParse && !sawDecimal) {
   1678             if (lastGroup != -1 && digitCount - lastGroup != fImpl->fEffGrouping.fGrouping) {
   1679                 strictFail = TRUE;
   1680             }
   1681         }
   1682 
   1683         if (strictFail) {
   1684             // only set with strictParse and a grouping separator error
   1685 
   1686             parsePosition.setIndex(oldStart);
   1687             parsePosition.setErrorIndex(position);
   1688             debug("strictFail!");
   1689             return FALSE;
   1690         }
   1691 
   1692         // If there was no decimal point we have an integer
   1693 
   1694         // If none of the text string was recognized.  For example, parse
   1695         // "x" with pattern "#0.00" (return index and error index both 0)
   1696         // parse "$" with pattern "$#0.00". (return index 0 and error index
   1697         // 1).
   1698         if (!sawDigit && digitCount == 0) {
   1699 #ifdef FMT_DEBUG
   1700             debug("none of text rec");
   1701             printf("position=%d\n",position);
   1702 #endif
   1703             parsePosition.setIndex(oldStart);
   1704             parsePosition.setErrorIndex(oldStart);
   1705             return FALSE;
   1706         }
   1707     }
   1708 
   1709     // Match padding before suffix
   1710     if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
   1711         position = skipPadding(text, position);
   1712     }
   1713 
   1714     int32_t posSuffixMatch = -1, negSuffixMatch = -1;
   1715 
   1716     // Match positive and negative suffixes; prefer longest match.
   1717     if (posMatch >= 0 || (!strictParse && negMatch < 0)) {
   1718         posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, complexCurrencyParsing, type, currency);
   1719     }
   1720     if (negMatch >= 0) {
   1721         negSuffixMatch = compareAffix(text, position, TRUE, FALSE, negSuffix, complexCurrencyParsing, type, currency);
   1722     }
   1723     if (posSuffixMatch >= 0 && negSuffixMatch >= 0) {
   1724         if (posSuffixMatch > negSuffixMatch) {
   1725             negSuffixMatch = -1;
   1726         } else if (negSuffixMatch > posSuffixMatch) {
   1727             posSuffixMatch = -1;
   1728         }
   1729     }
   1730 
   1731     // Fail if neither or both
   1732     if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) {
   1733         parsePosition.setErrorIndex(position);
   1734         debug("neither or both");
   1735         return FALSE;
   1736     }
   1737 
   1738     position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0));
   1739 
   1740     // Match padding before suffix
   1741     if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
   1742         position = skipPadding(text, position);
   1743     }
   1744 
   1745     parsePosition.setIndex(position);
   1746 
   1747     parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0 && negSuffixMatch < 0)) ? '+' : '-';
   1748 #ifdef FMT_DEBUG
   1749 printf("PP -> %d, SLOW = [%s]!    pp=%d, os=%d, err=%s\n", position, parsedNum.data(), parsePosition.getIndex(),oldStart,u_errorName(err));
   1750 #endif
   1751   } /* end SLOW parse */
   1752   if(parsePosition.getIndex() == oldStart)
   1753     {
   1754 #ifdef FMT_DEBUG
   1755       printf(" PP didnt move, err\n");
   1756 #endif
   1757         parsePosition.setErrorIndex(position);
   1758         return FALSE;
   1759     }
   1760 #if UCONFIG_HAVE_PARSEALLINPUT
   1761   else if (fParseAllInput==UNUM_YES&&parsePosition.getIndex()!=textLength)
   1762     {
   1763 #ifdef FMT_DEBUG
   1764       printf(" PP didnt consume all (UNUM_YES), err\n");
   1765 #endif
   1766         parsePosition.setErrorIndex(position);
   1767         return FALSE;
   1768     }
   1769 #endif
   1770     // uint32_t bits = (fastParseOk?kFastpathOk:0) |
   1771     //   (fastParseHadDecimal?0:kNoDecimal);
   1772     //printf("FPOK=%d, FPHD=%d, bits=%08X\n", fastParseOk, fastParseHadDecimal, bits);
   1773     digits.set(parsedNum.toStringPiece(),
   1774                err,
   1775                0//bits
   1776                );
   1777 
   1778     if (U_FAILURE(err)) {
   1779 #ifdef FMT_DEBUG
   1780       printf(" err setting %s\n", u_errorName(err));
   1781 #endif
   1782         parsePosition.setErrorIndex(position);
   1783         return FALSE;
   1784     }
   1785 
   1786     // check if we missed a required decimal point
   1787     if(fastParseOk && isDecimalPatternMatchRequired())
   1788     {
   1789         if(formatPattern.indexOf(kPatternDecimalSeparator) != -1)
   1790         {
   1791             parsePosition.setIndex(oldStart);
   1792             parsePosition.setErrorIndex(position);
   1793             debug("decimal point match required fail!");
   1794             return FALSE;
   1795         }
   1796     }
   1797 
   1798 
   1799     return TRUE;
   1800 }
   1801 
   1802 /**
   1803  * Starting at position, advance past a run of pad characters, if any.
   1804  * Return the index of the first character after position that is not a pad
   1805  * character.  Result is >= position.
   1806  */
   1807 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
   1808     int32_t padLen = U16_LENGTH(fImpl->fAffixes.fPadChar);
   1809     while (position < text.length() &&
   1810            text.char32At(position) == fImpl->fAffixes.fPadChar) {
   1811         position += padLen;
   1812     }
   1813     return position;
   1814 }
   1815 
   1816 /**
   1817  * Return the length matched by the given affix, or -1 if none.
   1818  * Runs of white space in the affix, match runs of white space in
   1819  * the input.  Pattern white space and input white space are
   1820  * determined differently; see code.
   1821  * @param text input text
   1822  * @param pos offset into input at which to begin matching
   1823  * @param isNegative
   1824  * @param isPrefix
   1825  * @param affixPat affix pattern used for currency affix comparison.
   1826  * @param complexCurrencyParsing whether it is currency parsing or not
   1827  * @param type the currency type to parse against, LONG_NAME only or not.
   1828  * @param currency return value for parsed currency, for generic
   1829  * currency parsing mode, or null for normal parsing. In generic
   1830  * currency parsing mode, any currency is parsed, not just the
   1831  * currency that this formatter is set to.
   1832  * @return length of input that matches, or -1 if match failure
   1833  */
   1834 int32_t DecimalFormat::compareAffix(const UnicodeString& text,
   1835                                     int32_t pos,
   1836                                     UBool isNegative,
   1837                                     UBool isPrefix,
   1838                                     const UnicodeString* affixPat,
   1839                                     UBool complexCurrencyParsing,
   1840                                     int8_t type,
   1841                                     UChar* currency) const
   1842 {
   1843     const UnicodeString *patternToCompare;
   1844     if (currency != NULL ||
   1845         (fImpl->fMonetary && complexCurrencyParsing)) {
   1846 
   1847         if (affixPat != NULL) {
   1848             return compareComplexAffix(*affixPat, text, pos, type, currency);
   1849         }
   1850     }
   1851 
   1852     if (isNegative) {
   1853         if (isPrefix) {
   1854             patternToCompare = &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString();
   1855         }
   1856         else {
   1857             patternToCompare = &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString();
   1858         }
   1859     }
   1860     else {
   1861         if (isPrefix) {
   1862             patternToCompare = &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString();
   1863         }
   1864         else {
   1865             patternToCompare = &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString();
   1866         }
   1867     }
   1868     return compareSimpleAffix(*patternToCompare, text, pos, isLenient());
   1869 }
   1870 
   1871 UBool DecimalFormat::equalWithSignCompatibility(UChar32 lhs, UChar32 rhs) const {
   1872     if (lhs == rhs) {
   1873         return TRUE;
   1874     }
   1875     U_ASSERT(fStaticSets != NULL); // should already be loaded
   1876     const UnicodeSet *minusSigns = fStaticSets->fMinusSigns;
   1877     const UnicodeSet *plusSigns = fStaticSets->fPlusSigns;
   1878     return (minusSigns->contains(lhs) && minusSigns->contains(rhs)) ||
   1879         (plusSigns->contains(lhs) && plusSigns->contains(rhs));
   1880 }
   1881 
   1882 // check for LRM 0x200E, RLM 0x200F, ALM 0x061C
   1883 #define IS_BIDI_MARK(c) (c==0x200E || c==0x200F || c==0x061C)
   1884 
   1885 #define TRIM_BUFLEN 32
   1886 UnicodeString& DecimalFormat::trimMarksFromAffix(const UnicodeString& affix, UnicodeString& trimmedAffix) {
   1887     UChar trimBuf[TRIM_BUFLEN];
   1888     int32_t affixLen = affix.length();
   1889     int32_t affixPos, trimLen = 0;
   1890 
   1891     for (affixPos = 0; affixPos < affixLen; affixPos++) {
   1892         UChar c = affix.charAt(affixPos);
   1893         if (!IS_BIDI_MARK(c)) {
   1894             if (trimLen < TRIM_BUFLEN) {
   1895                 trimBuf[trimLen++] = c;
   1896             } else {
   1897                 trimLen = 0;
   1898                 break;
   1899             }
   1900         }
   1901     }
   1902     return (trimLen > 0)? trimmedAffix.setTo(trimBuf, trimLen): trimmedAffix.setTo(affix);
   1903 }
   1904 
   1905 /**
   1906  * Return the length matched by the given affix, or -1 if none.
   1907  * Runs of white space in the affix, match runs of white space in
   1908  * the input.  Pattern white space and input white space are
   1909  * determined differently; see code.
   1910  * @param affix pattern string, taken as a literal
   1911  * @param input input text
   1912  * @param pos offset into input at which to begin matching
   1913  * @return length of input that matches, or -1 if match failure
   1914  */
   1915 int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
   1916                                           const UnicodeString& input,
   1917                                           int32_t pos,
   1918                                           UBool lenient) const {
   1919     int32_t start = pos;
   1920     UnicodeString trimmedAffix;
   1921     // For more efficiency we should keep lazily-created trimmed affixes around in
   1922     // instance variables instead of trimming each time they are used (the next step)
   1923     trimMarksFromAffix(affix, trimmedAffix);
   1924     UChar32 affixChar = trimmedAffix.char32At(0);
   1925     int32_t affixLength = trimmedAffix.length();
   1926     int32_t inputLength = input.length();
   1927     int32_t affixCharLength = U16_LENGTH(affixChar);
   1928     UnicodeSet *affixSet;
   1929     UErrorCode status = U_ZERO_ERROR;
   1930 
   1931     U_ASSERT(fStaticSets != NULL); // should already be loaded
   1932 
   1933     if (U_FAILURE(status)) {
   1934         return -1;
   1935     }
   1936     if (!lenient) {
   1937         affixSet = fStaticSets->fStrictDashEquivalents;
   1938 
   1939         // If the trimmedAffix is exactly one character long and that character
   1940         // is in the dash set and the very next input character is also
   1941         // in the dash set, return a match.
   1942         if (affixCharLength == affixLength && affixSet->contains(affixChar))  {
   1943             UChar32 ic = input.char32At(pos);
   1944             if (affixSet->contains(ic)) {
   1945                 pos += U16_LENGTH(ic);
   1946                 pos = skipBidiMarks(input, pos); // skip any trailing bidi marks
   1947                 return pos - start;
   1948             }
   1949         }
   1950 
   1951         for (int32_t i = 0; i < affixLength; ) {
   1952             UChar32 c = trimmedAffix.char32At(i);
   1953             int32_t len = U16_LENGTH(c);
   1954             if (PatternProps::isWhiteSpace(c)) {
   1955                 // We may have a pattern like: \u200F \u0020
   1956                 //        and input text like: \u200F \u0020
   1957                 // Note that U+200F and U+0020 are Pattern_White_Space but only
   1958                 // U+0020 is UWhiteSpace.  So we have to first do a direct
   1959                 // match of the run of Pattern_White_Space in the pattern,
   1960                 // then match any extra characters.
   1961                 UBool literalMatch = FALSE;
   1962                 while (pos < inputLength) {
   1963                     UChar32 ic = input.char32At(pos);
   1964                     if (ic == c) {
   1965                         literalMatch = TRUE;
   1966                         i += len;
   1967                         pos += len;
   1968                         if (i == affixLength) {
   1969                             break;
   1970                         }
   1971                         c = trimmedAffix.char32At(i);
   1972                         len = U16_LENGTH(c);
   1973                         if (!PatternProps::isWhiteSpace(c)) {
   1974                             break;
   1975                         }
   1976                     } else if (IS_BIDI_MARK(ic)) {
   1977                         pos ++; // just skip over this input text
   1978                     } else {
   1979                         break;
   1980                     }
   1981                 }
   1982 
   1983                 // Advance over run in pattern
   1984                 i = skipPatternWhiteSpace(trimmedAffix, i);
   1985 
   1986                 // Advance over run in input text
   1987                 // Must see at least one white space char in input,
   1988                 // unless we've already matched some characters literally.
   1989                 int32_t s = pos;
   1990                 pos = skipUWhiteSpace(input, pos);
   1991                 if (pos == s && !literalMatch) {
   1992                     return -1;
   1993                 }
   1994 
   1995                 // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
   1996                 // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
   1997                 // is also in the trimmedAffix.
   1998                 i = skipUWhiteSpace(trimmedAffix, i);
   1999             } else {
   2000                 UBool match = FALSE;
   2001                 while (pos < inputLength) {
   2002                     UChar32 ic = input.char32At(pos);
   2003                     if (!match && ic == c) {
   2004                         i += len;
   2005                         pos += len;
   2006                         match = TRUE;
   2007                     } else if (IS_BIDI_MARK(ic)) {
   2008                         pos++; // just skip over this input text
   2009                     } else {
   2010                         break;
   2011                     }
   2012                 }
   2013                 if (!match) {
   2014                     return -1;
   2015                 }
   2016             }
   2017         }
   2018     } else {
   2019         UBool match = FALSE;
   2020 
   2021         affixSet = fStaticSets->fDashEquivalents;
   2022 
   2023         if (affixCharLength == affixLength && affixSet->contains(affixChar))  {
   2024             pos = skipUWhiteSpaceAndMarks(input, pos);
   2025             UChar32 ic = input.char32At(pos);
   2026 
   2027             if (affixSet->contains(ic)) {
   2028                 pos += U16_LENGTH(ic);
   2029                 pos = skipBidiMarks(input, pos);
   2030                 return pos - start;
   2031             }
   2032         }
   2033 
   2034         for (int32_t i = 0; i < affixLength; )
   2035         {
   2036             //i = skipRuleWhiteSpace(trimmedAffix, i);
   2037             i = skipUWhiteSpace(trimmedAffix, i);
   2038             pos = skipUWhiteSpaceAndMarks(input, pos);
   2039 
   2040             if (i >= affixLength || pos >= inputLength) {
   2041                 break;
   2042             }
   2043 
   2044             UChar32 c = trimmedAffix.char32At(i);
   2045             UChar32 ic = input.char32At(pos);
   2046 
   2047             if (!equalWithSignCompatibility(ic, c)) {
   2048                 return -1;
   2049             }
   2050 
   2051             match = TRUE;
   2052             i += U16_LENGTH(c);
   2053             pos += U16_LENGTH(ic);
   2054             pos = skipBidiMarks(input, pos);
   2055         }
   2056 
   2057         if (affixLength > 0 && ! match) {
   2058             return -1;
   2059         }
   2060     }
   2061     return pos - start;
   2062 }
   2063 
   2064 /**
   2065  * Skip over a run of zero or more Pattern_White_Space characters at
   2066  * pos in text.
   2067  */
   2068 int32_t DecimalFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) {
   2069     const UChar* s = text.getBuffer();
   2070     return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s);
   2071 }
   2072 
   2073 /**
   2074  * Skip over a run of zero or more isUWhiteSpace() characters at pos
   2075  * in text.
   2076  */
   2077 int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) {
   2078     while (pos < text.length()) {
   2079         UChar32 c = text.char32At(pos);
   2080         if (!u_isUWhiteSpace(c)) {
   2081             break;
   2082         }
   2083         pos += U16_LENGTH(c);
   2084     }
   2085     return pos;
   2086 }
   2087 
   2088 /**
   2089  * Skip over a run of zero or more isUWhiteSpace() characters or bidi marks at pos
   2090  * in text.
   2091  */
   2092 int32_t DecimalFormat::skipUWhiteSpaceAndMarks(const UnicodeString& text, int32_t pos) {
   2093     while (pos < text.length()) {
   2094         UChar32 c = text.char32At(pos);
   2095         if (!u_isUWhiteSpace(c) && !IS_BIDI_MARK(c)) { // u_isUWhiteSpace doesn't include LRM,RLM,ALM
   2096             break;
   2097         }
   2098         pos += U16_LENGTH(c);
   2099     }
   2100     return pos;
   2101 }
   2102 
   2103 /**
   2104  * Skip over a run of zero or more bidi marks at pos in text.
   2105  */
   2106 int32_t DecimalFormat::skipBidiMarks(const UnicodeString& text, int32_t pos) {
   2107     while (pos < text.length()) {
   2108         UChar c = text.charAt(pos);
   2109         if (!IS_BIDI_MARK(c)) {
   2110             break;
   2111         }
   2112         pos++;
   2113     }
   2114     return pos;
   2115 }
   2116 
   2117 /**
   2118  * Return the length matched by the given affix, or -1 if none.
   2119  * @param affixPat pattern string
   2120  * @param input input text
   2121  * @param pos offset into input at which to begin matching
   2122  * @param type the currency type to parse against, LONG_NAME only or not.
   2123  * @param currency return value for parsed currency, for generic
   2124  * currency parsing mode, or null for normal parsing. In generic
   2125  * currency parsing mode, any currency is parsed, not just the
   2126  * currency that this formatter is set to.
   2127  * @return length of input that matches, or -1 if match failure
   2128  */
   2129 int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat,
   2130                                            const UnicodeString& text,
   2131                                            int32_t pos,
   2132                                            int8_t type,
   2133                                            UChar* currency) const
   2134 {
   2135     int32_t start = pos;
   2136     U_ASSERT(currency != NULL || fImpl->fMonetary);
   2137 
   2138     for (int32_t i=0;
   2139          i<affixPat.length() && pos >= 0; ) {
   2140         UChar32 c = affixPat.char32At(i);
   2141         i += U16_LENGTH(c);
   2142 
   2143         if (c == kQuote) {
   2144             U_ASSERT(i <= affixPat.length());
   2145             c = affixPat.char32At(i);
   2146             i += U16_LENGTH(c);
   2147 
   2148             const UnicodeString* affix = NULL;
   2149 
   2150             switch (c) {
   2151             case kCurrencySign: {
   2152                 // since the currency names in choice format is saved
   2153                 // the same way as other currency names,
   2154                 // do not need to do currency choice parsing here.
   2155                 // the general currency parsing parse against all names,
   2156                 // including names in choice format.
   2157                 UBool intl = i<affixPat.length() &&
   2158                     affixPat.char32At(i) == kCurrencySign;
   2159                 if (intl) {
   2160                     ++i;
   2161                 }
   2162                 UBool plural = i<affixPat.length() &&
   2163                     affixPat.char32At(i) == kCurrencySign;
   2164                 if (plural) {
   2165                     ++i;
   2166                     intl = FALSE;
   2167                 }
   2168                 // Parse generic currency -- anything for which we
   2169                 // have a display name, or any 3-letter ISO code.
   2170                 // Try to parse display name for our locale; first
   2171                 // determine our locale.
   2172                 const char* loc = fCurrencyPluralInfo->getLocale().getName();
   2173                 ParsePosition ppos(pos);
   2174                 UChar curr[4];
   2175                 UErrorCode ec = U_ZERO_ERROR;
   2176                 // Delegate parse of display name => ISO code to Currency
   2177                 uprv_parseCurrency(loc, text, ppos, type, curr, ec);
   2178 
   2179                 // If parse succeeds, populate currency[0]
   2180                 if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
   2181                     if (currency) {
   2182                         u_strcpy(currency, curr);
   2183                     } else {
   2184                         // The formatter is currency-style but the client has not requested
   2185                         // the value of the parsed currency. In this case, if that value does
   2186                         // not match the formatter's current value, then the parse fails.
   2187                         UChar effectiveCurr[4];
   2188                         getEffectiveCurrency(effectiveCurr, ec);
   2189                         if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) {
   2190                             pos = -1;
   2191                             continue;
   2192                         }
   2193                     }
   2194                     pos = ppos.getIndex();
   2195                 } else if (!isLenient()){
   2196                     pos = -1;
   2197                 }
   2198                 continue;
   2199             }
   2200             case kPatternPercent:
   2201                 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
   2202                 break;
   2203             case kPatternPerMill:
   2204                 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
   2205                 break;
   2206             case kPatternPlus:
   2207                 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
   2208                 break;
   2209             case kPatternMinus:
   2210                 affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
   2211                 break;
   2212             default:
   2213                 // fall through to affix!=0 test, which will fail
   2214                 break;
   2215             }
   2216 
   2217             if (affix != NULL) {
   2218                 pos = match(text, pos, *affix);
   2219                 continue;
   2220             }
   2221         }
   2222 
   2223         pos = match(text, pos, c);
   2224         if (PatternProps::isWhiteSpace(c)) {
   2225             i = skipPatternWhiteSpace(affixPat, i);
   2226         }
   2227     }
   2228     return pos - start;
   2229 }
   2230 
   2231 /**
   2232  * Match a single character at text[pos] and return the index of the
   2233  * next character upon success.  Return -1 on failure.  If
   2234  * ch is a Pattern_White_Space then match a run of white space in text.
   2235  */
   2236 int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) {
   2237     if (PatternProps::isWhiteSpace(ch)) {
   2238         // Advance over run of white space in input text
   2239         // Must see at least one white space char in input
   2240         int32_t s = pos;
   2241         pos = skipPatternWhiteSpace(text, pos);
   2242         if (pos == s) {
   2243             return -1;
   2244         }
   2245         return pos;
   2246     }
   2247     return (pos >= 0 && text.char32At(pos) == ch) ?
   2248         (pos + U16_LENGTH(ch)) : -1;
   2249 }
   2250 
   2251 /**
   2252  * Match a string at text[pos] and return the index of the next
   2253  * character upon success.  Return -1 on failure.  Match a run of
   2254  * white space in str with a run of white space in text.
   2255  */
   2256 int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) {
   2257     for (int32_t i=0; i<str.length() && pos >= 0; ) {
   2258         UChar32 ch = str.char32At(i);
   2259         i += U16_LENGTH(ch);
   2260         if (PatternProps::isWhiteSpace(ch)) {
   2261             i = skipPatternWhiteSpace(str, i);
   2262         }
   2263         pos = match(text, pos, ch);
   2264     }
   2265     return pos;
   2266 }
   2267 
   2268 UBool DecimalFormat::matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol,
   2269                          UnicodeSet *sset, UChar32 schar)
   2270 {
   2271     if (sset != NULL) {
   2272         return sset->contains(schar);
   2273     }
   2274 
   2275     return text.compare(position, length, symbol) == 0;
   2276 }
   2277 
   2278 UBool DecimalFormat::matchDecimal(UChar32 symbolChar,
   2279                             UBool sawDecimal,  UChar32 sawDecimalChar,
   2280                              const UnicodeSet *sset, UChar32 schar) {
   2281    if(sawDecimal) {
   2282        return schar==sawDecimalChar;
   2283    } else if(schar==symbolChar) {
   2284        return TRUE;
   2285    } else if(sset!=NULL) {
   2286         return sset->contains(schar);
   2287    } else {
   2288        return FALSE;
   2289    }
   2290 }
   2291 
   2292 UBool DecimalFormat::matchGrouping(UChar32 groupingChar,
   2293                             UBool sawGrouping, UChar32 sawGroupingChar,
   2294                              const UnicodeSet *sset,
   2295                              UChar32 /*decimalChar*/, const UnicodeSet *decimalSet,
   2296                              UChar32 schar) {
   2297     if(sawGrouping) {
   2298         return schar==sawGroupingChar;  // previously found
   2299     } else if(schar==groupingChar) {
   2300         return TRUE; // char from symbols
   2301     } else if(sset!=NULL) {
   2302         return sset->contains(schar) &&  // in groupingSet but...
   2303            ((decimalSet==NULL) || !decimalSet->contains(schar)); // Exclude decimalSet from groupingSet
   2304     } else {
   2305         return FALSE;
   2306     }
   2307 }
   2308 
   2309 
   2310 
   2311 //------------------------------------------------------------------------------
   2312 // Gets the pointer to the localized decimal format symbols
   2313 
   2314 const DecimalFormatSymbols*
   2315 DecimalFormat::getDecimalFormatSymbols() const
   2316 {
   2317     return &fImpl->getDecimalFormatSymbols();
   2318 }
   2319 
   2320 //------------------------------------------------------------------------------
   2321 // De-owning the current localized symbols and adopt the new symbols.
   2322 
   2323 void
   2324 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
   2325 {
   2326     if (symbolsToAdopt == NULL) {
   2327         return; // do not allow caller to set fSymbols to NULL
   2328     }
   2329     fImpl->adoptDecimalFormatSymbols(symbolsToAdopt);
   2330 }
   2331 //------------------------------------------------------------------------------
   2332 // Setting the symbols is equlivalent to adopting a newly created localized
   2333 // symbols.
   2334 
   2335 void
   2336 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
   2337 {
   2338     adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
   2339 }
   2340 
   2341 
   2342 const CurrencyPluralInfo*
   2343 DecimalFormat::getCurrencyPluralInfo(void) const
   2344 {
   2345     return fCurrencyPluralInfo;
   2346 }
   2347 
   2348 
   2349 void
   2350 DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt)
   2351 {
   2352     if (toAdopt != NULL) {
   2353         delete fCurrencyPluralInfo;
   2354         fCurrencyPluralInfo = toAdopt;
   2355         // re-set currency affix patterns and currency affixes.
   2356         if (fImpl->fMonetary) {
   2357             UErrorCode status = U_ZERO_ERROR;
   2358             if (fAffixPatternsForCurrency) {
   2359                 deleteHashForAffixPattern();
   2360             }
   2361             setupCurrencyAffixPatterns(status);
   2362         }
   2363     }
   2364 }
   2365 
   2366 void
   2367 DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info)
   2368 {
   2369     adoptCurrencyPluralInfo(info.clone());
   2370 }
   2371 
   2372 
   2373 //------------------------------------------------------------------------------
   2374 // Gets the positive prefix of the number pattern.
   2375 
   2376 UnicodeString&
   2377 DecimalFormat::getPositivePrefix(UnicodeString& result) const
   2378 {
   2379     return fImpl->getPositivePrefix(result);
   2380 }
   2381 
   2382 //------------------------------------------------------------------------------
   2383 // Sets the positive prefix of the number pattern.
   2384 
   2385 void
   2386 DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
   2387 {
   2388     fImpl->setPositivePrefix(newValue);
   2389 }
   2390 
   2391 //------------------------------------------------------------------------------
   2392 // Gets the negative prefix  of the number pattern.
   2393 
   2394 UnicodeString&
   2395 DecimalFormat::getNegativePrefix(UnicodeString& result) const
   2396 {
   2397     return fImpl->getNegativePrefix(result);
   2398 }
   2399 
   2400 //------------------------------------------------------------------------------
   2401 // Gets the negative prefix  of the number pattern.
   2402 
   2403 void
   2404 DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
   2405 {
   2406     fImpl->setNegativePrefix(newValue);
   2407 }
   2408 
   2409 //------------------------------------------------------------------------------
   2410 // Gets the positive suffix of the number pattern.
   2411 
   2412 UnicodeString&
   2413 DecimalFormat::getPositiveSuffix(UnicodeString& result) const
   2414 {
   2415     return fImpl->getPositiveSuffix(result);
   2416 }
   2417 
   2418 //------------------------------------------------------------------------------
   2419 // Sets the positive suffix of the number pattern.
   2420 
   2421 void
   2422 DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
   2423 {
   2424     fImpl->setPositiveSuffix(newValue);
   2425 }
   2426 
   2427 //------------------------------------------------------------------------------
   2428 // Gets the negative suffix of the number pattern.
   2429 
   2430 UnicodeString&
   2431 DecimalFormat::getNegativeSuffix(UnicodeString& result) const
   2432 {
   2433     return fImpl->getNegativeSuffix(result);
   2434 }
   2435 
   2436 //------------------------------------------------------------------------------
   2437 // Sets the negative suffix of the number pattern.
   2438 
   2439 void
   2440 DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
   2441 {
   2442     fImpl->setNegativeSuffix(newValue);
   2443 }
   2444 
   2445 //------------------------------------------------------------------------------
   2446 // Gets the multiplier of the number pattern.
   2447 //   Multipliers are stored as decimal numbers (DigitLists) because that
   2448 //      is the most convenient for muliplying or dividing the numbers to be formatted.
   2449 //   A NULL multiplier implies one, and the scaling operations are skipped.
   2450 
   2451 int32_t
   2452 DecimalFormat::getMultiplier() const
   2453 {
   2454     return fImpl->getMultiplier();
   2455 }
   2456 
   2457 //------------------------------------------------------------------------------
   2458 // Sets the multiplier of the number pattern.
   2459 void
   2460 DecimalFormat::setMultiplier(int32_t newValue)
   2461 {
   2462     fImpl->setMultiplier(newValue);
   2463 }
   2464 
   2465 /**
   2466  * Get the rounding increment.
   2467  * @return A positive rounding increment, or 0.0 if rounding
   2468  * is not in effect.
   2469  * @see #setRoundingIncrement
   2470  * @see #getRoundingMode
   2471  * @see #setRoundingMode
   2472  */
   2473 double DecimalFormat::getRoundingIncrement() const {
   2474     return fImpl->getRoundingIncrement();
   2475 }
   2476 
   2477 /**
   2478  * Set the rounding increment.  This method also controls whether
   2479  * rounding is enabled.
   2480  * @param newValue A positive rounding increment, or 0.0 to disable rounding.
   2481  * Negative increments are equivalent to 0.0.
   2482  * @see #getRoundingIncrement
   2483  * @see #getRoundingMode
   2484  * @see #setRoundingMode
   2485  */
   2486 void DecimalFormat::setRoundingIncrement(double newValue) {
   2487     fImpl->setRoundingIncrement(newValue);
   2488 }
   2489 
   2490 /**
   2491  * Get the rounding mode.
   2492  * @return A rounding mode
   2493  * @see #setRoundingIncrement
   2494  * @see #getRoundingIncrement
   2495  * @see #setRoundingMode
   2496  */
   2497 DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const {
   2498     return fImpl->getRoundingMode();
   2499 }
   2500 
   2501 /**
   2502  * Set the rounding mode.  This has no effect unless the rounding
   2503  * increment is greater than zero.
   2504  * @param roundingMode A rounding mode
   2505  * @see #setRoundingIncrement
   2506  * @see #getRoundingIncrement
   2507  * @see #getRoundingMode
   2508  */
   2509 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
   2510     fImpl->setRoundingMode(roundingMode);
   2511 }
   2512 
   2513 /**
   2514  * Get the width to which the output of <code>format()</code> is padded.
   2515  * @return the format width, or zero if no padding is in effect
   2516  * @see #setFormatWidth
   2517  * @see #getPadCharacter
   2518  * @see #setPadCharacter
   2519  * @see #getPadPosition
   2520  * @see #setPadPosition
   2521  */
   2522 int32_t DecimalFormat::getFormatWidth() const {
   2523     return fImpl->getFormatWidth();
   2524 }
   2525 
   2526 /**
   2527  * Set the width to which the output of <code>format()</code> is padded.
   2528  * This method also controls whether padding is enabled.
   2529  * @param width the width to which to pad the result of
   2530  * <code>format()</code>, or zero to disable padding.  A negative
   2531  * width is equivalent to 0.
   2532  * @see #getFormatWidth
   2533  * @see #getPadCharacter
   2534  * @see #setPadCharacter
   2535  * @see #getPadPosition
   2536  * @see #setPadPosition
   2537  */
   2538 void DecimalFormat::setFormatWidth(int32_t width) {
   2539     int32_t formatWidth = (width > 0) ? width : 0;
   2540     fImpl->setFormatWidth(formatWidth);
   2541 }
   2542 
   2543 UnicodeString DecimalFormat::getPadCharacterString() const {
   2544     return UnicodeString(fImpl->getPadCharacter());
   2545 }
   2546 
   2547 void DecimalFormat::setPadCharacter(const UnicodeString &padChar) {
   2548     UChar32 pad;
   2549     if (padChar.length() > 0) {
   2550         pad = padChar.char32At(0);
   2551     }
   2552     else {
   2553         pad = kDefaultPad;
   2554     }
   2555     fImpl->setPadCharacter(pad);
   2556 }
   2557 
   2558 static DecimalFormat::EPadPosition fromPadPosition(DigitAffixesAndPadding::EPadPosition padPos) {
   2559     switch (padPos) {
   2560     case DigitAffixesAndPadding::kPadBeforePrefix:
   2561         return DecimalFormat::kPadBeforePrefix;
   2562     case DigitAffixesAndPadding::kPadAfterPrefix:
   2563         return DecimalFormat::kPadAfterPrefix;
   2564     case DigitAffixesAndPadding::kPadBeforeSuffix:
   2565         return DecimalFormat::kPadBeforeSuffix;
   2566     case DigitAffixesAndPadding::kPadAfterSuffix:
   2567         return DecimalFormat::kPadAfterSuffix;
   2568     default:
   2569         U_ASSERT(FALSE);
   2570         break;
   2571     }
   2572     return DecimalFormat::kPadBeforePrefix;
   2573 }
   2574 
   2575 /**
   2576  * Get the position at which padding will take place.  This is the location
   2577  * at which padding will be inserted if the result of <code>format()</code>
   2578  * is shorter than the format width.
   2579  * @return the pad position, one of <code>kPadBeforePrefix</code>,
   2580  * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
   2581  * <code>kPadAfterSuffix</code>.
   2582  * @see #setFormatWidth
   2583  * @see #getFormatWidth
   2584  * @see #setPadCharacter
   2585  * @see #getPadCharacter
   2586  * @see #setPadPosition
   2587  * @see #kPadBeforePrefix
   2588  * @see #kPadAfterPrefix
   2589  * @see #kPadBeforeSuffix
   2590  * @see #kPadAfterSuffix
   2591  */
   2592 DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const {
   2593     return fromPadPosition(fImpl->getPadPosition());
   2594 }
   2595 
   2596 static DigitAffixesAndPadding::EPadPosition toPadPosition(DecimalFormat::EPadPosition padPos) {
   2597     switch (padPos) {
   2598     case DecimalFormat::kPadBeforePrefix:
   2599         return DigitAffixesAndPadding::kPadBeforePrefix;
   2600     case DecimalFormat::kPadAfterPrefix:
   2601         return DigitAffixesAndPadding::kPadAfterPrefix;
   2602     case DecimalFormat::kPadBeforeSuffix:
   2603         return DigitAffixesAndPadding::kPadBeforeSuffix;
   2604     case DecimalFormat::kPadAfterSuffix:
   2605         return DigitAffixesAndPadding::kPadAfterSuffix;
   2606     default:
   2607         U_ASSERT(FALSE);
   2608         break;
   2609     }
   2610     return DigitAffixesAndPadding::kPadBeforePrefix;
   2611 }
   2612 
   2613 /**
   2614  * <strong><font face=helvetica color=red>NEW</font></strong>
   2615  * Set the position at which padding will take place.  This is the location
   2616  * at which padding will be inserted if the result of <code>format()</code>
   2617  * is shorter than the format width.  This has no effect unless padding is
   2618  * enabled.
   2619  * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
   2620  * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
   2621  * <code>kPadAfterSuffix</code>.
   2622  * @see #setFormatWidth
   2623  * @see #getFormatWidth
   2624  * @see #setPadCharacter
   2625  * @see #getPadCharacter
   2626  * @see #getPadPosition
   2627  * @see #kPadBeforePrefix
   2628  * @see #kPadAfterPrefix
   2629  * @see #kPadBeforeSuffix
   2630  * @see #kPadAfterSuffix
   2631  */
   2632 void DecimalFormat::setPadPosition(EPadPosition padPos) {
   2633     fImpl->setPadPosition(toPadPosition(padPos));
   2634 }
   2635 
   2636 /**
   2637  * Return whether or not scientific notation is used.
   2638  * @return TRUE if this object formats and parses scientific notation
   2639  * @see #setScientificNotation
   2640  * @see #getMinimumExponentDigits
   2641  * @see #setMinimumExponentDigits
   2642  * @see #isExponentSignAlwaysShown
   2643  * @see #setExponentSignAlwaysShown
   2644  */
   2645 UBool DecimalFormat::isScientificNotation() const {
   2646     return fImpl->isScientificNotation();
   2647 }
   2648 
   2649 /**
   2650  * Set whether or not scientific notation is used.
   2651  * @param useScientific TRUE if this object formats and parses scientific
   2652  * notation
   2653  * @see #isScientificNotation
   2654  * @see #getMinimumExponentDigits
   2655  * @see #setMinimumExponentDigits
   2656  * @see #isExponentSignAlwaysShown
   2657  * @see #setExponentSignAlwaysShown
   2658  */
   2659 void DecimalFormat::setScientificNotation(UBool useScientific) {
   2660     fImpl->setScientificNotation(useScientific);
   2661 }
   2662 
   2663 /**
   2664  * Return the minimum exponent digits that will be shown.
   2665  * @return the minimum exponent digits that will be shown
   2666  * @see #setScientificNotation
   2667  * @see #isScientificNotation
   2668  * @see #setMinimumExponentDigits
   2669  * @see #isExponentSignAlwaysShown
   2670  * @see #setExponentSignAlwaysShown
   2671  */
   2672 int8_t DecimalFormat::getMinimumExponentDigits() const {
   2673     return fImpl->getMinimumExponentDigits();
   2674 }
   2675 
   2676 /**
   2677  * Set the minimum exponent digits that will be shown.  This has no
   2678  * effect unless scientific notation is in use.
   2679  * @param minExpDig a value >= 1 indicating the fewest exponent digits
   2680  * that will be shown.  Values less than 1 will be treated as 1.
   2681  * @see #setScientificNotation
   2682  * @see #isScientificNotation
   2683  * @see #getMinimumExponentDigits
   2684  * @see #isExponentSignAlwaysShown
   2685  * @see #setExponentSignAlwaysShown
   2686  */
   2687 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
   2688     int32_t minExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
   2689     fImpl->setMinimumExponentDigits(minExponentDigits);
   2690 }
   2691 
   2692 /**
   2693  * Return whether the exponent sign is always shown.
   2694  * @return TRUE if the exponent is always prefixed with either the
   2695  * localized minus sign or the localized plus sign, false if only negative
   2696  * exponents are prefixed with the localized minus sign.
   2697  * @see #setScientificNotation
   2698  * @see #isScientificNotation
   2699  * @see #setMinimumExponentDigits
   2700  * @see #getMinimumExponentDigits
   2701  * @see #setExponentSignAlwaysShown
   2702  */
   2703 UBool DecimalFormat::isExponentSignAlwaysShown() const {
   2704     return fImpl->isExponentSignAlwaysShown();
   2705 }
   2706 
   2707 /**
   2708  * Set whether the exponent sign is always shown.  This has no effect
   2709  * unless scientific notation is in use.
   2710  * @param expSignAlways TRUE if the exponent is always prefixed with either
   2711  * the localized minus sign or the localized plus sign, false if only
   2712  * negative exponents are prefixed with the localized minus sign.
   2713  * @see #setScientificNotation
   2714  * @see #isScientificNotation
   2715  * @see #setMinimumExponentDigits
   2716  * @see #getMinimumExponentDigits
   2717  * @see #isExponentSignAlwaysShown
   2718  */
   2719 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
   2720     fImpl->setExponentSignAlwaysShown(expSignAlways);
   2721 }
   2722 
   2723 //------------------------------------------------------------------------------
   2724 // Gets the grouping size of the number pattern.  For example, thousand or 10
   2725 // thousand groupings.
   2726 
   2727 int32_t
   2728 DecimalFormat::getGroupingSize() const
   2729 {
   2730     return fImpl->getGroupingSize();
   2731 }
   2732 
   2733 //------------------------------------------------------------------------------
   2734 // Gets the grouping size of the number pattern.
   2735 
   2736 void
   2737 DecimalFormat::setGroupingSize(int32_t newValue)
   2738 {
   2739     fImpl->setGroupingSize(newValue);
   2740 }
   2741 
   2742 //------------------------------------------------------------------------------
   2743 
   2744 int32_t
   2745 DecimalFormat::getSecondaryGroupingSize() const
   2746 {
   2747     return fImpl->getSecondaryGroupingSize();
   2748 }
   2749 
   2750 //------------------------------------------------------------------------------
   2751 
   2752 void
   2753 DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
   2754 {
   2755     fImpl->setSecondaryGroupingSize(newValue);
   2756 }
   2757 
   2758 //------------------------------------------------------------------------------
   2759 
   2760 int32_t
   2761 DecimalFormat::getMinimumGroupingDigits() const
   2762 {
   2763     return fImpl->getMinimumGroupingDigits();
   2764 }
   2765 
   2766 //------------------------------------------------------------------------------
   2767 
   2768 void
   2769 DecimalFormat::setMinimumGroupingDigits(int32_t newValue)
   2770 {
   2771     fImpl->setMinimumGroupingDigits(newValue);
   2772 }
   2773 
   2774 //------------------------------------------------------------------------------
   2775 // Checks if to show the decimal separator.
   2776 
   2777 UBool
   2778 DecimalFormat::isDecimalSeparatorAlwaysShown() const
   2779 {
   2780     return fImpl->isDecimalSeparatorAlwaysShown();
   2781 }
   2782 
   2783 //------------------------------------------------------------------------------
   2784 // Sets to always show the decimal separator.
   2785 
   2786 void
   2787 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
   2788 {
   2789     fImpl->setDecimalSeparatorAlwaysShown(newValue);
   2790 }
   2791 
   2792 //------------------------------------------------------------------------------
   2793 // Checks if decimal point pattern match is required
   2794 UBool
   2795 DecimalFormat::isDecimalPatternMatchRequired(void) const
   2796 {
   2797     return static_cast<UBool>(fBoolFlags.contains(UNUM_PARSE_DECIMAL_MARK_REQUIRED));
   2798 }
   2799 
   2800 //------------------------------------------------------------------------------
   2801 // Checks if decimal point pattern match is required
   2802 
   2803 void
   2804 DecimalFormat::setDecimalPatternMatchRequired(UBool newValue)
   2805 {
   2806     fBoolFlags.set(UNUM_PARSE_DECIMAL_MARK_REQUIRED, newValue);
   2807 }
   2808 
   2809 
   2810 //------------------------------------------------------------------------------
   2811 // Emits the pattern of this DecimalFormat instance.
   2812 
   2813 UnicodeString&
   2814 DecimalFormat::toPattern(UnicodeString& result) const
   2815 {
   2816     return fImpl->toPattern(result);
   2817 }
   2818 
   2819 //------------------------------------------------------------------------------
   2820 // Emits the localized pattern this DecimalFormat instance.
   2821 
   2822 UnicodeString&
   2823 DecimalFormat::toLocalizedPattern(UnicodeString& result) const
   2824 {
   2825     // toLocalizedPattern is deprecated, so we just make it the same as
   2826     // toPattern.
   2827     return fImpl->toPattern(result);
   2828 }
   2829 
   2830 //------------------------------------------------------------------------------
   2831 
   2832 void
   2833 DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
   2834 {
   2835     if (pattern.indexOf(kCurrencySign) != -1) {
   2836         handleCurrencySignInPattern(status);
   2837     }
   2838     fImpl->applyPattern(pattern, status);
   2839 }
   2840 
   2841 //------------------------------------------------------------------------------
   2842 
   2843 void
   2844 DecimalFormat::applyPattern(const UnicodeString& pattern,
   2845                             UParseError& parseError,
   2846                             UErrorCode& status)
   2847 {
   2848     if (pattern.indexOf(kCurrencySign) != -1) {
   2849         handleCurrencySignInPattern(status);
   2850     }
   2851     fImpl->applyPattern(pattern, parseError, status);
   2852 }
   2853 //------------------------------------------------------------------------------
   2854 
   2855 void
   2856 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
   2857 {
   2858     if (pattern.indexOf(kCurrencySign) != -1) {
   2859         handleCurrencySignInPattern(status);
   2860     }
   2861     fImpl->applyLocalizedPattern(pattern, status);
   2862 }
   2863 
   2864 //------------------------------------------------------------------------------
   2865 
   2866 void
   2867 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
   2868                                      UParseError& parseError,
   2869                                      UErrorCode& status)
   2870 {
   2871     if (pattern.indexOf(kCurrencySign) != -1) {
   2872         handleCurrencySignInPattern(status);
   2873     }
   2874     fImpl->applyLocalizedPattern(pattern, parseError, status);
   2875 }
   2876 
   2877 //------------------------------------------------------------------------------
   2878 
   2879 /**
   2880  * Sets the maximum number of digits allowed in the integer portion of a
   2881  * number.
   2882  * @see NumberFormat#setMaximumIntegerDigits
   2883  */
   2884 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
   2885     newValue = _min(newValue, gDefaultMaxIntegerDigits);
   2886     NumberFormat::setMaximumIntegerDigits(newValue);
   2887     fImpl->updatePrecision();
   2888 }
   2889 
   2890 /**
   2891  * Sets the minimum number of digits allowed in the integer portion of a
   2892  * number. This override limits the integer digit count to 309.
   2893  * @see NumberFormat#setMinimumIntegerDigits
   2894  */
   2895 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
   2896     newValue = _min(newValue, kDoubleIntegerDigits);
   2897     NumberFormat::setMinimumIntegerDigits(newValue);
   2898     fImpl->updatePrecision();
   2899 }
   2900 
   2901 /**
   2902  * Sets the maximum number of digits allowed in the fraction portion of a
   2903  * number. This override limits the fraction digit count to 340.
   2904  * @see NumberFormat#setMaximumFractionDigits
   2905  */
   2906 void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
   2907     newValue = _min(newValue, kDoubleFractionDigits);
   2908     NumberFormat::setMaximumFractionDigits(newValue);
   2909     fImpl->updatePrecision();
   2910 }
   2911 
   2912 /**
   2913  * Sets the minimum number of digits allowed in the fraction portion of a
   2914  * number. This override limits the fraction digit count to 340.
   2915  * @see NumberFormat#setMinimumFractionDigits
   2916  */
   2917 void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
   2918     newValue = _min(newValue, kDoubleFractionDigits);
   2919     NumberFormat::setMinimumFractionDigits(newValue);
   2920     fImpl->updatePrecision();
   2921 }
   2922 
   2923 int32_t DecimalFormat::getMinimumSignificantDigits() const {
   2924     return fImpl->getMinimumSignificantDigits();
   2925 }
   2926 
   2927 int32_t DecimalFormat::getMaximumSignificantDigits() const {
   2928     return fImpl->getMaximumSignificantDigits();
   2929 }
   2930 
   2931 void DecimalFormat::setMinimumSignificantDigits(int32_t min) {
   2932     if (min < 1) {
   2933         min = 1;
   2934     }
   2935     // pin max sig dig to >= min
   2936     int32_t max = _max(fImpl->fMaxSigDigits, min);
   2937     fImpl->setMinMaxSignificantDigits(min, max);
   2938 }
   2939 
   2940 void DecimalFormat::setMaximumSignificantDigits(int32_t max) {
   2941     if (max < 1) {
   2942         max = 1;
   2943     }
   2944     // pin min sig dig to 1..max
   2945     U_ASSERT(fImpl->fMinSigDigits >= 1);
   2946     int32_t min = _min(fImpl->fMinSigDigits, max);
   2947     fImpl->setMinMaxSignificantDigits(min, max);
   2948 }
   2949 
   2950 UBool DecimalFormat::areSignificantDigitsUsed() const {
   2951     return fImpl->areSignificantDigitsUsed();
   2952 }
   2953 
   2954 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
   2955     fImpl->setSignificantDigitsUsed(useSignificantDigits);
   2956 }
   2957 
   2958 void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
   2959     // set the currency before compute affixes to get the right currency names
   2960     NumberFormat::setCurrency(theCurrency, ec);
   2961     fImpl->updateCurrency(ec);
   2962 }
   2963 
   2964 void DecimalFormat::setCurrencyUsage(UCurrencyUsage newContext, UErrorCode* ec){
   2965     fImpl->setCurrencyUsage(newContext, *ec);
   2966 }
   2967 
   2968 UCurrencyUsage DecimalFormat::getCurrencyUsage() const {
   2969     return fImpl->getCurrencyUsage();
   2970 }
   2971 
   2972 // Deprecated variant with no UErrorCode parameter
   2973 void DecimalFormat::setCurrency(const UChar* theCurrency) {
   2974     UErrorCode ec = U_ZERO_ERROR;
   2975     setCurrency(theCurrency, ec);
   2976 }
   2977 
   2978 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
   2979     if (fImpl->fSymbols == NULL) {
   2980         ec = U_MEMORY_ALLOCATION_ERROR;
   2981         return;
   2982     }
   2983     ec = U_ZERO_ERROR;
   2984     const UChar* c = getCurrency();
   2985     if (*c == 0) {
   2986         const UnicodeString &intl =
   2987             fImpl->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
   2988         c = intl.getBuffer(); // ok for intl to go out of scope
   2989     }
   2990     u_strncpy(result, c, 3);
   2991     result[3] = 0;
   2992 }
   2993 
   2994 Hashtable*
   2995 DecimalFormat::initHashForAffixPattern(UErrorCode& status) {
   2996     if ( U_FAILURE(status) ) {
   2997         return NULL;
   2998     }
   2999     Hashtable* hTable;
   3000     if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
   3001         status = U_MEMORY_ALLOCATION_ERROR;
   3002         return NULL;
   3003     }
   3004     if ( U_FAILURE(status) ) {
   3005         delete hTable;
   3006         return NULL;
   3007     }
   3008     hTable->setValueComparator(decimfmtAffixPatternValueComparator);
   3009     return hTable;
   3010 }
   3011 
   3012 void
   3013 DecimalFormat::deleteHashForAffixPattern()
   3014 {
   3015     if ( fAffixPatternsForCurrency == NULL ) {
   3016         return;
   3017     }
   3018     int32_t pos = UHASH_FIRST;
   3019     const UHashElement* element = NULL;
   3020     while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
   3021         const UHashTok valueTok = element->value;
   3022         const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
   3023         delete value;
   3024     }
   3025     delete fAffixPatternsForCurrency;
   3026     fAffixPatternsForCurrency = NULL;
   3027 }
   3028 
   3029 
   3030 void
   3031 DecimalFormat::copyHashForAffixPattern(const Hashtable* source,
   3032                                        Hashtable* target,
   3033                                        UErrorCode& status) {
   3034     if ( U_FAILURE(status) ) {
   3035         return;
   3036     }
   3037     int32_t pos = UHASH_FIRST;
   3038     const UHashElement* element = NULL;
   3039     if ( source ) {
   3040         while ( (element = source->nextElement(pos)) != NULL ) {
   3041             const UHashTok keyTok = element->key;
   3042             const UnicodeString* key = (UnicodeString*)keyTok.pointer;
   3043             const UHashTok valueTok = element->value;
   3044             const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
   3045             AffixPatternsForCurrency* copy = new AffixPatternsForCurrency(
   3046                 value->negPrefixPatternForCurrency,
   3047                 value->negSuffixPatternForCurrency,
   3048                 value->posPrefixPatternForCurrency,
   3049                 value->posSuffixPatternForCurrency,
   3050                 value->patternType);
   3051             target->put(UnicodeString(*key), copy, status);
   3052             if ( U_FAILURE(status) ) {
   3053                 return;
   3054             }
   3055         }
   3056     }
   3057 }
   3058 
   3059 void
   3060 DecimalFormat::setGroupingUsed(UBool newValue) {
   3061   NumberFormat::setGroupingUsed(newValue);
   3062   fImpl->updateGrouping();
   3063 }
   3064 
   3065 void
   3066 DecimalFormat::setParseIntegerOnly(UBool newValue) {
   3067   NumberFormat::setParseIntegerOnly(newValue);
   3068 }
   3069 
   3070 void
   3071 DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) {
   3072   NumberFormat::setContext(value, status);
   3073 }
   3074 
   3075 DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr,
   3076                                             int32_t newValue,
   3077                                             UErrorCode &status) {
   3078   if(U_FAILURE(status)) return *this;
   3079 
   3080   switch(attr) {
   3081   case UNUM_LENIENT_PARSE:
   3082     setLenient(newValue!=0);
   3083     break;
   3084 
   3085     case UNUM_PARSE_INT_ONLY:
   3086       setParseIntegerOnly(newValue!=0);
   3087       break;
   3088 
   3089     case UNUM_GROUPING_USED:
   3090       setGroupingUsed(newValue!=0);
   3091       break;
   3092 
   3093     case UNUM_DECIMAL_ALWAYS_SHOWN:
   3094       setDecimalSeparatorAlwaysShown(newValue!=0);
   3095         break;
   3096 
   3097     case UNUM_MAX_INTEGER_DIGITS:
   3098       setMaximumIntegerDigits(newValue);
   3099         break;
   3100 
   3101     case UNUM_MIN_INTEGER_DIGITS:
   3102       setMinimumIntegerDigits(newValue);
   3103         break;
   3104 
   3105     case UNUM_INTEGER_DIGITS:
   3106       setMinimumIntegerDigits(newValue);
   3107       setMaximumIntegerDigits(newValue);
   3108         break;
   3109 
   3110     case UNUM_MAX_FRACTION_DIGITS:
   3111       setMaximumFractionDigits(newValue);
   3112         break;
   3113 
   3114     case UNUM_MIN_FRACTION_DIGITS:
   3115       setMinimumFractionDigits(newValue);
   3116         break;
   3117 
   3118     case UNUM_FRACTION_DIGITS:
   3119       setMinimumFractionDigits(newValue);
   3120       setMaximumFractionDigits(newValue);
   3121       break;
   3122 
   3123     case UNUM_SIGNIFICANT_DIGITS_USED:
   3124       setSignificantDigitsUsed(newValue!=0);
   3125         break;
   3126 
   3127     case UNUM_MAX_SIGNIFICANT_DIGITS:
   3128       setMaximumSignificantDigits(newValue);
   3129         break;
   3130 
   3131     case UNUM_MIN_SIGNIFICANT_DIGITS:
   3132       setMinimumSignificantDigits(newValue);
   3133         break;
   3134 
   3135     case UNUM_MULTIPLIER:
   3136       setMultiplier(newValue);
   3137        break;
   3138 
   3139     case UNUM_GROUPING_SIZE:
   3140       setGroupingSize(newValue);
   3141         break;
   3142 
   3143     case UNUM_ROUNDING_MODE:
   3144       setRoundingMode((DecimalFormat::ERoundingMode)newValue);
   3145         break;
   3146 
   3147     case UNUM_FORMAT_WIDTH:
   3148       setFormatWidth(newValue);
   3149         break;
   3150 
   3151     case UNUM_PADDING_POSITION:
   3152         /** The position at which padding will take place. */
   3153       setPadPosition((DecimalFormat::EPadPosition)newValue);
   3154         break;
   3155 
   3156     case UNUM_SECONDARY_GROUPING_SIZE:
   3157       setSecondaryGroupingSize(newValue);
   3158         break;
   3159 
   3160 #if UCONFIG_HAVE_PARSEALLINPUT
   3161     case UNUM_PARSE_ALL_INPUT:
   3162       setParseAllInput((UNumberFormatAttributeValue)newValue);
   3163         break;
   3164 #endif
   3165 
   3166     /* These are stored in fBoolFlags */
   3167     case UNUM_PARSE_NO_EXPONENT:
   3168     case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
   3169     case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
   3170       if(!fBoolFlags.isValidValue(newValue)) {
   3171           status = U_ILLEGAL_ARGUMENT_ERROR;
   3172       } else {
   3173           if (attr == UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS) {
   3174               fImpl->setFailIfMoreThanMaxDigits((UBool) newValue);
   3175           }
   3176           fBoolFlags.set(attr, newValue);
   3177       }
   3178       break;
   3179 
   3180     case UNUM_SCALE:
   3181         fImpl->setScale(newValue);
   3182         break;
   3183 
   3184     case UNUM_CURRENCY_USAGE:
   3185         setCurrencyUsage((UCurrencyUsage)newValue, &status);
   3186         break;
   3187 
   3188     case UNUM_MINIMUM_GROUPING_DIGITS:
   3189         setMinimumGroupingDigits(newValue);
   3190         break;
   3191 
   3192     default:
   3193       status = U_UNSUPPORTED_ERROR;
   3194       break;
   3195   }
   3196   return *this;
   3197 }
   3198 
   3199 int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr,
   3200                                      UErrorCode &status ) const {
   3201   if(U_FAILURE(status)) return -1;
   3202   switch(attr) {
   3203     case UNUM_LENIENT_PARSE:
   3204         return isLenient();
   3205 
   3206     case UNUM_PARSE_INT_ONLY:
   3207         return isParseIntegerOnly();
   3208 
   3209     case UNUM_GROUPING_USED:
   3210         return isGroupingUsed();
   3211 
   3212     case UNUM_DECIMAL_ALWAYS_SHOWN:
   3213         return isDecimalSeparatorAlwaysShown();
   3214 
   3215     case UNUM_MAX_INTEGER_DIGITS:
   3216         return getMaximumIntegerDigits();
   3217 
   3218     case UNUM_MIN_INTEGER_DIGITS:
   3219         return getMinimumIntegerDigits();
   3220 
   3221     case UNUM_INTEGER_DIGITS:
   3222         // TBD: what should this return?
   3223         return getMinimumIntegerDigits();
   3224 
   3225     case UNUM_MAX_FRACTION_DIGITS:
   3226         return getMaximumFractionDigits();
   3227 
   3228     case UNUM_MIN_FRACTION_DIGITS:
   3229         return getMinimumFractionDigits();
   3230 
   3231     case UNUM_FRACTION_DIGITS:
   3232         // TBD: what should this return?
   3233         return getMinimumFractionDigits();
   3234 
   3235     case UNUM_SIGNIFICANT_DIGITS_USED:
   3236         return areSignificantDigitsUsed();
   3237 
   3238     case UNUM_MAX_SIGNIFICANT_DIGITS:
   3239         return getMaximumSignificantDigits();
   3240 
   3241     case UNUM_MIN_SIGNIFICANT_DIGITS:
   3242         return getMinimumSignificantDigits();
   3243 
   3244     case UNUM_MULTIPLIER:
   3245         return getMultiplier();
   3246 
   3247     case UNUM_GROUPING_SIZE:
   3248         return getGroupingSize();
   3249 
   3250     case UNUM_ROUNDING_MODE:
   3251         return getRoundingMode();
   3252 
   3253     case UNUM_FORMAT_WIDTH:
   3254         return getFormatWidth();
   3255 
   3256     case UNUM_PADDING_POSITION:
   3257         return getPadPosition();
   3258 
   3259     case UNUM_SECONDARY_GROUPING_SIZE:
   3260         return getSecondaryGroupingSize();
   3261 
   3262     /* These are stored in fBoolFlags */
   3263     case UNUM_PARSE_NO_EXPONENT:
   3264     case UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS:
   3265     case UNUM_PARSE_DECIMAL_MARK_REQUIRED:
   3266       return fBoolFlags.get(attr);
   3267 
   3268     case UNUM_SCALE:
   3269         return fImpl->fScale;
   3270 
   3271     case UNUM_CURRENCY_USAGE:
   3272         return fImpl->getCurrencyUsage();
   3273 
   3274     case UNUM_MINIMUM_GROUPING_DIGITS:
   3275         return getMinimumGroupingDigits();
   3276 
   3277     default:
   3278         status = U_UNSUPPORTED_ERROR;
   3279         break;
   3280   }
   3281 
   3282   return -1; /* undefined */
   3283 }
   3284 
   3285 #if UCONFIG_HAVE_PARSEALLINPUT
   3286 void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
   3287   fParseAllInput = value;
   3288 }
   3289 #endif
   3290 
   3291 U_NAMESPACE_END
   3292 
   3293 #endif /* #if !UCONFIG_NO_FORMATTING */
   3294 
   3295 //eof
   3296