2 *******************************************************************************
3 * Copyright (C) 1997-2006, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
9 * Modification History:
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 ********************************************************************************
25 #include "unicode/utypes.h"
27 #if !UCONFIG_NO_FORMATTING
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"
50 static void debugout(UnicodeString s
) {
52 s
.extract((int32_t) 0, s
.length(), buf
);
55 #define debug(x) printf("%s", x);
61 // If no number pattern can be located for a locale, this is the last
63 static const UChar gLastResortDecimalPat
[] = {
64 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0x3B, 0x2D, 0x23, 0x30, 0x2E, 0x23, 0x23, 0x23, 0 /* "#0.###;-#0.###" */
66 static const UChar gLastResortCurrencyPat
[] = {
67 0x24, 0x23, 0x30, 0x2E, 0x30, 0x30, 0x3B, 0x28, 0x24, 0x23, 0x30, 0x2E, 0x30, 0x30, 0x29, 0 /* "$#0.00;($#0.00)" */
69 static const UChar gLastResortPercentPat
[] = {
70 0x23, 0x30, 0x25, 0 /* "#0%" */
72 static const UChar gLastResortScientificPat
[] = {
73 0x23, 0x45, 0x30, 0 /* "#E0" */
76 // If the maximum base 10 exponent were 4, then the largest number would
77 // be 99,999 which has 5 digits.
78 static const int32_t gMaxIntegerDigits
= DBL_MAX_10_EXP
+ 1; // Should be ~40 ? --srl
79 static const int32_t gMinIntegerDigits
= 127;
81 static const UChar
* const gLastResortNumberPatterns
[] =
83 gLastResortDecimalPat
,
84 gLastResortCurrencyPat
,
85 gLastResortPercentPat
,
86 gLastResortScientificPat
89 // *****************************************************************************
91 // *****************************************************************************
95 UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(NumberFormat
)
97 #if !UCONFIG_NO_SERVICE
98 // -------------------------------------
99 // SimpleNumberFormatFactory implementation
100 NumberFormatFactory::~NumberFormatFactory() {}
101 SimpleNumberFormatFactory::SimpleNumberFormatFactory(const Locale
& locale
, UBool visible
)
104 LocaleUtility::initNameFromLocale(locale
, _id
);
107 SimpleNumberFormatFactory::~SimpleNumberFormatFactory() {}
109 UBool
SimpleNumberFormatFactory::visible(void) const {
113 const UnicodeString
*
114 SimpleNumberFormatFactory::getSupportedIDs(int32_t &count
, UErrorCode
& status
) const
116 if (U_SUCCESS(status
)) {
123 #endif /* #if !UCONFIG_NO_SERVICE */
125 // -------------------------------------
126 // default constructor
127 NumberFormat::NumberFormat()
128 : fGroupingUsed(TRUE
),
129 fMaxIntegerDigits(gMaxIntegerDigits
),
130 fMinIntegerDigits(1),
131 fMaxFractionDigits(3), // invariant, >= minFractionDigits
132 fMinFractionDigits(0),
133 fParseIntegerOnly(FALSE
)
138 // -------------------------------------
140 NumberFormat::~NumberFormat()
144 // -------------------------------------
147 NumberFormat::NumberFormat(const NumberFormat
&source
)
153 // -------------------------------------
154 // assignment operator
157 NumberFormat::operator=(const NumberFormat
& rhs
)
161 fGroupingUsed
= rhs
.fGroupingUsed
;
162 fMaxIntegerDigits
= rhs
.fMaxIntegerDigits
;
163 fMinIntegerDigits
= rhs
.fMinIntegerDigits
;
164 fMaxFractionDigits
= rhs
.fMaxFractionDigits
;
165 fMinFractionDigits
= rhs
.fMinFractionDigits
;
166 fParseIntegerOnly
= rhs
.fParseIntegerOnly
;
167 u_strncpy(fCurrency
, rhs
.fCurrency
, 4);
172 // -------------------------------------
175 NumberFormat::operator==(const Format
& that
) const
177 // Format::operator== guarantees this cast is safe
178 NumberFormat
* other
= (NumberFormat
*)&that
;
181 // This code makes it easy to determine why two format objects that should
184 if (!Format::operator==(that
)) {
185 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
188 if (!(fMaxIntegerDigits
== other
->fMaxIntegerDigits
&&
189 fMinIntegerDigits
== other
->fMinIntegerDigits
)) {
190 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
191 debug("Integer digits !=");
193 if (!(fMaxFractionDigits
== other
->fMaxFractionDigits
&&
194 fMinFractionDigits
== other
->fMinFractionDigits
)) {
195 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
196 debug("Fraction digits !=");
198 if (!(fGroupingUsed
== other
->fGroupingUsed
)) {
199 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
200 debug("fGroupingUsed != ");
202 if (!(fParseIntegerOnly
== other
->fParseIntegerOnly
)) {
203 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
204 debug("fParseIntegerOnly != ");
206 if (!(u_strcmp(fCurrency
, other
->fCurrency
) == 0)) {
207 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
208 debug("fCurrency !=");
210 if (!first
) { printf(" ]"); }
213 return ((this == &that
) ||
214 ((Format::operator==(that
) &&
215 fMaxIntegerDigits
== other
->fMaxIntegerDigits
&&
216 fMinIntegerDigits
== other
->fMinIntegerDigits
&&
217 fMaxFractionDigits
== other
->fMaxFractionDigits
&&
218 fMinFractionDigits
== other
->fMinFractionDigits
&&
219 fGroupingUsed
== other
->fGroupingUsed
&&
220 fParseIntegerOnly
== other
->fParseIntegerOnly
&&
221 u_strcmp(fCurrency
, other
->fCurrency
) == 0)));
224 // -------------------------------------x
225 // Formats the number object and save the format
226 // result in the toAppendTo string buffer.
229 NumberFormat::format(const Formattable
& obj
,
230 UnicodeString
& appendTo
,
232 UErrorCode
& status
) const
234 if (U_FAILURE(status
)) return appendTo
;
236 NumberFormat
* nonconst
= (NumberFormat
*) this;
237 const Formattable
* n
= &obj
;
240 UBool setCurr
= FALSE
;
241 const UObject
* o
= obj
.getObject(); // most commonly o==NULL
243 o
->getDynamicClassID() == CurrencyAmount::getStaticClassID()) {
244 // getISOCurrency() returns a pointer to internal storage, so we
245 // copy it to retain it across the call to setCurrency().
246 const CurrencyAmount
* amt
= (const CurrencyAmount
*) o
;
247 const UChar
* curr
= amt
->getISOCurrency();
248 u_strcpy(save
, getCurrency());
249 setCurr
= (u_strcmp(curr
, save
) != 0);
251 nonconst
->setCurrency(curr
, status
);
253 n
= &amt
->getNumber();
256 switch (n
->getType()) {
257 case Formattable::kDouble
:
258 format(n
->getDouble(), appendTo
, pos
);
260 case Formattable::kLong
:
261 format(n
->getLong(), appendTo
, pos
);
263 case Formattable::kInt64
:
264 format(n
->getInt64(), appendTo
, pos
);
267 status
= U_INVALID_FORMAT_ERROR
;
272 UErrorCode ok
= U_ZERO_ERROR
;
273 nonconst
->setCurrency(save
, ok
); // always restore currency
278 // -------------------------------------
281 NumberFormat::format(int64_t number
,
282 UnicodeString
& appendTo
,
283 FieldPosition
& pos
) const
285 // default so we don't introduce a new abstract method
286 return format((int32_t)number
, appendTo
, pos
);
289 // -------------------------------------
290 // Parses the string and save the result object as well
291 // as the final parsed position.
294 NumberFormat::parseObject(const UnicodeString
& source
,
296 ParsePosition
& parse_pos
) const
298 parse(source
, result
, parse_pos
);
301 // -------------------------------------
302 // Formats a double number and save the result in a string.
305 NumberFormat::format(double number
, UnicodeString
& appendTo
) const
307 FieldPosition
pos(0);
308 return format(number
, appendTo
, pos
);
311 // -------------------------------------
312 // Formats a long number and save the result in a string.
315 NumberFormat::format(int32_t number
, UnicodeString
& appendTo
) const
317 FieldPosition
pos(0);
318 return format(number
, appendTo
, pos
);
321 // -------------------------------------
322 // Formats a long number and save the result in a string.
325 NumberFormat::format(int64_t number
, UnicodeString
& appendTo
) const
327 FieldPosition
pos(0);
328 return format(number
, appendTo
, pos
);
331 // -------------------------------------
332 // Parses the text and save the result object. If the returned
333 // parse position is 0, that means the parsing failed, the status
334 // code needs to be set to failure. Ignores the returned parse
335 // position, otherwise.
338 NumberFormat::parse(const UnicodeString
& text
,
340 UErrorCode
& status
) const
342 if (U_FAILURE(status
)) return;
344 ParsePosition
parsePosition(0);
345 parse(text
, result
, parsePosition
);
346 if (parsePosition
.getIndex() == 0) {
347 status
= U_INVALID_FORMAT_ERROR
;
351 Formattable
& NumberFormat::parseCurrency(const UnicodeString
& text
,
353 ParsePosition
& pos
) const {
354 // Default implementation only -- subclasses should override
355 int32_t start
= pos
.getIndex();
356 parse(text
, result
, pos
);
357 if (pos
.getIndex() != start
) {
359 UErrorCode ec
= U_ZERO_ERROR
;
360 getEffectiveCurrency(curr
, ec
);
362 Formattable
n(result
);
363 result
.adoptObject(new CurrencyAmount(n
, curr
, ec
));
365 pos
.setIndex(start
); // indicate failure
372 // -------------------------------------
373 // Sets to only parse integers.
376 NumberFormat::setParseIntegerOnly(UBool value
)
378 fParseIntegerOnly
= value
;
381 // -------------------------------------
382 // Create a number style NumberFormat instance with the default locale.
384 NumberFormat
* U_EXPORT2
385 NumberFormat::createInstance(UErrorCode
& status
)
387 return createInstance(Locale::getDefault(), kNumberStyle
, status
);
390 // -------------------------------------
391 // Create a number style NumberFormat instance with the inLocale locale.
393 NumberFormat
* U_EXPORT2
394 NumberFormat::createInstance(const Locale
& inLocale
, UErrorCode
& status
)
396 return createInstance(inLocale
, kNumberStyle
, status
);
399 // -------------------------------------
400 // Create a currency style NumberFormat instance with the default locale.
402 NumberFormat
* U_EXPORT2
403 NumberFormat::createCurrencyInstance(UErrorCode
& status
)
405 return createCurrencyInstance(Locale::getDefault(), status
);
408 // -------------------------------------
409 // Create a currency style NumberFormat instance with the inLocale locale.
411 NumberFormat
* U_EXPORT2
412 NumberFormat::createCurrencyInstance(const Locale
& inLocale
, UErrorCode
& status
)
414 return createInstance(inLocale
, kCurrencyStyle
, status
);
417 // -------------------------------------
418 // Create a percent style NumberFormat instance with the default locale.
420 NumberFormat
* U_EXPORT2
421 NumberFormat::createPercentInstance(UErrorCode
& status
)
423 return createInstance(Locale::getDefault(), kPercentStyle
, status
);
426 // -------------------------------------
427 // Create a percent style NumberFormat instance with the inLocale locale.
429 NumberFormat
* U_EXPORT2
430 NumberFormat::createPercentInstance(const Locale
& inLocale
, UErrorCode
& status
)
432 return createInstance(inLocale
, kPercentStyle
, status
);
435 // -------------------------------------
436 // Create a scientific style NumberFormat instance with the default locale.
438 NumberFormat
* U_EXPORT2
439 NumberFormat::createScientificInstance(UErrorCode
& status
)
441 return createInstance(Locale::getDefault(), kScientificStyle
, status
);
444 // -------------------------------------
445 // Create a scientific style NumberFormat instance with the inLocale locale.
447 NumberFormat
* U_EXPORT2
448 NumberFormat::createScientificInstance(const Locale
& inLocale
, UErrorCode
& status
)
450 return createInstance(inLocale
, kScientificStyle
, status
);
453 // -------------------------------------
455 const Locale
* U_EXPORT2
456 NumberFormat::getAvailableLocales(int32_t& count
)
458 return Locale::getAvailableLocales(count
);
461 // ------------------------------------------
465 //-------------------------------------------
467 #if !UCONFIG_NO_SERVICE
468 static ICULocaleService
* gService
= NULL
;
471 * Release all static memory held by numberformat.
474 static UBool U_CALLCONV
numfmt_cleanup(void) {
483 // -------------------------------------
485 class ICUNumberFormatFactory
: public ICUResourceBundleFactory
{
487 virtual UObject
* handleCreate(const Locale
& loc
, int32_t kind
, const ICUService
* /* service */, UErrorCode
& status
) const {
488 // !!! kind is not an EStyles, need to determine how to handle this
489 return NumberFormat::makeInstance(loc
, (NumberFormat::EStyles
)kind
, status
);
493 // -------------------------------------
495 class NFFactory
: public LocaleKeyFactory
{
497 NumberFormatFactory
* _delegate
;
501 NFFactory(NumberFormatFactory
* delegate
)
502 : LocaleKeyFactory(delegate
->visible() ? VISIBLE
: INVISIBLE
)
503 , _delegate(delegate
)
514 virtual UObject
* create(const ICUServiceKey
& key
, const ICUService
* service
, UErrorCode
& status
) const
516 if (handlesKey(key
, status
)) {
517 const LocaleKey
& lkey
= (const LocaleKey
&)key
;
519 lkey
.canonicalLocale(loc
);
520 int32_t kind
= lkey
.kind();
522 UObject
* result
= _delegate
->createFormat(loc
, (UNumberFormatStyle
)(kind
+1));
523 if (result
== NULL
) {
524 result
= service
->getKey((ICUServiceKey
&)key
/* cast away const */, NULL
, this, status
);
533 * Return the set of ids that this factory supports (visible or
534 * otherwise). This can be called often and might need to be
535 * cached if it is expensive to create.
537 virtual const Hashtable
* getSupportedIDs(UErrorCode
& status
) const
539 if (U_SUCCESS(status
)) {
542 const UnicodeString
* const idlist
= _delegate
->getSupportedIDs(count
, status
);
543 ((NFFactory
*)this)->_ids
= new Hashtable(status
); /* cast away const */
545 for (int i
= 0; i
< count
; ++i
) {
546 _ids
->put(idlist
[i
], (void*)this, status
);
556 class ICUNumberFormatService
: public ICULocaleService
{
558 ICUNumberFormatService()
559 : ICULocaleService(UNICODE_STRING_SIMPLE("Number Format"))
561 UErrorCode status
= U_ZERO_ERROR
;
562 registerFactory(new ICUNumberFormatFactory(), status
);
565 virtual UObject
* cloneInstance(UObject
* instance
) const {
566 return ((NumberFormat
*)instance
)->clone();
569 virtual UObject
* handleDefault(const ICUServiceKey
& key
, UnicodeString
* /* actualID */, UErrorCode
& status
) const {
570 LocaleKey
& lkey
= (LocaleKey
&)key
;
571 int32_t kind
= lkey
.kind();
573 lkey
.currentLocale(loc
);
574 return NumberFormat::makeInstance(loc
, (NumberFormat::EStyles
)kind
, status
);
577 virtual UBool
isDefault() const {
578 return countFactories() == 1;
582 // -------------------------------------
584 static ICULocaleService
*
585 getNumberFormatService(void)
590 needInit
= (UBool
)(gService
== NULL
);
593 ICULocaleService
* newservice
= new ICUNumberFormatService();
596 if (gService
== NULL
) {
597 gService
= newservice
;
604 // we won the contention, this thread can register cleanup.
605 #if !UCONFIG_NO_SERVICE
606 ucln_i18n_registerCleanup(UCLN_I18N_NUMFMT
, numfmt_cleanup
);
613 // -------------------------------------
615 URegistryKey U_EXPORT2
616 NumberFormat::registerFactory(NumberFormatFactory
* toAdopt
, UErrorCode
& status
)
618 ICULocaleService
*service
= getNumberFormatService();
620 return service
->registerFactory(new NFFactory(toAdopt
), status
);
622 status
= U_MEMORY_ALLOCATION_ERROR
;
626 // -------------------------------------
629 NumberFormat::unregister(URegistryKey key
, UErrorCode
& status
)
631 if (U_SUCCESS(status
)) {
633 UBool haveService
= gService
!= NULL
;
636 return gService
->unregister(key
, status
);
638 status
= U_ILLEGAL_ARGUMENT_ERROR
;
643 // -------------------------------------
644 StringEnumeration
* U_EXPORT2
645 NumberFormat::getAvailableLocales(void)
647 ICULocaleService
*service
= getNumberFormatService();
649 return service
->getAvailableLocales();
651 return NULL
; // no way to return error condition
653 #endif /* UCONFIG_NO_SERVICE */
654 // -------------------------------------
656 NumberFormat
* U_EXPORT2
657 NumberFormat::createInstance(const Locale
& loc
, EStyles kind
, UErrorCode
& status
)
659 #if !UCONFIG_NO_SERVICE
661 UBool haveService
= gService
!= NULL
;
664 return (NumberFormat
*)gService
->get(loc
, kind
, status
);
669 return makeInstance(loc
, kind
, status
);
674 // -------------------------------------
675 // Checks if the thousand/10 thousand grouping is used in the
676 // NumberFormat instance.
679 NumberFormat::isGroupingUsed() const
681 return fGroupingUsed
;
684 // -------------------------------------
685 // Sets to use the thousand/10 thousand grouping in the
686 // NumberFormat instance.
689 NumberFormat::setGroupingUsed(UBool newValue
)
691 fGroupingUsed
= newValue
;
694 // -------------------------------------
695 // Gets the maximum number of digits for the integral part for
696 // this NumberFormat instance.
698 int32_t NumberFormat::getMaximumIntegerDigits() const
700 return fMaxIntegerDigits
;
703 // -------------------------------------
704 // Sets the maximum number of digits for the integral part for
705 // this NumberFormat instance.
708 NumberFormat::setMaximumIntegerDigits(int32_t newValue
)
710 fMaxIntegerDigits
= uprv_max(0, uprv_min(newValue
, gMaxIntegerDigits
));
711 if(fMinIntegerDigits
> fMaxIntegerDigits
)
712 fMinIntegerDigits
= fMaxIntegerDigits
;
715 // -------------------------------------
716 // Gets the minimum number of digits for the integral part for
717 // this NumberFormat instance.
720 NumberFormat::getMinimumIntegerDigits() const
722 return fMinIntegerDigits
;
725 // -------------------------------------
726 // Sets the minimum number of digits for the integral part for
727 // this NumberFormat instance.
730 NumberFormat::setMinimumIntegerDigits(int32_t newValue
)
732 fMinIntegerDigits
= uprv_max(0, uprv_min(newValue
, gMinIntegerDigits
));
733 if(fMinIntegerDigits
> fMaxIntegerDigits
)
734 fMaxIntegerDigits
= fMinIntegerDigits
;
737 // -------------------------------------
738 // Gets the maximum number of digits for the fractional part for
739 // this NumberFormat instance.
742 NumberFormat::getMaximumFractionDigits() const
744 return fMaxFractionDigits
;
747 // -------------------------------------
748 // Sets the maximum number of digits for the fractional part for
749 // this NumberFormat instance.
752 NumberFormat::setMaximumFractionDigits(int32_t newValue
)
754 fMaxFractionDigits
= uprv_max(0, uprv_min(newValue
, gMaxIntegerDigits
));
755 if(fMaxFractionDigits
< fMinFractionDigits
)
756 fMinFractionDigits
= fMaxFractionDigits
;
759 // -------------------------------------
760 // Gets the minimum number of digits for the fractional part for
761 // this NumberFormat instance.
764 NumberFormat::getMinimumFractionDigits() const
766 return fMinFractionDigits
;
769 // -------------------------------------
770 // Sets the minimum number of digits for the fractional part for
771 // this NumberFormat instance.
774 NumberFormat::setMinimumFractionDigits(int32_t newValue
)
776 fMinFractionDigits
= uprv_max(0, uprv_min(newValue
, gMinIntegerDigits
));
777 if (fMaxFractionDigits
< fMinFractionDigits
)
778 fMaxFractionDigits
= fMinFractionDigits
;
781 // -------------------------------------
783 void NumberFormat::setCurrency(const UChar
* theCurrency
, UErrorCode
& ec
) {
788 u_strncpy(fCurrency
, theCurrency
, 3);
795 const UChar
* NumberFormat::getCurrency() const {
799 void NumberFormat::getEffectiveCurrency(UChar
* result
, UErrorCode
& ec
) const {
800 const UChar
* c
= getCurrency();
802 u_strncpy(result
, c
, 3);
805 const char* loc
= getLocaleID(ULOC_VALID_LOCALE
, ec
);
807 loc
= uloc_getDefault();
809 ucurr_forLocale(loc
, result
, 4, &ec
);
813 // -------------------------------------
814 // Creates the NumberFormat instance of the specified style (number, currency,
815 // or percent) for the desired locale.
818 NumberFormat::makeInstance(const Locale
& desiredLocale
,
822 if (U_FAILURE(status
)) return NULL
;
824 if (style
< 0 || style
>= kStyleCount
) {
825 status
= U_ILLEGAL_ARGUMENT_ERROR
;
831 int32_t count
= desiredLocale
.getKeywordValue("compat", buffer
, sizeof(buffer
), status
);
833 // if the locale has "@compat=host", create a host-specific NumberFormat
834 if (count
> 0 && uprv_strcmp(buffer
, "host") == 0) {
835 Win32NumberFormat
*f
= NULL
;
844 f
= new Win32NumberFormat(desiredLocale
, curr
, status
);
846 if (U_SUCCESS(status
)) {
859 NumberFormat
* f
= NULL
;
860 DecimalFormatSymbols
* symbolsToAdopt
= NULL
;
861 UnicodeString pattern
;
862 UResourceBundle
*resource
= ures_open((char *)0, desiredLocale
.getName(), &status
);
863 UResourceBundle
*numberPatterns
= ures_getByKey(resource
, DecimalFormat::fgNumberPatterns
, NULL
, &status
);
865 if (U_FAILURE(status
)) {
866 // We don't appear to have resource data available -- use the last-resort data
867 status
= U_USING_FALLBACK_WARNING
;
868 // When the data is unavailable, and locale isn't passed in, last resort data is used.
869 symbolsToAdopt
= new DecimalFormatSymbols(status
);
871 // Creates a DecimalFormat instance with the last resort number patterns.
872 pattern
.setTo(TRUE
, gLastResortNumberPatterns
[style
], -1);
875 // If not all the styled patterns exists for the NumberFormat in this locale,
876 // sets the status code to failure and returns nil.
877 if (ures_getSize(numberPatterns
) < (int32_t)(sizeof(gLastResortNumberPatterns
)/sizeof(gLastResortNumberPatterns
[0]))) {
878 status
= U_INVALID_FORMAT_ERROR
;
882 // Loads the decimal symbols of the desired locale.
883 symbolsToAdopt
= new DecimalFormatSymbols(desiredLocale
, status
);
886 const UChar
*patResStr
= ures_getStringByIndex(numberPatterns
, (int32_t)style
, &patLen
, &status
);
887 // Creates the specified decimal format style of the desired locale.
888 pattern
.setTo(TRUE
, patResStr
, patLen
);
890 if (U_FAILURE(status
) || symbolsToAdopt
== NULL
) {
893 if(style
==kCurrencyStyle
){
894 const UChar
* currPattern
= symbolsToAdopt
->getCurrencyPattern();
895 if(currPattern
!=NULL
){
896 pattern
.setTo(currPattern
, u_strlen(currPattern
));
899 f
= new DecimalFormat(pattern
, symbolsToAdopt
, status
);
900 if (U_FAILURE(status
) || f
== NULL
) {
904 f
->setLocaleIDs(ures_getLocaleByType(numberPatterns
, ULOC_VALID_LOCALE
, &status
),
905 ures_getLocaleByType(numberPatterns
, ULOC_ACTUAL_LOCALE
, &status
));
907 ures_close(numberPatterns
);
908 ures_close(resource
);
909 if (U_FAILURE(status
)) {
910 /* If f exists, then it will delete the symbols */
912 delete symbolsToAdopt
;
919 if (f
== NULL
|| symbolsToAdopt
== NULL
) {
920 status
= U_MEMORY_ALLOCATION_ERROR
;
928 #endif /* #if !UCONFIG_NO_FORMATTING */