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