number_currencysymbols.cpp (4975B)
1 // © 2018 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 4 #include "unicode/utypes.h" 5 6 #if !UCONFIG_NO_FORMATTING 7 8 // Allow implicit conversion from char16_t* to UnicodeString for this file: 9 // Helpful in toString methods and elsewhere. 10 #define UNISTR_FROM_STRING_EXPLICIT 11 12 #include "numparse_types.h" 13 #include "number_currencysymbols.h" 14 15 using namespace icu; 16 using namespace icu::number; 17 using namespace icu::number::impl; 18 19 20 CurrencySymbols::CurrencySymbols(CurrencyUnit currency, const Locale& locale, UErrorCode& status) 21 : fCurrency(currency), fLocaleName(locale.getName(), status) { 22 fCurrencySymbol.setToBogus(); 23 fIntlCurrencySymbol.setToBogus(); 24 } 25 26 CurrencySymbols::CurrencySymbols(CurrencyUnit currency, const Locale& locale, 27 const DecimalFormatSymbols& symbols, UErrorCode& status) 28 : CurrencySymbols(currency, locale, status) { 29 // If either of the overrides is present, save it in the local UnicodeString. 30 if (symbols.isCustomCurrencySymbol()) { 31 fCurrencySymbol = symbols.getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); 32 } 33 if (symbols.isCustomIntlCurrencySymbol()) { 34 fIntlCurrencySymbol = symbols.getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 35 } 36 } 37 38 const char16_t* CurrencySymbols::getIsoCode() const { 39 return fCurrency.getISOCurrency(); 40 } 41 42 UnicodeString CurrencySymbols::getNarrowCurrencySymbol(UErrorCode& status) const { 43 // Note: currently no override is available for narrow currency symbol 44 return loadSymbol(UCURR_NARROW_SYMBOL_NAME, status); 45 } 46 47 UnicodeString CurrencySymbols::getFormalCurrencySymbol(UErrorCode& status) const { 48 // Note: currently no override is available for formal currency symbol 49 return loadSymbol(UCURR_FORMAL_SYMBOL_NAME, status); 50 } 51 52 UnicodeString CurrencySymbols::getVariantCurrencySymbol(UErrorCode& status) const { 53 // Note: currently no override is available for variant currency symbol 54 return loadSymbol(UCURR_VARIANT_SYMBOL_NAME, status); 55 } 56 57 UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const { 58 if (!fCurrencySymbol.isBogus()) { 59 return fCurrencySymbol; 60 } 61 return loadSymbol(UCURR_SYMBOL_NAME, status); 62 } 63 64 UnicodeString CurrencySymbols::loadSymbol(UCurrNameStyle selector, UErrorCode& status) const { 65 const char16_t* isoCode = fCurrency.getISOCurrency(); 66 int32_t symbolLen = 0; 67 const char16_t* symbol = ucurr_getName( 68 isoCode, 69 fLocaleName.data(), 70 selector, 71 nullptr /* isChoiceFormat */, 72 &symbolLen, 73 &status); 74 // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely! 75 // Otherwise, symbol points to a resource bundle, and we can use readonly-aliasing constructor. 76 if (symbol == isoCode) { 77 return UnicodeString(isoCode, 3); 78 } else { 79 return UnicodeString(true, symbol, symbolLen); 80 } 81 } 82 83 UnicodeString CurrencySymbols::getIntlCurrencySymbol(UErrorCode&) const { 84 if (!fIntlCurrencySymbol.isBogus()) { 85 return fIntlCurrencySymbol; 86 } 87 // Note: Not safe to use readonly-aliasing constructor here because the buffer belongs to this object, 88 // which could be destructed or moved during the lifetime of the return value. 89 return UnicodeString(fCurrency.getISOCurrency(), 3); 90 } 91 92 UnicodeString CurrencySymbols::getPluralName(StandardPlural::Form plural, UErrorCode& status) const { 93 const char16_t* isoCode = fCurrency.getISOCurrency(); 94 int32_t symbolLen = 0; 95 const char16_t* symbol = ucurr_getPluralName( 96 isoCode, 97 fLocaleName.data(), 98 nullptr /* isChoiceFormat */, 99 StandardPlural::getKeyword(plural), 100 &symbolLen, 101 &status); 102 // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely! 103 // Otherwise, symbol points to a resource bundle, and we can use readonly-aliasing constructor. 104 if (symbol == isoCode) { 105 return UnicodeString(isoCode, 3); 106 } else { 107 return UnicodeString(true, symbol, symbolLen); 108 } 109 } 110 111 bool CurrencySymbols::hasEmptyCurrencySymbol() const { 112 return !fCurrencySymbol.isBogus() && fCurrencySymbol.isEmpty(); 113 } 114 115 116 CurrencyUnit 117 icu::number::impl::resolveCurrency(const DecimalFormatProperties& properties, const Locale& locale, 118 UErrorCode& status) { 119 if (!properties.currency.isNull()) { 120 return properties.currency.getNoError(); 121 } else { 122 UErrorCode localStatus = U_ZERO_ERROR; 123 char16_t buf[4] = {}; 124 ucurr_forLocale(locale.getName(), buf, 4, &localStatus); 125 if (U_SUCCESS(localStatus)) { 126 return CurrencyUnit(buf, status); 127 } else { 128 // Default currency (XXX) 129 return {}; 130 } 131 } 132 } 133 134 135 #endif /* #if !UCONFIG_NO_FORMATTING */