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