From: Shane Carr Date: Fri, 6 May 2016 23:06:26 +0000 (+0000) Subject: ICU-12521 Adding C++ version of DecimalFormatSymbols data loading sink. X-Git-Tag: milestone-59-0-1~448 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=29e5258904af46bdbf3c19108435ae2bc961def7;p=icu ICU-12521 Adding C++ version of DecimalFormatSymbols data loading sink. X-SVN-Rev: 38714 --- diff --git a/icu4c/source/i18n/dcfmtsym.cpp b/icu4c/source/i18n/dcfmtsym.cpp index 35d2f0d7562..25d9bc1df3e 100644 --- a/icu4c/source/i18n/dcfmtsym.cpp +++ b/icu4c/source/i18n/dcfmtsym.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 1997-2015, International Business Machines Corporation and +* Copyright (C) 1997-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -35,6 +35,7 @@ #include "locbased.h" #include "uresimp.h" #include "ureslocs.h" +#include "charstr.h" // ***************************************************************************** // class DecimalFormatSymbols @@ -51,10 +52,45 @@ static const char gAfterCurrencyTag[] = "afterCurrency"; static const char gCurrencyMatchTag[] = "currencyMatch"; static const char gCurrencySudMatchTag[] = "surroundingMatch"; static const char gCurrencyInsertBtnTag[] = "insertBetween"; - +static const char gLatn[] = "latn"; +static const char gSymbols[] = "symbols"; +static const char gNumberElementsLatnSymbols[] = "NumberElements/latn/symbols"; static const UChar INTL_CURRENCY_SYMBOL_STR[] = {0xa4, 0xa4, 0}; +// List of field names to be loaded from the data files. +// These are parallel with the enum ENumberFormatSymbol in unicode/dcfmtsym.h. +static const char *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] = { + "decimal", + "group", + "list", + "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 */ + "minusSign", + "plusSign", + NULL, /* currency symbol - Wait until we know the currency before loading from CLDR */ + NULL, /* intl currency symbol - Wait until we know the currency before loading from CLDR */ + "currencyDecimal", + "exponential", + "perMille", + NULL, /* Escape padding character - not in CLDR */ + "infinity", + "nan", + NULL, /* Significant digit symbol - not in CLDR */ + "currencyGroup", + NULL, /* one digit - get it from the numbering system */ + NULL, /* two digit - get it from the numbering system */ + NULL, /* three digit - get it from the numbering system */ + NULL, /* four digit - get it from the numbering system */ + NULL, /* five digit - get it from the numbering system */ + NULL, /* six digit - get it from the numbering system */ + NULL, /* seven digit - get it from the numbering system */ + NULL, /* eight digit - get it from the numbering system */ + NULL, /* nine digit - get it from the numbering system */ + "superscriptingExponent", /* Multiplication (x) symbol for exponents */ +}; + // ------------------------------------- // Initializes this with the decimal format symbols in the default locale. @@ -166,63 +202,84 @@ DecimalFormatSymbols::operator==(const DecimalFormatSymbols& that) const // ------------------------------------- +namespace { + +/** + * Sink for enumerating all of the decimal format symbols (more specifically, anything + * under the "NumberElements.symbols" tree). + * + * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root): + * Only store a value if it is still missing, that is, it has not been overridden. + */ +struct DecFmtSymDataSink : public ResourceSink { + + // Destination for data, modified via setters. + DecimalFormatSymbols& dfs; + // Boolean array of whether or not we have seen a particular symbol yet. + // Can't simpy check fSymbols because it is pre-populated with defaults. + UBool seenSymbol[DecimalFormatSymbols::kFormatSymbolCount] = { FALSE }; + + // Constructor/Destructor + DecFmtSymDataSink(DecimalFormatSymbols& _dfs) : dfs(_dfs) {} + virtual ~DecFmtSymDataSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, + UErrorCode &errorCode) { + ResourceTable symbolsTable = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t j = 0; symbolsTable.getKeyAndValue(j, key, value); ++j) { + for (int32_t i=0; i ns(NumberingSystem::createInstance(loc, status)); + const char *nsName; if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) { nsName = ns->getName(); UnicodeString digitString(ns->getDescription()); @@ -248,61 +305,61 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool us nsName = gLatn; } - UBool isLatn = !uprv_strcmp(nsName,gLatn); + // Open resource bundles + const char* locStr = loc.getName(); + LocalUResourceBundlePointer resource(ures_open(NULL, locStr, &status)); + LocalUResourceBundlePointer numberElementsRes( + ures_getByKeyWithFallback(resource.getAlias(), gNumberElements, NULL, &status)); - UErrorCode nlStatus = U_ZERO_ERROR; - LocalUResourceBundlePointer nonLatnSymbols; - if ( !isLatn ) { - nonLatnSymbols.adoptInstead( - ures_getByKeyWithFallback(numberElementsRes.getAlias(), nsName, NULL, &nlStatus)); - ures_getByKeyWithFallback(nonLatnSymbols.getAlias(), gSymbols, nonLatnSymbols.getAlias(), &nlStatus); + if (U_FAILURE(status)) { + if ( useLastResortData ) { + status = U_USING_DEFAULT_WARNING; + initialize(); + } + return; } - LocalUResourceBundlePointer latnSymbols( - ures_getByKeyWithFallback(numberElementsRes.getAlias(), gLatn, NULL, &status)); - ures_getByKeyWithFallback(latnSymbols.getAlias(), gSymbols, latnSymbols.getAlias(), &status); - - UBool kMonetaryDecimalSet = FALSE; - UBool kMonetaryGroupingSet = FALSE; - for(int32_t i = 0; i