diff --git a/icu4c/source/i18n/currpinf.cpp b/icu4c/source/i18n/currpinf.cpp index e80d84702b..436e892941 100644 --- a/icu4c/source/i18n/currpinf.cpp +++ b/icu4c/source/i18n/currpinf.cpp @@ -19,6 +19,7 @@ #include "unicode/locid.h" #include "unicode/plurrule.h" #include "unicode/ures.h" +#include "unicode/numsys.h" #include "cstring.h" #include "hash.h" #include "uresimp.h" @@ -239,13 +240,21 @@ CurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& st return; } + static NumberingSystem *ns = NumberingSystem::createInstance(loc,status); UErrorCode ec = U_ZERO_ERROR; UResourceBundle *rb = ures_open(NULL, loc.getName(), &ec); - rb = ures_getByKeyWithFallback(rb, gNumberElementsTag, rb, &ec); - rb = ures_getByKeyWithFallback(rb, gLatnTag, rb, &ec); + UResourceBundle *numElements = ures_getByKeyWithFallback(rb, gNumberElementsTag, NULL, &ec); + rb = ures_getByKeyWithFallback(numElements, ns->getName(), rb, &ec); rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec); int32_t ptnLen; const UChar* numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec); + // Fall back to "latn" if num sys specific pattern isn't there. + if ( ec == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),gLatnTag)) { + ec = U_ZERO_ERROR; + rb = ures_getByKeyWithFallback(numElements, gLatnTag, rb, &ec); + rb = ures_getByKeyWithFallback(rb, gPatternsTag, rb, &ec); + numberStylePattern = ures_getStringByKeyWithFallback(rb, gDecimalFormatTag, &ptnLen, &ec); + } int32_t numberStylePatternLen = ptnLen; const UChar* negNumberStylePattern = NULL; int32_t negNumberStylePatternLen = 0; @@ -263,6 +272,8 @@ CurrencyPluralInfo::setupCurrencyPluralPattern(const Locale& loc, UErrorCode& st } } } + + ures_close(numElements); ures_close(rb); if (U_FAILURE(ec)) { diff --git a/icu4c/source/i18n/decimfmt.cpp b/icu4c/source/i18n/decimfmt.cpp index edc48dce4a..d8724fcae3 100644 --- a/icu4c/source/i18n/decimfmt.cpp +++ b/icu4c/source/i18n/decimfmt.cpp @@ -54,6 +54,7 @@ #include "unicode/currpinf.h" #include "unicode/plurrule.h" #include "unicode/utf16.h" +#include "unicode/numsys.h" #include "uresimp.h" #include "ucurrimp.h" #include "charstr.h" @@ -386,6 +387,12 @@ DecimalFormat::construct(UErrorCode& status, return; } } + UErrorCode nsStatus = U_ZERO_ERROR; + NumberingSystem *ns = NumberingSystem::createInstance(nsStatus); + if (U_FAILURE(nsStatus)) { + status = nsStatus; + return; + } UnicodeString str; // Uses the default locale's number format pattern if there isn't @@ -393,16 +400,23 @@ DecimalFormat::construct(UErrorCode& status, if (pattern == NULL) { int32_t len = 0; - UResourceBundle *resource = ures_open(NULL, Locale::getDefault().getName(), &status); + UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &status); - resource = ures_getByKeyWithFallback(resource, fgNumberElements, resource, &status); - // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn". - resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status); + UResourceBundle *resource = ures_getByKeyWithFallback(top, fgNumberElements, NULL, &status); + resource = ures_getByKeyWithFallback(resource, ns->getName(), resource, &status); resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status); const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status); + if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(fgLatn,ns->getName())) { + status = U_ZERO_ERROR; + resource = ures_getByKeyWithFallback(top, fgNumberElements, resource, &status); + resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status); + resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status); + resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status); + } str.setTo(TRUE, resStr, len); pattern = &str; ures_close(resource); + ures_close(top); } if (U_FAILURE(status)) @@ -486,6 +500,8 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { return; } + NumberingSystem *ns = NumberingSystem::createInstance(fSymbols->getLocale(),status); + // Save the default currency patterns of this locale. // Here, chose onlyApplyPatternWithoutExpandAffix without // expanding the affix patterns into affixes. @@ -493,12 +509,18 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { UErrorCode error = U_ZERO_ERROR; UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(), &error); - resource = ures_getByKeyWithFallback(resource, fgNumberElements, resource, &error); - // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn". - resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &error); + UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberElements, NULL, &error); + resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &error); resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error); int32_t patLen = 0; const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat, &patLen, &error); + if ( error == U_MISSING_RESOURCE_ERROR && uprv_strcmp(ns->getName(),fgLatn)) { + error = U_ZERO_ERROR; + resource = ures_getByKeyWithFallback(numElements, fgLatn, resource, &error); + resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error); + patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat, &patLen, &error); + } + ures_close(numElements); ures_close(resource); if (U_SUCCESS(error)) { diff --git a/icu4c/source/i18n/numfmt.cpp b/icu4c/source/i18n/numfmt.cpp index 692107c080..5354c4fd19 100644 --- a/icu4c/source/i18n/numfmt.cpp +++ b/icu4c/source/i18n/numfmt.cpp @@ -1151,54 +1151,6 @@ NumberFormat::makeInstance(const Locale& desiredLocale, } } #endif - - LocalPointer symbolsToAdopt; - UnicodeString pattern; - LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getName(), &status)); - if (U_FAILURE(status)) { - // We don't appear to have resource data available -- use the last-resort data - status = U_USING_FALLBACK_WARNING; - // When the data is unavailable, and locale isn't passed in, last resort data is used. - symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(status)); - if (symbolsToAdopt.isNull()) { - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - - // Creates a DecimalFormat instance with the last resort number patterns. - pattern.setTo(TRUE, gLastResortNumberPatterns[style], -1); - } - else { - // Loads the decimal symbols of the desired locale. - symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, status)); - if (symbolsToAdopt.isNull()) { - status = U_MEMORY_ALLOCATION_ERROR; - return NULL; - } - - UResourceBundle *resource = ownedResource.orphan(); - resource = ures_getByKeyWithFallback(resource, gNumberElements, resource, &status); - // TODO : Get patterns on a per numbering system basis, for right now assumes "latn" for patterns - resource = ures_getByKeyWithFallback(resource, gLatn, resource, &status); - resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status); - ownedResource.adoptInstead(resource); - - int32_t patLen = 0; - const UChar *patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status); - - // Creates the specified decimal format style of the desired locale. - pattern.setTo(TRUE, patResStr, patLen); - } - if (U_FAILURE(status)) { - return NULL; - } - if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO){ - const UChar* currPattern = symbolsToAdopt->getCurrencyPattern(); - if(currPattern!=NULL){ - pattern.setTo(currPattern, u_strlen(currPattern)); - } - } - // Use numbering system cache hashtable UHashtable *cache; UMTX_CHECK(&nscacheMutex, NumberingSystem_cache, cache); @@ -1253,6 +1205,61 @@ NumberFormat::makeInstance(const Locale& desiredLocale, return NULL; } + LocalPointer symbolsToAdopt; + UnicodeString pattern; + LocalUResourceBundlePointer ownedResource(ures_open(NULL, desiredLocale.getName(), &status)); + if (U_FAILURE(status)) { + // We don't appear to have resource data available -- use the last-resort data + status = U_USING_FALLBACK_WARNING; + // When the data is unavailable, and locale isn't passed in, last resort data is used. + symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(status)); + if (symbolsToAdopt.isNull()) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + // Creates a DecimalFormat instance with the last resort number patterns. + pattern.setTo(TRUE, gLastResortNumberPatterns[style], -1); + } + else { + // Loads the decimal symbols of the desired locale. + symbolsToAdopt.adoptInstead(new DecimalFormatSymbols(desiredLocale, status)); + if (symbolsToAdopt.isNull()) { + status = U_MEMORY_ALLOCATION_ERROR; + return NULL; + } + + UResourceBundle *resource = ownedResource.orphan(); + UResourceBundle *numElements = ures_getByKeyWithFallback(resource, gNumberElements, NULL, &status); + resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &status); + resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status); + ownedResource.adoptInstead(resource); + + int32_t patLen = 0; + const UChar *patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status); + + // Didn't find a pattern specific to the numbering system, so fall back to "latn" + if ( status == U_MISSING_RESOURCE_ERROR && uprv_strcmp(gLatn,ns->getName())) { + status = U_ZERO_ERROR; + resource = ures_getByKeyWithFallback(numElements, gLatn, resource, &status); + resource = ures_getByKeyWithFallback(resource, gPatterns, resource, &status); + patResStr = ures_getStringByKeyWithFallback(resource, gFormatKeys[style], &patLen, &status); + } + + // Creates the specified decimal format style of the desired locale. + pattern.setTo(TRUE, patResStr, patLen); + } + if (U_FAILURE(status)) { + return NULL; + } + if(style==UNUM_CURRENCY || style == UNUM_CURRENCY_ISO){ + const UChar* currPattern = symbolsToAdopt->getCurrencyPattern(); + if(currPattern!=NULL){ + pattern.setTo(currPattern, u_strlen(currPattern)); + } + } + + NumberFormat *f; if (ns->isAlgorithmic()) { UnicodeString nsDesc;