ICU-8611 Make ICU look at patterns by numbering system

X-SVN-Rev: 30574
This commit is contained in:
John Emmons 2011-08-24 18:06:46 +00:00
parent 8eb6ce1f6a
commit bda69e7101
3 changed files with 97 additions and 57 deletions

View File

@ -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)) {

View File

@ -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)) {

View File

@ -1151,54 +1151,6 @@ NumberFormat::makeInstance(const Locale& desiredLocale,
}
}
#endif
LocalPointer<DecimalFormatSymbols> 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<DecimalFormatSymbols> 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;