Home | History | Annotate | Download | only in i18n
      1 /*
      2 *******************************************************************************
      3 * Copyright (C) 1997-2015, International Business Machines Corporation and
      4 * others. All Rights Reserved.
      5 *******************************************************************************
      6 *
      7 * File NUMFMT.CPP
      8 *
      9 * Modification History:
     10 *
     11 *   Date        Name        Description
     12 *   02/19/97    aliu        Converted from java.
     13 *   03/18/97    clhuang     Implemented with C++ APIs.
     14 *   04/17/97    aliu        Enlarged MAX_INTEGER_DIGITS to fully accomodate the
     15 *                           largest double, by default.
     16 *                           Changed DigitCount to int per code review.
     17 *    07/20/98    stephen        Changed operator== to check for grouping
     18 *                            Changed setMaxIntegerDigits per Java implementation.
     19 *                            Changed setMinIntegerDigits per Java implementation.
     20 *                            Changed setMinFractionDigits per Java implementation.
     21 *                            Changed setMaxFractionDigits per Java implementation.
     22 ********************************************************************************
     23 */
     24 
     25 #include "unicode/utypes.h"
     26 
     27 #if !UCONFIG_NO_FORMATTING
     28 
     29 #include "unicode/numfmt.h"
     30 #include "unicode/locid.h"
     31 #include "unicode/dcfmtsym.h"
     32 #include "unicode/decimfmt.h"
     33 #include "unicode/ustring.h"
     34 #include "unicode/ucurr.h"
     35 #include "unicode/curramt.h"
     36 #include "unicode/numsys.h"
     37 #include "unicode/rbnf.h"
     38 #include "unicode/localpointer.h"
     39 #include "unicode/udisplaycontext.h"
     40 #include "charstr.h"
     41 #include "winnmfmt.h"
     42 #include "uresimp.h"
     43 #include "uhash.h"
     44 #include "cmemory.h"
     45 #include "servloc.h"
     46 #include "ucln_in.h"
     47 #include "cstring.h"
     48 #include "putilimp.h"
     49 #include "uassert.h"
     50 #include "umutex.h"
     51 #include "mutex.h"
     52 #include "digitlst.h"
     53 #include <float.h>
     54 #include "sharednumberformat.h"
     55 #include "unifiedcache.h"
     56 
     57 //#define FMT_DEBUG
     58 
     59 #ifdef FMT_DEBUG
     60 #include <stdio.h>
     61 static inline void debugout(UnicodeString s) {
     62     char buf[2000];
     63     s.extract((int32_t) 0, s.length(), buf);
     64     printf("%s", buf);
     65 }
     66 #define debug(x) printf("%s", x);
     67 #else
     68 #define debugout(x)
     69 #define debug(x)
     70 #endif
     71 
     72 // If no number pattern can be located for a locale, this is the last
     73 // resort. The patterns are same as the ones in root locale.
     74 static const UChar gLastResortDecimalPat[] = {
     75     0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0 /* "#,##0.###" */
     76 };
     77 static const UChar gLastResortCurrencyPat[] = {
     78     0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u00A4\u00A0#,##0.00" */
     79 };
     80 static const UChar gLastResortPercentPat[] = {
     81     0x23, 0x2C, 0x23, 0x23, 0x30, 0x25, 0 /* "#,##0%" */
     82 };
     83 static const UChar gLastResortScientificPat[] = {
     84     0x23, 0x45, 0x30, 0 /* "#E0" */
     85 };
     86 static const UChar gLastResortIsoCurrencyPat[] = {
     87     0xA4, 0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0  /* "\u00A4\u00A4\u00A0#,##0.00" */
     88 };
     89 static const UChar gLastResortPluralCurrencyPat[] = {
     90     0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x20, 0xA4, 0xA4, 0xA4, 0 /* "#,##0.### \u00A4\u00A4\u00A4*/
     91 };
     92 static const UChar gLastResortAccountingCurrencyPat[] =  {
     93     0xA4, 0xA0, 0x23, 0x2C, 0x23, 0x23, 0x30, 0x2E, 0x30, 0x30, 0 /* "\u00A4\u00A0#,##0.00" */
     94 };
     95 
     96 static const UChar gSingleCurrencySign[] = {0xA4, 0};
     97 static const UChar gDoubleCurrencySign[] = {0xA4, 0xA4, 0};
     98 
     99 static const UChar gSlash = 0x2f;
    100 
    101 // If the maximum base 10 exponent were 4, then the largest number would
    102 // be 99,999 which has 5 digits.
    103 // On IEEE754 systems gMaxIntegerDigits is 308 + possible denormalized 15 digits + rounding digit
    104 // With big decimal, the max exponent is 999,999,999 and the max number of digits is the same, 999,999,999
    105 const int32_t icu::NumberFormat::gDefaultMaxIntegerDigits = 2000000000;
    106 const int32_t icu::NumberFormat::gDefaultMinIntegerDigits = 127;
    107 
    108 static const UChar * const gLastResortNumberPatterns[UNUM_FORMAT_STYLE_COUNT] = {
    109     NULL,  // UNUM_PATTERN_DECIMAL
    110     gLastResortDecimalPat,  // UNUM_DECIMAL
    111     gLastResortCurrencyPat,  // UNUM_CURRENCY
    112     gLastResortPercentPat,  // UNUM_PERCENT
    113     gLastResortScientificPat,  // UNUM_SCIENTIFIC
    114     NULL,  // UNUM_SPELLOUT
    115     NULL,  // UNUM_ORDINAL
    116     NULL,  // UNUM_DURATION
    117     NULL,  // UNUM_NUMBERING_SYSTEM
    118     NULL,  // UNUM_PATTERN_RULEBASED
    119     gLastResortIsoCurrencyPat,  // UNUM_CURRENCY_ISO
    120     gLastResortPluralCurrencyPat,  // UNUM_CURRENCY_PLURAL
    121     gLastResortAccountingCurrencyPat, // UNUM_CURRENCY_ACCOUNTING
    122     gLastResortCurrencyPat,  // UNUM_CASH_CURRENCY
    123     NULL,  // UNUM_DECIMAL_COMPACT_SHORT
    124     NULL,  // UNUM_DECIMAL_COMPACT_LONG
    125     gLastResortCurrencyPat,  // UNUM_CURRENCY_STANDARD
    126 };
    127 
    128 // Keys used for accessing resource bundles
    129 
    130 static const char *gNumberElements = "NumberElements";
    131 static const char *gLatn = "latn";
    132 static const char *gPatterns = "patterns";
    133 static const char *gFormatKeys[UNUM_FORMAT_STYLE_COUNT] = {
    134     NULL,  // UNUM_PATTERN_DECIMAL
    135     "decimalFormat",  // UNUM_DECIMAL
    136     "currencyFormat",  // UNUM_CURRENCY
    137     "percentFormat",  // UNUM_PERCENT
    138     "scientificFormat",  // UNUM_SCIENTIFIC
    139     NULL,  // UNUM_SPELLOUT
    140     NULL,  // UNUM_ORDINAL
    141     NULL,  // UNUM_DURATION
    142     NULL,  // UNUM_NUMBERING_SYSTEM
    143     NULL,  // UNUM_PATTERN_RULEBASED
    144     // For UNUM_CURRENCY_ISO and UNUM_CURRENCY_PLURAL,
    145     // the pattern is the same as the pattern of UNUM_CURRENCY
    146     // except for replacing the single currency sign with
    147     // double currency sign or triple currency sign.
    148     "currencyFormat",  // UNUM_CURRENCY_ISO
    149     "currencyFormat",  // UNUM_CURRENCY_PLURAL
    150     "accountingFormat",  // UNUM_CURRENCY_ACCOUNTING
    151     "currencyFormat",  // UNUM_CASH_CURRENCY
    152     NULL,  // UNUM_DECIMAL_COMPACT_SHORT
    153     NULL,  // UNUM_DECIMAL_COMPACT_LONG
    154     "currencyFormat",  // UNUM_CURRENCY_STANDARD
    155 };
    156 
    157 // Static hashtable cache of NumberingSystem objects used by NumberFormat
    158 static UHashtable * NumberingSystem_cache = NULL;
    159 static UMutex nscacheMutex = U_MUTEX_INITIALIZER;
    160 static icu::UInitOnce gNSCacheInitOnce = U_INITONCE_INITIALIZER;
    161 
    162 #if !UCONFIG_NO_SERVICE
    163 static icu::ICULocaleService* gService = NULL;
    164 static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER;
    165 #endif
    166 
    167 /**
    168  * Release all static memory held by Number Format.
    169  */
    170 U_CDECL_BEGIN
    171 static void U_CALLCONV
    172 deleteNumberingSystem(void *obj) {
    173     delete (icu::NumberingSystem *)obj;
    174 }
    175 
    176 static UBool U_CALLCONV numfmt_cleanup(void) {
    177 #if !UCONFIG_NO_SERVICE
    178     gServiceInitOnce.reset();
    179     if (gService) {
    180         delete gService;
    181         gService = NULL;
    182     }
    183 #endif
    184     gNSCacheInitOnce.reset();
    185     if (NumberingSystem_cache) {
    186         // delete NumberingSystem_cache;
    187         uhash_close(NumberingSystem_cache);
    188         NumberingSystem_cache = NULL;
    189     }
    190     return TRUE;
    191 }
    192 U_CDECL_END
    193 
    194 // *****************************************************************************
    195 // class NumberFormat
    196 // *****************************************************************************
    197 
    198 U_NAMESPACE_BEGIN
    199 
    200 UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(NumberFormat)
    201 
    202 #if !UCONFIG_NO_SERVICE
    203 // -------------------------------------
    204 // SimpleNumberFormatFactory implementation
    205 NumberFormatFactory::~NumberFormatFactory() {}
    206 SimpleNumberFormatFactory::SimpleNumberFormatFactory(const Locale& locale, UBool visible)
    207     : _visible(visible)
    208 {
    209     LocaleUtility::initNameFromLocale(locale, _id);
    210 }
    211 
    212 SimpleNumberFormatFactory::~SimpleNumberFormatFactory() {}
    213 
    214 UBool SimpleNumberFormatFactory::visible(void) const {
    215     return _visible;
    216 }
    217 
    218 const UnicodeString *
    219 SimpleNumberFormatFactory::getSupportedIDs(int32_t &count, UErrorCode& status) const
    220 {
    221     if (U_SUCCESS(status)) {
    222         count = 1;
    223         return &_id;
    224     }
    225     count = 0;
    226     return NULL;
    227 }
    228 #endif /* #if !UCONFIG_NO_SERVICE */
    229 
    230 // -------------------------------------
    231 // default constructor
    232 NumberFormat::NumberFormat()
    233 :   fGroupingUsed(TRUE),
    234     fMaxIntegerDigits(gDefaultMaxIntegerDigits),
    235     fMinIntegerDigits(1),
    236     fMaxFractionDigits(3), // invariant, >= minFractionDigits
    237     fMinFractionDigits(0),
    238     fParseIntegerOnly(FALSE),
    239     fLenient(FALSE),
    240     fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
    241 {
    242     fCurrency[0] = 0;
    243 }
    244 
    245 // -------------------------------------
    246 
    247 NumberFormat::~NumberFormat()
    248 {
    249 }
    250 
    251 SharedNumberFormat::~SharedNumberFormat() {
    252     delete ptr;
    253 }
    254 
    255 // -------------------------------------
    256 // copy constructor
    257 
    258 NumberFormat::NumberFormat(const NumberFormat &source)
    259 :   Format(source)
    260 {
    261     *this = source;
    262 }
    263 
    264 // -------------------------------------
    265 // assignment operator
    266 
    267 NumberFormat&
    268 NumberFormat::operator=(const NumberFormat& rhs)
    269 {
    270     if (this != &rhs)
    271     {
    272         Format::operator=(rhs);
    273         fGroupingUsed = rhs.fGroupingUsed;
    274         fMaxIntegerDigits = rhs.fMaxIntegerDigits;
    275         fMinIntegerDigits = rhs.fMinIntegerDigits;
    276         fMaxFractionDigits = rhs.fMaxFractionDigits;
    277         fMinFractionDigits = rhs.fMinFractionDigits;
    278         fParseIntegerOnly = rhs.fParseIntegerOnly;
    279         u_strncpy(fCurrency, rhs.fCurrency, 4);
    280         fLenient = rhs.fLenient;
    281         fCapitalizationContext = rhs.fCapitalizationContext;
    282     }
    283     return *this;
    284 }
    285 
    286 // -------------------------------------
    287 
    288 UBool
    289 NumberFormat::operator==(const Format& that) const
    290 {
    291     // Format::operator== guarantees this cast is safe
    292     NumberFormat* other = (NumberFormat*)&that;
    293 
    294 #ifdef FMT_DEBUG
    295     // This code makes it easy to determine why two format objects that should
    296     // be equal aren't.
    297     UBool first = TRUE;
    298     if (!Format::operator==(that)) {
    299         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    300         debug("Format::!=");
    301     }
    302     if (!(fMaxIntegerDigits == other->fMaxIntegerDigits &&
    303           fMinIntegerDigits == other->fMinIntegerDigits)) {
    304         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    305         debug("Integer digits !=");
    306     }
    307     if (!(fMaxFractionDigits == other->fMaxFractionDigits &&
    308           fMinFractionDigits == other->fMinFractionDigits)) {
    309         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    310         debug("Fraction digits !=");
    311     }
    312     if (!(fGroupingUsed == other->fGroupingUsed)) {
    313         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    314         debug("fGroupingUsed != ");
    315     }
    316     if (!(fParseIntegerOnly == other->fParseIntegerOnly)) {
    317         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    318         debug("fParseIntegerOnly != ");
    319     }
    320     if (!(u_strcmp(fCurrency, other->fCurrency) == 0)) {
    321         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    322         debug("fCurrency !=");
    323     }
    324     if (!(fLenient == other->fLenient)) {
    325         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    326         debug("fLenient != ");
    327     }
    328     if (!(fCapitalizationContext == other->fCapitalizationContext)) {
    329         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
    330         debug("fCapitalizationContext != ");
    331     }
    332     if (!first) { printf(" ]"); }
    333 #endif
    334 
    335     return ((this == &that) ||
    336             ((Format::operator==(that) &&
    337               fMaxIntegerDigits == other->fMaxIntegerDigits &&
    338               fMinIntegerDigits == other->fMinIntegerDigits &&
    339               fMaxFractionDigits == other->fMaxFractionDigits &&
    340               fMinFractionDigits == other->fMinFractionDigits &&
    341               fGroupingUsed == other->fGroupingUsed &&
    342               fParseIntegerOnly == other->fParseIntegerOnly &&
    343               u_strcmp(fCurrency, other->fCurrency) == 0 &&
    344               fLenient == other->fLenient &&
    345               fCapitalizationContext == other->fCapitalizationContext)));
    346 }
    347 
    348 // -------------------------------------
    349 // Default implementation sets unsupported error; subclasses should
    350 // override.
    351 
    352 UnicodeString&
    353 NumberFormat::format(double /* unused number */,
    354                      UnicodeString& toAppendTo,
    355                      FieldPositionIterator* /* unused posIter */,
    356                      UErrorCode& status) const
    357 {
    358     if (!U_FAILURE(status)) {
    359         status = U_UNSUPPORTED_ERROR;
    360     }
    361     return toAppendTo;
    362 }
    363 
    364 // -------------------------------------
    365 // Default implementation sets unsupported error; subclasses should
    366 // override.
    367 
    368 UnicodeString&
    369 NumberFormat::format(int32_t /* unused number */,
    370                      UnicodeString& toAppendTo,
    371                      FieldPositionIterator* /* unused posIter */,
    372                      UErrorCode& status) const
    373 {
    374     if (!U_FAILURE(status)) {
    375         status = U_UNSUPPORTED_ERROR;
    376     }
    377     return toAppendTo;
    378 }
    379 
    380 // -------------------------------------
    381 // Default implementation sets unsupported error; subclasses should
    382 // override.
    383 
    384 UnicodeString&
    385 NumberFormat::format(int64_t /* unused number */,
    386                      UnicodeString& toAppendTo,
    387                      FieldPositionIterator* /* unused posIter */,
    388                      UErrorCode& status) const
    389 {
    390     if (!U_FAILURE(status)) {
    391         status = U_UNSUPPORTED_ERROR;
    392     }
    393     return toAppendTo;
    394 }
    395 
    396 // ------------------------------------------
    397 // These functions add the status code, just fall back to the non-status versions
    398 UnicodeString&
    399 NumberFormat::format(double number,
    400                      UnicodeString& appendTo,
    401                      FieldPosition& pos,
    402                      UErrorCode &status) const {
    403     if(U_SUCCESS(status)) {
    404         return format(number,appendTo,pos);
    405     } else {
    406         return appendTo;
    407     }
    408 }
    409 
    410 UnicodeString&
    411 NumberFormat::format(int32_t number,
    412                      UnicodeString& appendTo,
    413                      FieldPosition& pos,
    414                      UErrorCode &status) const {
    415     if(U_SUCCESS(status)) {
    416         return format(number,appendTo,pos);
    417     } else {
    418         return appendTo;
    419     }
    420 }
    421 
    422 UnicodeString&
    423 NumberFormat::format(int64_t number,
    424                      UnicodeString& appendTo,
    425                      FieldPosition& pos,
    426                      UErrorCode &status) const {
    427     if(U_SUCCESS(status)) {
    428         return format(number,appendTo,pos);
    429     } else {
    430         return appendTo;
    431     }
    432 }
    433 
    434 
    435 
    436 // -------------------------------------
    437 // Decimal Number format() default implementation
    438 // Subclasses do not normally override this function, but rather the DigitList
    439 // formatting functions..
    440 //   The expected call chain from here is
    441 //      this function ->
    442 //      NumberFormat::format(Formattable  ->
    443 //      DecimalFormat::format(DigitList
    444 //
    445 //   Or, for subclasses of Formattable that do not know about DigitList,
    446 //       this Function ->
    447 //       NumberFormat::format(Formattable  ->
    448 //       NumberFormat::format(DigitList  ->
    449 //       XXXFormat::format(double
    450 
    451 UnicodeString&
    452 NumberFormat::format(const StringPiece &decimalNum,
    453                      UnicodeString& toAppendTo,
    454                      FieldPositionIterator* fpi,
    455                      UErrorCode& status) const
    456 {
    457     Formattable f;
    458     f.setDecimalNumber(decimalNum, status);
    459     format(f, toAppendTo, fpi, status);
    460     return toAppendTo;
    461 }
    462 
    463 /**
    464  *
    465 // Formats the number object and save the format
    466 // result in the toAppendTo string buffer.
    467 
    468 // utility to save/restore state, used in two overloads
    469 // of format(const Formattable&...) below.
    470 *
    471 * Old purpose of ArgExtractor was to avoid const. Not thread safe!
    472 *
    473 * keeping it around as a shim.
    474 */
    475 class ArgExtractor {
    476   const Formattable* num;
    477   UChar save[4];
    478   UBool fWasCurrency;
    479 
    480  public:
    481   ArgExtractor(const NumberFormat& nf, const Formattable& obj, UErrorCode& status);
    482   ~ArgExtractor();
    483 
    484   const Formattable* number(void) const;
    485   const UChar *iso(void) const;
    486   UBool wasCurrency(void) const;
    487 };
    488 
    489 inline const Formattable*
    490 ArgExtractor::number(void) const {
    491   return num;
    492 }
    493 
    494 inline UBool
    495 ArgExtractor::wasCurrency(void) const {
    496   return fWasCurrency;
    497 }
    498 
    499 inline const UChar *
    500 ArgExtractor::iso(void) const {
    501   return save;
    502 }
    503 
    504 ArgExtractor::ArgExtractor(const NumberFormat& /*nf*/, const Formattable& obj, UErrorCode& /*status*/)
    505   : num(&obj), fWasCurrency(FALSE) {
    506 
    507     const UObject* o = obj.getObject(); // most commonly o==NULL
    508     const CurrencyAmount* amt;
    509     if (o != NULL && (amt = dynamic_cast<const CurrencyAmount*>(o)) != NULL) {
    510         // getISOCurrency() returns a pointer to internal storage, so we
    511         // copy it to retain it across the call to setCurrency().
    512         //const UChar* curr = amt->getISOCurrency();
    513         u_strcpy(save, amt->getISOCurrency());
    514         num = &amt->getNumber();
    515         fWasCurrency=TRUE;
    516     } else {
    517       save[0]=0;
    518     }
    519 }
    520 
    521 ArgExtractor::~ArgExtractor() {
    522 }
    523 
    524 UnicodeString& NumberFormat::format(const DigitList &number,
    525                       UnicodeString& appendTo,
    526                       FieldPositionIterator* posIter,
    527                       UErrorCode& status) const {
    528     // DecimalFormat overrides this function, and handles DigitList based big decimals.
    529     // Other subclasses (ChoiceFormat, RuleBasedNumberFormat) do not (yet) handle DigitLists,
    530     // so this default implementation falls back to formatting decimal numbers as doubles.
    531     if (U_FAILURE(status)) {
    532         return appendTo;
    533     }
    534     double dnum = number.getDouble();
    535     format(dnum, appendTo, posIter, status);
    536     return appendTo;
    537 }
    538 
    539 
    540 
    541 UnicodeString&
    542 NumberFormat::format(const DigitList &number,
    543                      UnicodeString& appendTo,
    544                      FieldPosition& pos,
    545                      UErrorCode &status) const {
    546     // DecimalFormat overrides this function, and handles DigitList based big decimals.
    547     // Other subclasses (ChoiceFormat, RuleBasedNumberFormat) do not (yet) handle DigitLists,
    548     // so this default implementation falls back to formatting decimal numbers as doubles.
    549     if (U_FAILURE(status)) {
    550         return appendTo;
    551     }
    552     double dnum = number.getDouble();
    553     format(dnum, appendTo, pos, status);
    554     return appendTo;
    555 }
    556 
    557 UnicodeString&
    558 NumberFormat::format(const Formattable& obj,
    559                         UnicodeString& appendTo,
    560                         FieldPosition& pos,
    561                         UErrorCode& status) const
    562 {
    563     if (U_FAILURE(status)) return appendTo;
    564 
    565     ArgExtractor arg(*this, obj, status);
    566     const Formattable *n = arg.number();
    567     const UChar *iso = arg.iso();
    568 
    569     if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) {
    570       // trying to format a different currency.
    571       // Right now, we clone.
    572       LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone());
    573       cloneFmt->setCurrency(iso, status);
    574       // next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount.
    575       return cloneFmt->format(*n, appendTo, pos, status);
    576     }
    577 
    578     if (n->isNumeric() && n->getDigitList() != NULL) {
    579         // Decimal Number.  We will have a DigitList available if the value was
    580         //   set to a decimal number, or if the value originated with a parse.
    581         //
    582         // The default implementation for formatting a DigitList converts it
    583         // to a double, and formats that, allowing formatting classes that don't
    584         // know about DigitList to continue to operate as they had.
    585         //
    586         // DecimalFormat overrides the DigitList formatting functions.
    587         format(*n->getDigitList(), appendTo, pos, status);
    588     } else {
    589         switch (n->getType()) {
    590         case Formattable::kDouble:
    591             format(n->getDouble(), appendTo, pos);
    592             break;
    593         case Formattable::kLong:
    594             format(n->getLong(), appendTo, pos);
    595             break;
    596         case Formattable::kInt64:
    597             format(n->getInt64(), appendTo, pos);
    598             break;
    599         default:
    600             status = U_INVALID_FORMAT_ERROR;
    601             break;
    602         }
    603     }
    604 
    605     return appendTo;
    606 }
    607 
    608 // -------------------------------------x
    609 // Formats the number object and save the format
    610 // result in the toAppendTo string buffer.
    611 
    612 UnicodeString&
    613 NumberFormat::format(const Formattable& obj,
    614                         UnicodeString& appendTo,
    615                         FieldPositionIterator* posIter,
    616                         UErrorCode& status) const
    617 {
    618     if (U_FAILURE(status)) return appendTo;
    619 
    620     ArgExtractor arg(*this, obj, status);
    621     const Formattable *n = arg.number();
    622     const UChar *iso = arg.iso();
    623 
    624     if(arg.wasCurrency() && u_strcmp(iso, getCurrency())) {
    625       // trying to format a different currency.
    626       // Right now, we clone.
    627       LocalPointer<NumberFormat> cloneFmt((NumberFormat*)this->clone());
    628       cloneFmt->setCurrency(iso, status);
    629       // next line should NOT recurse, because n is numeric whereas obj was a wrapper around currency amount.
    630       return cloneFmt->format(*n, appendTo, posIter, status);
    631     }
    632 
    633     if (n->isNumeric() && n->getDigitList() != NULL) {
    634         // Decimal Number
    635         format(*n->getDigitList(), appendTo, posIter, status);
    636     } else {
    637         switch (n->getType()) {
    638         case Formattable::kDouble:
    639             format(n->getDouble(), appendTo, posIter, status);
    640             break;
    641         case Formattable::kLong:
    642             format(n->getLong(), appendTo, posIter, status);
    643             break;
    644         case Formattable::kInt64:
    645             format(n->getInt64(), appendTo, posIter, status);
    646             break;
    647         default:
    648             status = U_INVALID_FORMAT_ERROR;
    649             break;
    650         }
    651     }
    652 
    653     return appendTo;
    654 }
    655 
    656 // -------------------------------------
    657 
    658 UnicodeString&
    659 NumberFormat::format(int64_t number,
    660                      UnicodeString& appendTo,
    661                      FieldPosition& pos) const
    662 {
    663     // default so we don't introduce a new abstract method
    664     return format((int32_t)number, appendTo, pos);
    665 }
    666 
    667 // -------------------------------------
    668 // Parses the string and save the result object as well
    669 // as the final parsed position.
    670 
    671 void
    672 NumberFormat::parseObject(const UnicodeString& source,
    673                              Formattable& result,
    674                              ParsePosition& parse_pos) const
    675 {
    676     parse(source, result, parse_pos);
    677 }
    678 
    679 // -------------------------------------
    680 // Formats a double number and save the result in a string.
    681 
    682 UnicodeString&
    683 NumberFormat::format(double number, UnicodeString& appendTo) const
    684 {
    685     FieldPosition pos(0);
    686     return format(number, appendTo, pos);
    687 }
    688 
    689 // -------------------------------------
    690 // Formats a long number and save the result in a string.
    691 
    692 UnicodeString&
    693 NumberFormat::format(int32_t number, UnicodeString& appendTo) const
    694 {
    695     FieldPosition pos(0);
    696     return format(number, appendTo, pos);
    697 }
    698 
    699 // -------------------------------------
    700 // Formats a long number and save the result in a string.
    701 
    702 UnicodeString&
    703 NumberFormat::format(int64_t number, UnicodeString& appendTo) const
    704 {
    705     FieldPosition pos(0);
    706     return format(number, appendTo, pos);
    707 }
    708 
    709 // -------------------------------------
    710 // Parses the text and save the result object.  If the returned
    711 // parse position is 0, that means the parsing failed, the status
    712 // code needs to be set to failure.  Ignores the returned parse
    713 // position, otherwise.
    714 
    715 void
    716 NumberFormat::parse(const UnicodeString& text,
    717                         Formattable& result,
    718                         UErrorCode& status) const
    719 {
    720     if (U_FAILURE(status)) return;
    721 
    722     ParsePosition parsePosition(0);
    723     parse(text, result, parsePosition);
    724     if (parsePosition.getIndex() == 0) {
    725         status = U_INVALID_FORMAT_ERROR;
    726     }
    727 }
    728 
    729 CurrencyAmount* NumberFormat::parseCurrency(const UnicodeString& text,
    730                                             ParsePosition& pos) const {
    731     // Default implementation only -- subclasses should override
    732     Formattable parseResult;
    733     int32_t start = pos.getIndex();
    734     parse(text, parseResult, pos);
    735     if (pos.getIndex() != start) {
    736         UChar curr[4];
    737         UErrorCode ec = U_ZERO_ERROR;
    738         getEffectiveCurrency(curr, ec);
    739         if (U_SUCCESS(ec)) {
    740             LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curr, ec), ec);
    741             if (U_FAILURE(ec)) {
    742                 pos.setIndex(start); // indicate failure
    743             } else {
    744                 return currAmt.orphan();
    745             }
    746         }
    747     }
    748     return NULL;
    749 }
    750 
    751 // -------------------------------------
    752 // Sets to only parse integers.
    753 
    754 void
    755 NumberFormat::setParseIntegerOnly(UBool value)
    756 {
    757     fParseIntegerOnly = value;
    758 }
    759 
    760 // -------------------------------------
    761 // Sets whether lenient parse is enabled.
    762 
    763 void
    764 NumberFormat::setLenient(UBool enable)
    765 {
    766     fLenient = enable;
    767 }
    768 
    769 // -------------------------------------
    770 // Create a number style NumberFormat instance with the default locale.
    771 
    772 NumberFormat* U_EXPORT2
    773 NumberFormat::createInstance(UErrorCode& status)
    774 {
    775     return createInstance(Locale::getDefault(), UNUM_DECIMAL, status);
    776 }
    777 
    778 // -------------------------------------
    779 // Create a number style NumberFormat instance with the inLocale locale.
    780 
    781 NumberFormat* U_EXPORT2
    782 NumberFormat::createInstance(const Locale& inLocale, UErrorCode& status)
    783 {
    784     return createInstance(inLocale, UNUM_DECIMAL, status);
    785 }
    786 
    787 // -------------------------------------
    788 // Create a currency style NumberFormat instance with the default locale.
    789 
    790 NumberFormat* U_EXPORT2
    791 NumberFormat::createCurrencyInstance(UErrorCode& status)
    792 {
    793     return createCurrencyInstance(Locale::getDefault(),  status);
    794 }
    795 
    796 // -------------------------------------
    797 // Create a currency style NumberFormat instance with the inLocale locale.
    798 
    799 NumberFormat* U_EXPORT2
    800 NumberFormat::createCurrencyInstance(const Locale& inLocale, UErrorCode& status)
    801 {
    802     return createInstance(inLocale, UNUM_CURRENCY, status);
    803 }
    804 
    805 // -------------------------------------
    806 // Create a percent style NumberFormat instance with the default locale.
    807 
    808 NumberFormat* U_EXPORT2
    809 NumberFormat::createPercentInstance(UErrorCode& status)
    810 {
    811     return createInstance(Locale::getDefault(), UNUM_PERCENT, status);
    812 }
    813 
    814 // -------------------------------------
    815 // Create a percent style NumberFormat instance with the inLocale locale.
    816 
    817 NumberFormat* U_EXPORT2
    818 NumberFormat::createPercentInstance(const Locale& inLocale, UErrorCode& status)
    819 {
    820     return createInstance(inLocale, UNUM_PERCENT, status);
    821 }
    822 
    823 // -------------------------------------
    824 // Create a scientific style NumberFormat instance with the default locale.
    825 
    826 NumberFormat* U_EXPORT2
    827 NumberFormat::createScientificInstance(UErrorCode& status)
    828 {
    829     return createInstance(Locale::getDefault(), UNUM_SCIENTIFIC, status);
    830 }
    831 
    832 // -------------------------------------
    833 // Create a scientific style NumberFormat instance with the inLocale locale.
    834 
    835 NumberFormat* U_EXPORT2
    836 NumberFormat::createScientificInstance(const Locale& inLocale, UErrorCode& status)
    837 {
    838     return createInstance(inLocale, UNUM_SCIENTIFIC, status);
    839 }
    840 
    841 // -------------------------------------
    842 
    843 const Locale* U_EXPORT2
    844 NumberFormat::getAvailableLocales(int32_t& count)
    845 {
    846     return Locale::getAvailableLocales(count);
    847 }
    848 
    849 // ------------------------------------------
    850 //
    851 // Registration
    852 //
    853 //-------------------------------------------
    854 
    855 #if !UCONFIG_NO_SERVICE
    856 
    857 // -------------------------------------
    858 
    859 class ICUNumberFormatFactory : public ICUResourceBundleFactory {
    860 public:
    861     virtual ~ICUNumberFormatFactory();
    862 protected:
    863     virtual UObject* handleCreate(const Locale& loc, int32_t kind, const ICUService* /* service */, UErrorCode& status) const {
    864         return NumberFormat::makeInstance(loc, (UNumberFormatStyle)kind, status);
    865     }
    866 };
    867 
    868 ICUNumberFormatFactory::~ICUNumberFormatFactory() {}
    869 
    870 // -------------------------------------
    871 
    872 class NFFactory : public LocaleKeyFactory {
    873 private:
    874     NumberFormatFactory* _delegate;
    875     Hashtable* _ids;
    876 
    877 public:
    878     NFFactory(NumberFormatFactory* delegate)
    879         : LocaleKeyFactory(delegate->visible() ? VISIBLE : INVISIBLE)
    880         , _delegate(delegate)
    881         , _ids(NULL)
    882     {
    883     }
    884 
    885     virtual ~NFFactory();
    886 
    887     virtual UObject* create(const ICUServiceKey& key, const ICUService* service, UErrorCode& status) const
    888     {
    889         if (handlesKey(key, status)) {
    890             const LocaleKey& lkey = (const LocaleKey&)key;
    891             Locale loc;
    892             lkey.canonicalLocale(loc);
    893             int32_t kind = lkey.kind();
    894 
    895             UObject* result = _delegate->createFormat(loc, (UNumberFormatStyle)kind);
    896             if (result == NULL) {
    897                 result = service->getKey((ICUServiceKey&)key /* cast away const */, NULL, this, status);
    898             }
    899             return result;
    900         }
    901         return NULL;
    902     }
    903 
    904 protected:
    905     /**
    906      * Return the set of ids that this factory supports (visible or
    907      * otherwise).  This can be called often and might need to be
    908      * cached if it is expensive to create.
    909      */
    910     virtual const Hashtable* getSupportedIDs(UErrorCode& status) const
    911     {
    912         if (U_SUCCESS(status)) {
    913             if (!_ids) {
    914                 int32_t count = 0;
    915                 const UnicodeString * const idlist = _delegate->getSupportedIDs(count, status);
    916                 ((NFFactory*)this)->_ids = new Hashtable(status); /* cast away const */
    917                 if (_ids) {
    918                     for (int i = 0; i < count; ++i) {
    919                         _ids->put(idlist[i], (void*)this, status);
    920                     }
    921                 }
    922             }
    923             return _ids;
    924         }
    925         return NULL;
    926     }
    927 };
    928 
    929 NFFactory::~NFFactory()
    930 {
    931     delete _delegate;
    932     delete _ids;
    933 }
    934 
    935 class ICUNumberFormatService : public ICULocaleService {
    936 public:
    937     ICUNumberFormatService()
    938         : ICULocaleService(UNICODE_STRING_SIMPLE("Number Format"))
    939     {
    940         UErrorCode status = U_ZERO_ERROR;
    941         registerFactory(new ICUNumberFormatFactory(), status);
    942     }
    943 
    944     virtual ~ICUNumberFormatService();
    945 
    946     virtual UObject* cloneInstance(UObject* instance) const {
    947         return ((NumberFormat*)instance)->clone();
    948     }
    949 
    950     virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* /* actualID */, UErrorCode& status) const {
    951         LocaleKey& lkey = (LocaleKey&)key;
    952         int32_t kind = lkey.kind();
    953         Locale loc;
    954         lkey.currentLocale(loc);
    955         return NumberFormat::makeInstance(loc, (UNumberFormatStyle)kind, status);
    956     }
    957 
    958     virtual UBool isDefault() const {
    959         return countFactories() == 1;
    960     }
    961 };
    962 
    963 ICUNumberFormatService::~ICUNumberFormatService() {}
    964 
    965 // -------------------------------------
    966 
    967 static void U_CALLCONV initNumberFormatService() {
    968     U_ASSERT(gService == NULL);
    969     ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
    970     gService = new ICUNumberFormatService();
    971 }
    972 
    973 static ICULocaleService*
    974 getNumberFormatService(void)
    975 {
    976     umtx_initOnce(gServiceInitOnce, &initNumberFormatService);
    977     return gService;
    978 }
    979 
    980 static UBool haveService() {
    981     return !gServiceInitOnce.isReset() && (getNumberFormatService() != NULL);
    982 }
    983 
    984 // -------------------------------------
    985 
    986 URegistryKey U_EXPORT2
    987 NumberFormat::registerFactory(NumberFormatFactory* toAdopt, UErrorCode& status)
    988 {
    989   ICULocaleService *service = getNumberFormatService();
    990   if (service) {
    991 	  NFFactory *tempnnf = new NFFactory(toAdopt);
    992 	  if (tempnnf != NULL) {
    993 		  return service->registerFactory(tempnnf, status);
    994 	  }
    995   }
    996   status = U_MEMORY_ALLOCATION_ERROR;
    997   return NULL;
    998 }
    999 
   1000 // -------------------------------------
   1001 
   1002 UBool U_EXPORT2
   1003 NumberFormat::unregister(URegistryKey key, UErrorCode& status)
   1004 {
   1005     if (U_FAILURE(status)) {
   1006         return FALSE;
   1007     }
   1008     if (haveService()) {
   1009         return gService->unregister(key, status);
   1010     } else {
   1011         status = U_ILLEGAL_ARGUMENT_ERROR;
   1012         return FALSE;
   1013     }
   1014 }
   1015 
   1016 // -------------------------------------
   1017 StringEnumeration* U_EXPORT2
   1018 NumberFormat::getAvailableLocales(void)
   1019 {
   1020   ICULocaleService *service = getNumberFormatService();
   1021   if (service) {
   1022       return service->getAvailableLocales();
   1023   }
   1024   return NULL; // no way to return error condition
   1025 }
   1026 #endif /* UCONFIG_NO_SERVICE */
   1027 // -------------------------------------
   1028 
   1029 enum { kKeyValueLenMax = 32 };
   1030 
   1031 NumberFormat*
   1032 NumberFormat::internalCreateInstance(const Locale& loc, UNumberFormatStyle kind, UErrorCode& status) {
   1033     if (kind == UNUM_CURRENCY) {
   1034         char cfKeyValue[kKeyValueLenMax] = {0};
   1035         UErrorCode kvStatus = U_ZERO_ERROR;
   1036         int32_t kLen = loc.getKeywordValue("cf", cfKeyValue, kKeyValueLenMax, kvStatus);
   1037         if (U_SUCCESS(kvStatus) && kLen > 0 && uprv_strcmp(cfKeyValue,"account")==0) {
   1038             kind = UNUM_CURRENCY_ACCOUNTING;
   1039         }
   1040     }
   1041 #if !UCONFIG_NO_SERVICE
   1042     if (haveService()) {
   1043         return (NumberFormat*)gService->get(loc, kind, status);
   1044     }
   1045 #endif
   1046     return makeInstance(loc, kind, status);
   1047 }
   1048 
   1049 NumberFormat* U_EXPORT2
   1050 NumberFormat::createInstance(const Locale& loc, UNumberFormatStyle kind, UErrorCode& status) {
   1051     if (kind != UNUM_DECIMAL) {
   1052         return internalCreateInstance(loc, kind, status);
   1053     }
   1054     const SharedNumberFormat *shared = createSharedInstance(loc, kind, status);
   1055     if (U_FAILURE(status)) {
   1056         return NULL;
   1057     }
   1058     NumberFormat *result = static_cast<NumberFormat *>((*shared)->clone());
   1059     shared->removeRef();
   1060     if (result == NULL) {
   1061         status = U_MEMORY_ALLOCATION_ERROR;
   1062     }
   1063     return result;
   1064 }
   1065 
   1066 
   1067 // -------------------------------------
   1068 // Checks if the thousand/10 thousand grouping is used in the
   1069 // NumberFormat instance.
   1070 
   1071 UBool
   1072 NumberFormat::isGroupingUsed() const
   1073 {
   1074     return fGroupingUsed;
   1075 }
   1076 
   1077 // -------------------------------------
   1078 // Sets to use the thousand/10 thousand grouping in the
   1079 // NumberFormat instance.
   1080 
   1081 void
   1082 NumberFormat::setGroupingUsed(UBool newValue)
   1083 {
   1084     fGroupingUsed = newValue;
   1085 }
   1086 
   1087 // -------------------------------------
   1088 // Gets the maximum number of digits for the integral part for
   1089 // this NumberFormat instance.
   1090 
   1091 int32_t NumberFormat::getMaximumIntegerDigits() const
   1092 {
   1093     return fMaxIntegerDigits;
   1094 }
   1095 
   1096 // -------------------------------------
   1097 // Sets the maximum number of digits for the integral part for
   1098 // this NumberFormat instance.
   1099 
   1100 void
   1101 NumberFormat::setMaximumIntegerDigits(int32_t newValue)
   1102 {
   1103     fMaxIntegerDigits = uprv_max(0, uprv_min(newValue, gDefaultMaxIntegerDigits));
   1104     if(fMinIntegerDigits > fMaxIntegerDigits)
   1105         fMinIntegerDigits = fMaxIntegerDigits;
   1106 }
   1107 
   1108 // -------------------------------------
   1109 // Gets the minimum number of digits for the integral part for
   1110 // this NumberFormat instance.
   1111 
   1112 int32_t
   1113 NumberFormat::getMinimumIntegerDigits() const
   1114 {
   1115     return fMinIntegerDigits;
   1116 }
   1117 
   1118 // -------------------------------------
   1119 // Sets the minimum number of digits for the integral part for
   1120 // this NumberFormat instance.
   1121 
   1122 void
   1123 NumberFormat::setMinimumIntegerDigits(int32_t newValue)
   1124 {
   1125     fMinIntegerDigits = uprv_max(0, uprv_min(newValue, gDefaultMinIntegerDigits));
   1126     if(fMinIntegerDigits > fMaxIntegerDigits)
   1127         fMaxIntegerDigits = fMinIntegerDigits;
   1128 }
   1129 
   1130 // -------------------------------------
   1131 // Gets the maximum number of digits for the fractional part for
   1132 // this NumberFormat instance.
   1133 
   1134 int32_t
   1135 NumberFormat::getMaximumFractionDigits() const
   1136 {
   1137     return fMaxFractionDigits;
   1138 }
   1139 
   1140 // -------------------------------------
   1141 // Sets the maximum number of digits for the fractional part for
   1142 // this NumberFormat instance.
   1143 
   1144 void
   1145 NumberFormat::setMaximumFractionDigits(int32_t newValue)
   1146 {
   1147     fMaxFractionDigits = uprv_max(0, uprv_min(newValue, gDefaultMaxIntegerDigits));
   1148     if(fMaxFractionDigits < fMinFractionDigits)
   1149         fMinFractionDigits = fMaxFractionDigits;
   1150 }
   1151 
   1152 // -------------------------------------
   1153 // Gets the minimum number of digits for the fractional part for
   1154 // this NumberFormat instance.
   1155 
   1156 int32_t
   1157 NumberFormat::getMinimumFractionDigits() const
   1158 {
   1159     return fMinFractionDigits;
   1160 }
   1161 
   1162 // -------------------------------------
   1163 // Sets the minimum number of digits for the fractional part for
   1164 // this NumberFormat instance.
   1165 
   1166 void
   1167 NumberFormat::setMinimumFractionDigits(int32_t newValue)
   1168 {
   1169     fMinFractionDigits = uprv_max(0, uprv_min(newValue, gDefaultMinIntegerDigits));
   1170     if (fMaxFractionDigits < fMinFractionDigits)
   1171         fMaxFractionDigits = fMinFractionDigits;
   1172 }
   1173 
   1174 // -------------------------------------
   1175 
   1176 void NumberFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
   1177     if (U_FAILURE(ec)) {
   1178         return;
   1179     }
   1180     if (theCurrency) {
   1181         u_strncpy(fCurrency, theCurrency, 3);
   1182         fCurrency[3] = 0;
   1183     } else {
   1184         fCurrency[0] = 0;
   1185     }
   1186 }
   1187 
   1188 const UChar* NumberFormat::getCurrency() const {
   1189     return fCurrency;
   1190 }
   1191 
   1192 void NumberFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
   1193     const UChar* c = getCurrency();
   1194     if (*c != 0) {
   1195         u_strncpy(result, c, 3);
   1196         result[3] = 0;
   1197     } else {
   1198         const char* loc = getLocaleID(ULOC_VALID_LOCALE, ec);
   1199         if (loc == NULL) {
   1200             loc = uloc_getDefault();
   1201         }
   1202         ucurr_forLocale(loc, result, 4, &ec);
   1203     }
   1204 }
   1205 
   1206 //----------------------------------------------------------------------
   1207 
   1208 
   1209 void NumberFormat::setContext(UDisplayContext value, UErrorCode& status)
   1210 {
   1211     if (U_FAILURE(status))
   1212         return;
   1213     if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
   1214         fCapitalizationContext = value;
   1215     } else {
   1216         status = U_ILLEGAL_ARGUMENT_ERROR;
   1217    }
   1218 }
   1219 
   1220 
   1221 UDisplayContext NumberFormat::getContext(UDisplayContextType type, UErrorCode& status) const
   1222 {
   1223     if (U_FAILURE(status))
   1224         return (UDisplayContext)0;
   1225     if (type != UDISPCTX_TYPE_CAPITALIZATION) {
   1226         status = U_ILLEGAL_ARGUMENT_ERROR;
   1227         return (UDisplayContext)0;
   1228     }
   1229     return fCapitalizationContext;
   1230 }
   1231 
   1232 
   1233 // -------------------------------------
   1234 // Creates the NumberFormat instance of the specified style (number, currency,
   1235 // or percent) for the desired locale.
   1236 
   1237 static void U_CALLCONV nscacheInit() {
   1238     U_ASSERT(NumberingSystem_cache == NULL);
   1239     ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT, numfmt_cleanup);
   1240     UErrorCode status = U_ZERO_ERROR;
   1241     NumberingSystem_cache = uhash_open(uhash_hashLong,
   1242                                        uhash_compareLong,
   1243                                        NULL,
   1244                                        &status);
   1245     if (U_FAILURE(status)) {
   1246         // Number Format code will run with no cache if creation fails.
   1247         NumberingSystem_cache = NULL;
   1248         return;
   1249     }
   1250     uhash_setValueDeleter(NumberingSystem_cache, deleteNumberingSystem);
   1251 }
   1252 
   1253 template<> U_I18N_API
   1254 const SharedNumberFormat *LocaleCacheKey<SharedNumberFormat>::createObject(
   1255         const void * /*unused*/, UErrorCode &status) const {
   1256     const char *localeId = fLoc.getName();
   1257     NumberFormat *nf = NumberFormat::internalCreateInstance(
   1258             localeId, UNUM_DECIMAL, status);
   1259     if (U_FAILURE(status)) {
   1260         return NULL;
   1261     }
   1262     SharedNumberFormat *result = new SharedNumberFormat(nf);
   1263     if (result == NULL) {
   1264         status = U_MEMORY_ALLOCATION_ERROR;
   1265         delete nf;
   1266         return NULL;
   1267     }
   1268     result->addRef();
   1269     return result;
   1270 }
   1271 
   1272 const SharedNumberFormat* U_EXPORT2
   1273 NumberFormat::createSharedInstance(const Locale& loc, UNumberFormatStyle kind, UErrorCode& status) {
   1274     if (U_FAILURE(status)) {
   1275         return NULL;
   1276     }
   1277     if (kind != UNUM_DECIMAL) {
   1278         status = U_UNSUPPORTED_ERROR;
   1279         return NULL;
   1280     }
   1281     const SharedNumberFormat *result = NULL;
   1282     UnifiedCache::getByLocale(loc, result, status);
   1283     return result;
   1284 }
   1285 
   1286 UBool
   1287 NumberFormat::isStyleSupported(UNumberFormatStyle style) {
   1288     return gLastResortNumberPatterns[style] != NULL;
   1289 }
   1290 
   1291 NumberFormat*
   1292 NumberFormat::makeInstance(const Locale& desiredLocale,
   1293                            UNumberFormatStyle style,
   1294                            UErrorCode& status) {
   1295   return makeInstance(desiredLocale, style, false, status);
   1296 }
   1297 
   1298 NumberFormat*
   1299 NumberFormat::makeInstance(const Locale& desiredLocale,
   1300                            UNumberFormatStyle style,
   1301                            UBool mustBeDecimalFormat,
   1302                            UErrorCode& status) {
   1303     if (U_FAILURE(status)) return NULL;
   1304 
   1305     if (style < 0 || style >= UNUM_FORMAT_STYLE_COUNT) {
   1306         status = U_ILLEGAL_ARGUMENT_ERROR;
   1307         return NULL;
   1308     }
   1309 
   1310     // Some styles are not supported. This is a result of merging
   1311     // the @draft ICU 4.2 NumberFormat::EStyles into the long-existing UNumberFormatStyle.
   1312     // Ticket #8503 is for reviewing/fixing/merging the two relevant implementations:
   1313     // this one and unum_open().
   1314     // The UNUM_PATTERN_ styles are not supported here
   1315     // because this method does not take a pattern string.
   1316     if (!isStyleSupported(style)) {
   1317         status = U_UNSUPPORTED_ERROR;
   1318         return NULL;
   1319     }
   1320 
   1321 #if U_PLATFORM_USES_ONLY_WIN32_API
   1322     if (!mustBeDecimalFormat) {
   1323         char buffer[8];
   1324         int32_t count = desiredLocale.getKeywordValue("compat", buffer, sizeof(buffer), status);
   1325 
   1326         // if the locale has "@compat=host", create a host-specific NumberFormat
   1327         if (U_SUCCESS(status) && count > 0 && uprv_strcmp(buffer, "host") == 0) {
   1328             Win32NumberFormat *f = NULL;
   1329             UBool curr = TRUE;
   1330 
   1331             switch (style) {
   1332             case UNUM_DECIMAL:
   1333                 curr = FALSE;
   1334                 // fall-through
   1335 
   1336             case UNUM_CURRENCY:
   1337             case UNUM_CURRENCY_ISO: // do not support plural formatting here
   1338             case UNUM_CURRENCY_PLURAL:
   1339             case UNUM_CURRENCY_ACCOUNTING:
   1340             case UNUM_CASH_CURRENCY:
   1341             case UNUM_CURRENCY_STANDARD:
   1342                 f = new Win32NumberFormat(desiredLocale, curr, status);
   1343 
   1344                 if (U_SUCCESS(status)) {
   1345                     return f;
   1346                 }
   1347 
   1348                 delete f;
   1349                 break;
   1350             default:
   1351                 break;
   1352             }
   1353         }
   1354     }
   1355 #endif
   1356     // Use numbering system cache hashtable
   1357     umtx_initOnce(gNSCacheInitOnce, &nscacheInit);
   1358 
   1359     // Get cached numbering system
   1360     LocalPointer<NumberingSystem> ownedNs;
   1361     NumberingSystem *ns = NULL;
   1362     if (NumberingSystem_cache != NULL) {
   1363         // TODO: Bad hash key usage, see ticket #8504.
   1364         int32_t hashKey = desiredLocale.hashCode();
   1365 
   1366         Mutex lock(&nscacheMutex);
   1367         ns = (NumberingSystem *)uhash_iget(NumberingSystem_cache, hashKey);
   1368         if (ns == NULL) {
   1369             ns = NumberingSystem::createInstance(desiredLocale,status);
   1370             uhash_iput(NumberingSystem_cache, hashKey, (void*)ns, &status);
   1371         }
   1372     } else {
   1373         ownedNs.adoptInstead(NumberingSystem::createInstance(desiredLocale,status));
   1374         ns = ownedNs.getAlias();
   1375     }
   1376 
   1377     // check results of getting a numbering system
   1378     if (U_FAILURE(status)) {
   1379         return NULL;
   1380     }
   1381 
   1382     if (mustBeDecimalFormat && ns->isAlgorithmic()) {
   1383         status = U_UNSUPPORTED_ERROR;
   1384         return NULL;
   1385     }
   1386 
   1387     LocalPointer<DecimalFormatSymbols> symbolsToAdopt;
   1388     UnicodeString pattern;
   1389     LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getName(), &status));
   1390     if (U_FAILURE(status)) {
   1391         return NULL;
   1392     }
   1393     else {
   1394         // Loads the decimal symbols of the desired locale.
   1395         symbolsToAdopt.adoptInsteadAndCheckErrorCode(new DecimalFormatSymbols(desiredLocale, status), status);
   1396         if (U_FAILURE(status)) {
   1397             return NULL;
   1398         }
   1399 
   1400         UResourceBundle *resource = ownedResource.orphan();
   1401         UResourceBundle *numElements = ures_getByKeyWithFallback(resource, gNumberElements, NULL, &status);
   1402         resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &status);
   1403         resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status);
   1404         ownedResource.adoptInstead(resource);
   1405 
   1406         int32_t patLen = 0;
   1407         const UChar *patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status);
   1408 
   1409         // Didn't find a pattern specific to the numbering system, so fall back to "latn"
   1410         if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(gLatn,ns->getName())) {
   1411             status = U_ZERO_ERROR;
   1412             resource = ures_getByKeyWithFallback(numElements, gLatn, resource, &status);
   1413             resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status);
   1414             patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status);
   1415         }
   1416 
   1417         ures_close(numElements);
   1418 
   1419         // Creates the specified decimal format style of the desired locale.
   1420         pattern.setTo(TRUE, patResStr, patLen);
   1421     }
   1422     if (U_FAILURE(status)) {
   1423         return NULL;
   1424     }
   1425     if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO || style == UNUM_CURRENCY_ACCOUNTING
   1426         || style == UNUM_CASH_CURRENCY || style == UNUM_CURRENCY_STANDARD){
   1427         const UChar* currPattern = symbolsToAdopt->getCurrencyPattern();
   1428         if(currPattern!=NULL){
   1429             pattern.setTo(currPattern, u_strlen(currPattern));
   1430         }
   1431     }
   1432 
   1433 
   1434     NumberFormat *f;
   1435     if (ns->isAlgorithmic()) {
   1436         UnicodeString nsDesc;
   1437         UnicodeString nsRuleSetGroup;
   1438         UnicodeString nsRuleSetName;
   1439         Locale nsLoc;
   1440         URBNFRuleSetTag desiredRulesType = URBNF_NUMBERING_SYSTEM;
   1441 
   1442         nsDesc.setTo(ns->getDescription());
   1443         int32_t firstSlash = nsDesc.indexOf(gSlash);
   1444         int32_t lastSlash = nsDesc.lastIndexOf(gSlash);
   1445         if ( lastSlash > firstSlash ) {
   1446             CharString nsLocID;
   1447 
   1448             nsLocID.appendInvariantChars(nsDesc.tempSubString(0, firstSlash), status);
   1449             nsRuleSetGroup.setTo(nsDesc,firstSlash+1,lastSlash-firstSlash-1);
   1450             nsRuleSetName.setTo(nsDesc,lastSlash+1);
   1451 
   1452             nsLoc = Locale::createFromName(nsLocID.data());
   1453 
   1454             UnicodeString SpelloutRules = UNICODE_STRING_SIMPLE("SpelloutRules");
   1455             if ( nsRuleSetGroup.compare(SpelloutRules) == 0 ) {
   1456                 desiredRulesType = URBNF_SPELLOUT;
   1457             }
   1458         } else {
   1459             nsLoc = desiredLocale;
   1460             nsRuleSetName.setTo(nsDesc);
   1461         }
   1462 
   1463         RuleBasedNumberFormat *r = new RuleBasedNumberFormat(desiredRulesType,nsLoc,status);
   1464         if (r == NULL) {
   1465             status = U_MEMORY_ALLOCATION_ERROR;
   1466             return NULL;
   1467         }
   1468         r->setDefaultRuleSet(nsRuleSetName,status);
   1469         f = r;
   1470     } else {
   1471         // replace single currency sign in the pattern with double currency sign
   1472         // if the style is UNUM_CURRENCY_ISO
   1473         if (style == UNUM_CURRENCY_ISO) {
   1474             pattern.findAndReplace(UnicodeString(TRUE, gSingleCurrencySign, 1),
   1475                                    UnicodeString(TRUE, gDoubleCurrencySign, 2));
   1476         }
   1477 
   1478         // "new DecimalFormat()" does not adopt the symbols if its memory allocation fails.
   1479         DecimalFormatSymbols *syms = symbolsToAdopt.orphan();
   1480         DecimalFormat* df = new DecimalFormat(pattern, syms, style, status);
   1481 
   1482         // if it is cash currency style, setCurrencyUsage with usage
   1483         if (style == UNUM_CASH_CURRENCY){
   1484             df->setCurrencyUsage(UCURR_USAGE_CASH, &status);
   1485         }
   1486 
   1487         if (U_FAILURE(status)) {
   1488             delete df;
   1489             return NULL;
   1490         }
   1491 
   1492         f = df;
   1493         if (f == NULL) {
   1494             delete syms;
   1495             status = U_MEMORY_ALLOCATION_ERROR;
   1496             return NULL;
   1497         }
   1498     }
   1499 
   1500     f->setLocaleIDs(ures_getLocaleByType(ownedResource.getAlias(), ULOC_VALID_LOCALE, &status),
   1501                     ures_getLocaleByType(ownedResource.getAlias(), ULOC_ACTUAL_LOCALE, &status));
   1502     if (U_FAILURE(status)) {
   1503         delete f;
   1504         return NULL;
   1505     }
   1506     return f;
   1507 }
   1508 
   1509 U_NAMESPACE_END
   1510 
   1511 #endif /* #if !UCONFIG_NO_FORMATTING */
   1512 
   1513 //eof
   1514