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