X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/f3c0d7a59d99c2a94c6b8822291f0e42be3773c9..249c4c5ea9376c24572daf9c2effa7484a282f14:/icuSources/i18n/dcfmtsym.cpp diff --git a/icuSources/i18n/dcfmtsym.cpp b/icuSources/i18n/dcfmtsym.cpp index 08a85b54..e6785ab7 100644 --- a/icuSources/i18n/dcfmtsym.cpp +++ b/icuSources/i18n/dcfmtsym.cpp @@ -38,6 +38,7 @@ #include "uresimp.h" #include "ureslocs.h" #include "charstr.h" +#include "uassert.h" // ***************************************************************************** // class DecimalFormatSymbols @@ -65,7 +66,7 @@ static const UChar INTL_CURRENCY_SYMBOL_STR[] = {0xa4, 0xa4, 0}; static const char *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] = { "decimal", "group", - "list", + NULL, /* #11897: the symbol is NOT the pattern separator symbol */ "percentSign", NULL, /* Native zero digit is deprecated from CLDR - get it from the numbering system */ NULL, /* Pattern digit character is deprecated from CLDR - use # by default always */ @@ -97,9 +98,7 @@ static const char *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] // Initializes this with the decimal format symbols in the default locale. DecimalFormatSymbols::DecimalFormatSymbols(UErrorCode& status) - : UObject(), - locale() -{ + : UObject(), locale(), currPattern(NULL) { initialize(locale, status, TRUE); } @@ -107,16 +106,17 @@ DecimalFormatSymbols::DecimalFormatSymbols(UErrorCode& status) // Initializes this with the decimal format symbols in the desired locale. DecimalFormatSymbols::DecimalFormatSymbols(const Locale& loc, UErrorCode& status) - : UObject(), - locale(loc) -{ + : UObject(), locale(loc), currPattern(NULL) { initialize(locale, status); } +DecimalFormatSymbols::DecimalFormatSymbols(const Locale& loc, const NumberingSystem& ns, UErrorCode& status) + : UObject(), locale(loc), currPattern(NULL) { + initialize(locale, status, FALSE, &ns); +} + DecimalFormatSymbols::DecimalFormatSymbols() - : UObject(), - locale(Locale::getRoot()), - currPattern(NULL) { + : UObject(), locale(Locale::getRoot()), currPattern(NULL) { *validLocale = *actualLocale = 0; initialize(); } @@ -166,6 +166,7 @@ DecimalFormatSymbols::operator=(const DecimalFormatSymbols& rhs) uprv_strcpy(actualLocale, rhs.actualLocale); fIsCustomCurrencySymbol = rhs.fIsCustomCurrencySymbol; fIsCustomIntlCurrencySymbol = rhs.fIsCustomIntlCurrencySymbol; + fCodePointZero = rhs.fCodePointZero; } return *this; } @@ -197,6 +198,7 @@ DecimalFormatSymbols::operator==(const DecimalFormatSymbols& that) const return FALSE; } } + // No need to check fCodePointZero since it is based on fSymbols return locale == that.locale && uprv_strcmp(validLocale, that.validLocale) == 0 && uprv_strcmp(actualLocale, that.actualLocale) == 0; @@ -342,11 +344,11 @@ CurrencySpacingSink::~CurrencySpacingSink() {} } // namespace void -DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool useLastResortData) +DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, + UBool useLastResortData, const NumberingSystem* ns) { if (U_FAILURE(status)) { return; } *validLocale = *actualLocale = 0; - currPattern = NULL; // First initialize all the symbols to the fallbacks for anything we can't find initialize(); @@ -355,7 +357,13 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us // Next get the numbering system for this locale and set zero digit // and the digit string based on the numbering system for the locale // - LocalPointer ns(NumberingSystem::createInstance(loc, status)); + LocalPointer nsLocal; + if (ns == nullptr) { + // Use the numbering system according to the locale. + // Save it into a LocalPointer so it gets cleaned up. + nsLocal.adoptInstead(NumberingSystem::createInstance(loc, status)); + ns = nsLocal.getAlias(); + } const char *nsName; if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) { nsName = ns->getName(); @@ -427,18 +435,37 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us // Let the monetary number separators equal the default number separators if necessary. sink.resolveMissingMonetarySeparators(fSymbols); + // Resolve codePointZero + UChar32 tempCodePointZero; + for (int32_t i=0; i<=9; i++) { + const UnicodeString& stringDigit = getConstDigitSymbol(i); + if (stringDigit.countChar32() != 1) { + tempCodePointZero = -1; + break; + } + UChar32 cp = stringDigit.char32At(0); + if (i == 0) { + tempCodePointZero = cp; + } else if (cp != tempCodePointZero + i) { + tempCodePointZero = -1; + break; + } + } + fCodePointZero = tempCodePointZero; + // Obtain currency data from the currency API. This is strictly // for backward compatibility; we don't use DecimalFormatSymbols // for currency data anymore. UErrorCode internalStatus = U_ZERO_ERROR; // don't propagate failures out UChar curriso[4]; UnicodeString tempStr; - ucurr_forLocale(locStr, curriso, 4, &internalStatus); - - uprv_getStaticCurrencyName(curriso, locStr, tempStr, internalStatus); - if (U_SUCCESS(internalStatus)) { - fSymbols[kIntlCurrencySymbol].setTo(curriso, -1); - fSymbols[kCurrencySymbol] = tempStr; + int32_t currisoLength = ucurr_forLocale(locStr, curriso, UPRV_LENGTHOF(curriso), &internalStatus); + if (U_SUCCESS(internalStatus) && currisoLength == 3) { + uprv_getStaticCurrencyName(curriso, locStr, tempStr, internalStatus); + if (U_SUCCESS(internalStatus)) { + fSymbols[kIntlCurrencySymbol].setTo(curriso, currisoLength); + fSymbols[kCurrencySymbol] = tempStr; + } } /* else use the default values. */ @@ -449,6 +476,7 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us UErrorCode localStatus = U_ZERO_ERROR; uccLen = ucurr_forLocale(locName, ucc, uccLen, &localStatus); + // TODO: Currency pattern data loading is duplicated in number_formatimpl.cpp if(U_SUCCESS(localStatus) && uccLen > 0) { char cc[4]={0}; u_UCharsToChars(ucc, cc, uccLen); @@ -523,6 +551,8 @@ DecimalFormatSymbols::initialize() { fSymbols[kExponentMultiplicationSymbol] = (UChar)0xd7; // 'x' multiplication symbol for exponents fIsCustomCurrencySymbol = FALSE; fIsCustomIntlCurrencySymbol = FALSE; + fCodePointZero = 0x30; + U_ASSERT(fCodePointZero == fSymbols[kZeroDigitSymbol].char32At(0)); }