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