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>
56static 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.
69static const UChar gLastResortDecimalPat[] = {
70    0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x3B, 0x2D, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0 /* "#0.###;-#0.###" */
71};
72static 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};
75static const UChar gLastResortPercentPat[] = {
76    0x23, 0x30, 0x25, 0 /* "#0%" */
77};
78static const UChar gLastResortScientificPat[] = {
79    0x23, 0x45, 0x30, 0 /* "#E0" */
80};
81static 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};
84static const UChar gLastResortPluralCurrencyPat[] = {
85    0x23, 0x30, 0x2E, 0x30, 0x30, 0xA0, 0xA4, 0xA4, 0xA4, 0 /* "#0.00\u00A0\u00A4\u00A4\u00A4*/
86};
87
88static const UChar gSingleCurrencySign[] = {0xA4, 0};
89static const UChar gDoubleCurrencySign[] = {0xA4, 0xA4, 0};
90
91static 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
96static const int32_t gMaxIntegerDigits = DBL_MAX_10_EXP + DBL_DIG + 1;
97static const int32_t gMinIntegerDigits = 127;
98
99static 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
116static const char *gNumberElements = "NumberElements";
117static const char *gLatn = "latn";
118static const char *gPatterns = "patterns";
119static 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
139static UHashtable * NumberingSystem_cache = NULL;
140
141static UMTX nscacheMutex = NULL;
142
143#if !UCONFIG_NO_SERVICE
144static U_NAMESPACE_QUALIFIER ICULocaleService* gService = NULL;
145#endif
146
147/**
148 * Release all static memory held by Number Format.
149 */
150U_CDECL_BEGIN
151static void U_CALLCONV
152deleteNumberingSystem(void *obj) {
153    delete (U_NAMESPACE_QUALIFIER NumberingSystem *)obj;
154}
155
156static 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}
171U_CDECL_END
172
173// *****************************************************************************
174// class NumberFormat
175// *****************************************************************************
176
177U_NAMESPACE_BEGIN
178
179UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(NumberFormat)
180
181#if !UCONFIG_NO_SERVICE
182// -------------------------------------
183// SimpleNumberFormatFactory implementation
184NumberFormatFactory::~NumberFormatFactory() {}
185SimpleNumberFormatFactory::SimpleNumberFormatFactory(const Locale& locale, UBool visible)
186    : _visible(visible)
187{
188    LocaleUtility::initNameFromLocale(locale, _id);
189}
190
191SimpleNumberFormatFactory::~SimpleNumberFormatFactory() {}
192
193UBool SimpleNumberFormatFactory::visible(void) const {
194    return _visible;
195}
196
197const UnicodeString *
198SimpleNumberFormatFactory::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
211NumberFormat::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
225NumberFormat::~NumberFormat()
226{
227}
228
229// -------------------------------------
230// copy constructor
231
232NumberFormat::NumberFormat(const NumberFormat &source)
233:   Format(source)
234{
235    *this = source;
236}
237
238// -------------------------------------
239// assignment operator
240
241NumberFormat&
242NumberFormat::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
261UBool
262NumberFormat::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
320UnicodeString&
321NumberFormat::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
336UnicodeString&
337NumberFormat::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
352UnicodeString&
353NumberFormat::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
379UnicodeString&
380NumberFormat::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
398class 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
411inline const Formattable*
412ArgExtractor::number(void) const {
413  return num;
414}
415
416ArgExtractor::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
434ArgExtractor::~ArgExtractor() {
435    if (setCurr) {
436        UErrorCode ok = U_ZERO_ERROR;
437        ncnf->setCurrency(save, ok); // always restore currency
438    }
439}
440
441UnicodeString& 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
458UnicodeString&
459NumberFormat::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
474UnicodeString&
475NumberFormat::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
519UnicodeString&
520NumberFormat::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
555UnicodeString&
556NumberFormat::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
568void
569NumberFormat::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
579UnicodeString&
580NumberFormat::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
589UnicodeString&
590NumberFormat::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
599UnicodeString&
600NumberFormat::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
612void
613NumberFormat::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
626Formattable& 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
652void
653NumberFormat::setParseIntegerOnly(UBool value)
654{
655    fParseIntegerOnly = value;
656}
657
658// -------------------------------------
659// Sets whether lenient parse is enabled.
660
661void
662NumberFormat::setLenient(UBool enable)
663{
664    fLenient = enable;
665}
666
667// -------------------------------------
668// Create a number style NumberFormat instance with the default locale.
669
670NumberFormat* U_EXPORT2
671NumberFormat::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
679NumberFormat* U_EXPORT2
680NumberFormat::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
688NumberFormat* U_EXPORT2
689NumberFormat::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
697NumberFormat* U_EXPORT2
698NumberFormat::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
706NumberFormat* U_EXPORT2
707NumberFormat::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
715NumberFormat* U_EXPORT2
716NumberFormat::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
724NumberFormat* U_EXPORT2
725NumberFormat::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
733NumberFormat* U_EXPORT2
734NumberFormat::createScientificInstance(const Locale& inLocale, UErrorCode& status)
735{
736    return createInstance(inLocale, UNUM_SCIENTIFIC, status);
737}
738
739// -------------------------------------
740
741const Locale* U_EXPORT2
742NumberFormat::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
757class ICUNumberFormatFactory : public ICUResourceBundleFactory {
758protected:
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
766class NFFactory : public LocaleKeyFactory {
767private:
768    NumberFormatFactory* _delegate;
769    Hashtable* _ids;
770
771public:
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
802protected:
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
827class ICUNumberFormatService : public ICULocaleService {
828public:
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
855static ICULocaleService*
856getNumberFormatService(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
882URegistryKey U_EXPORT2
883NumberFormat::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
898UBool U_EXPORT2
899NumberFormat::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// -------------------------------------
913StringEnumeration* U_EXPORT2
914NumberFormat::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
925NumberFormat* U_EXPORT2
926NumberFormat::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
946UBool
947NumberFormat::isGroupingUsed() const
948{
949    return fGroupingUsed;
950}
951
952// -------------------------------------
953// Sets to use the thousand/10 thousand grouping in the
954// NumberFormat instance.
955
956void
957NumberFormat::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
966int32_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
975void
976NumberFormat::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
987int32_t
988NumberFormat::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
997void
998NumberFormat::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
1009int32_t
1010NumberFormat::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
1019void
1020NumberFormat::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
1031int32_t
1032NumberFormat::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
1041void
1042NumberFormat::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
1051void 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
1063const UChar* NumberFormat::getCurrency() const {
1064    return fCurrency;
1065}
1066
1067void 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
1085UBool
1086NumberFormat::isStyleSupported(UNumberFormatStyle style) {
1087    return gLastResortNumberPatterns[style] != NULL;
1088}
1089
1090NumberFormat*
1091NumberFormat::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
1308U_NAMESPACE_END
1309
1310#endif /* #if !UCONFIG_NO_FORMATTING */
1311
1312//eof
1313