// List of field names to be loaded from the data files. // These are parallel with the enum ENumberFormatSymbol in unicode/dcfmtsym.h. staticconstchar *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] = { "decimal", "group",
nullptr, /* #11897: the <list> symbol is NOT the pattern separator symbol */ "percentSign",
nullptr, /* Native zero digit is deprecated from CLDR - get it from the numbering system */
nullptr, /* Pattern digit character is deprecated from CLDR - use # by default always */ "minusSign", "plusSign",
nullptr, /* currency symbol - Wait until we know the currency before loading from CLDR */
nullptr, /* intl currency symbol - Wait until we know the currency before loading from CLDR */ "currencyDecimal", "exponential", "perMille",
nullptr, /* Escape padding character - not in CLDR */ "infinity", "nan",
nullptr, /* Significant digit symbol - not in CLDR */ "currencyGroup",
nullptr, /* one digit - get it from the numbering system */
nullptr, /* two digit - get it from the numbering system */
nullptr, /* three digit - get it from the numbering system */
nullptr, /* four digit - get it from the numbering system */
nullptr, /* five digit - get it from the numbering system */
nullptr, /* six digit - get it from the numbering system */
nullptr, /* seven digit - get it from the numbering system */
nullptr, /* eight digit - get it from the numbering system */
nullptr, /* nine digit - get it from the numbering system */ "superscriptingExponent", /* Multiplication (x) symbol for exponents */ "approximatelySign"/* Approximately sign symbol */
};
// ------------------------------------- // Initializes this with the decimal format symbols in the default locale.
DecimalFormatSymbols&
DecimalFormatSymbols::operator=(const DecimalFormatSymbols& rhs)
{ if (this != &rhs) { for (int32_t i = 0; i < static_cast<int32_t>(kFormatSymbolCount); ++i) { // fastCopyFrom is safe, see docs on fSymbols
fSymbols[static_cast<ENumberFormatSymbol>(i)].fastCopyFrom(rhs.fSymbols[static_cast<ENumberFormatSymbol>(i)]);
} for (int32_t i = 0; i < static_cast<int32_t>(UNUM_CURRENCY_SPACING_COUNT); ++i) {
currencySpcBeforeSym[i].fastCopyFrom(rhs.currencySpcBeforeSym[i]);
currencySpcAfterSym[i].fastCopyFrom(rhs.currencySpcAfterSym[i]);
}
locale = rhs.locale;
uprv_strcpy(validLocale, rhs.validLocale);
uprv_strcpy(actualLocale, rhs.actualLocale);
fIsCustomCurrencySymbol = rhs.fIsCustomCurrencySymbol;
fIsCustomIntlCurrencySymbol = rhs.fIsCustomIntlCurrencySymbol;
fCodePointZero = rhs.fCodePointZero;
currPattern = rhs.currPattern;
uprv_strcpy(nsName, rhs.nsName);
} return *this;
}
// -------------------------------------
bool
DecimalFormatSymbols::operator==(const DecimalFormatSymbols& that) const
{ if (this == &that) { returntrue;
} if (fIsCustomCurrencySymbol != that.fIsCustomCurrencySymbol) { returnfalse;
} if (fIsCustomIntlCurrencySymbol != that.fIsCustomIntlCurrencySymbol) { returnfalse;
} for (int32_t i = 0; i < static_cast<int32_t>(kFormatSymbolCount); ++i) { if (fSymbols[static_cast<ENumberFormatSymbol>(i)] != that.fSymbols[static_cast<ENumberFormatSymbol>(i)]) { returnfalse;
}
} for (int32_t i = 0; i < static_cast<int32_t>(UNUM_CURRENCY_SPACING_COUNT); ++i) { if(currencySpcBeforeSym[i] != that.currencySpcBeforeSym[i]) { returnfalse;
} if(currencySpcAfterSym[i] != that.currencySpcAfterSym[i]) { returnfalse;
}
} // 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;
}
// -------------------------------------
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 simply check fSymbols because it is pre-populated with defaults.
UBool seenSymbol[DecimalFormatSymbols::kFormatSymbolCount];
// Returns true if all the symbols have been seen.
UBool seenAll() { for (int32_t i=0; i<DecimalFormatSymbols::kFormatSymbolCount; i++) { if (!seenSymbol[i]) { returnfalse;
}
} returntrue;
}
// If monetary decimal or grouping were not explicitly set, then set them to be the // same as their non-monetary counterparts. void resolveMissingMonetarySeparators(const UnicodeString* fSymbols) { if (!seenSymbol[DecimalFormatSymbols::kMonetarySeparatorSymbol]) {
dfs.setSymbol(
DecimalFormatSymbols::kMonetarySeparatorSymbol,
fSymbols[DecimalFormatSymbols::kDecimalSeparatorSymbol]);
} if (!seenSymbol[DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol]) {
dfs.setSymbol(
DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol,
fSymbols[DecimalFormatSymbols::kGroupingSeparatorSymbol]);
}
}
};
// First initialize all the symbols to the fallbacks for anything we can't find
initialize();
// // 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<NumberingSystem> 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();
} constchar *nsName; if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) {
nsName = ns->getName();
UnicodeString digitString(ns->getDescription());
int32_t digitIndex = 0;
UChar32 digit = digitString.char32At(0);
fSymbols[kZeroDigitSymbol].setTo(digit); for (int32_t i = kOneDigitSymbol; i <= kNineDigitSymbol; ++i) {
digitIndex += U16_LENGTH(digit);
digit = digitString.char32At(digitIndex);
fSymbols[i].setTo(digit);
}
} else {
nsName = gLatn;
}
uprv_strcpy(this->nsName, nsName);
if (U_FAILURE(status)) { if ( useLastResortData ) {
status = U_USING_DEFAULT_WARNING;
initialize();
} return;
}
// Set locale IDs // TODO: Is there a way to do this without depending on the resource bundle instance?
U_LOCALE_BASED(locBased, *this);
locBased.setLocaleIDs(
ures_getLocaleByType(
numberElementsRes.getAlias(),
ULOC_VALID_LOCALE, &status),
ures_getLocaleByType(
numberElementsRes.getAlias(),
ULOC_ACTUAL_LOCALE, &status));
// Now load the rest of the data from the data sink. // Start with loading this nsName if it is not Latin.
DecFmtSymDataSink sink(*this); if (uprv_strcmp(nsName, gLatn) != 0) {
CharString path;
path.append(gNumberElements, status)
.append('/', status)
.append(nsName, status)
.append('/', status)
.append(gSymbols, status);
ures_getAllItemsWithFallback(resource.getAlias(), path.data(), sink, status);
// If no symbols exist for the given nsName and resource bundle, silently ignore // and fall back to Latin. if (status == U_MISSING_RESOURCE_ERROR) {
status = U_ZERO_ERROR;
} elseif (U_FAILURE(status)) { return;
}
}
// Continue with Latin if necessary. if (!sink.seenAll()) {
ures_getAllItemsWithFallback(resource.getAlias(), gNumberElementsLatnSymbols, sink, status); if (U_FAILURE(status)) { return; }
}
// Let the monetary number separators equal the default number separators if necessary.
sink.resolveMissingMonetarySeparators(fSymbols);
void DecimalFormatSymbols::setCurrency(const char16_t* currency, UErrorCode& status) { // TODO: If this method is made public: // - Adopt ICU4J behavior of not allowing currency to be null. // - Also verify that the length of currency is 3. if (!currency) { return;
}
/* An explicit currency was requested */ // TODO(ICU-13297): Move this data loading logic into a centralized place
UErrorCode localStatus = U_ZERO_ERROR;
LocalUResourceBundlePointer rbTop(ures_open(U_ICUDATA_CURR, locale.getName(), &localStatus));
LocalUResourceBundlePointer rb(
ures_getByKeyWithFallback(rbTop.getAlias(), "Currencies", nullptr, &localStatus));
ures_getByKeyWithFallback(rb.getAlias(), cc, rb.getAlias(), &localStatus); if(U_SUCCESS(localStatus) && ures_getSize(rb.getAlias())>2) { // the length is 3 if more data is present
ures_getByIndex(rb.getAlias(), 2, rb.getAlias(), &localStatus);
int32_t currPatternLen = 0;
currPattern =
ures_getStringByIndex(rb.getAlias(), static_cast<int32_t>(0), &currPatternLen, &localStatus);
UnicodeString decimalSep =
ures_getUnicodeStringByIndex(rb.getAlias(), static_cast<int32_t>(1), &localStatus);
UnicodeString groupingSep =
ures_getUnicodeStringByIndex(rb.getAlias(), static_cast<int32_t>(2), &localStatus); if(U_SUCCESS(localStatus)){
fSymbols[kMonetaryGroupingSeparatorSymbol] = groupingSep;
fSymbols[kMonetarySeparatorSymbol] = decimalSep; //pattern.setTo(true, currPattern, currPatternLen);
}
} /* else An explicit currency was requested and is unknown or locale data is malformed. */ /* ucurr_* API will get the correct value later on. */
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.