number_currencysymbols.cpp 4.9 KB

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