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
15using namespace icu;
16using namespace icu::number;
17using namespace icu::number::impl;
18
19
20CurrencySymbols::CurrencySymbols(CurrencyUnit currency, const Locale& locale, UErrorCode& status)
21 : fCurrency(currency), fLocaleName(locale.getName(), status) {
22 fCurrencySymbol.setToBogus();
23 fIntlCurrencySymbol.setToBogus();
24}
25
26CurrencySymbols::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
38const char16_t* CurrencySymbols::getIsoCode() const {
39 return fCurrency.getISOCurrency();
40}
41
42UnicodeString 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
47UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const {
48 if (!fCurrencySymbol.isBogus()) {
49 return fCurrencySymbol;
50 }
51 return loadSymbol(UCURR_SYMBOL_NAME, status);
52}
53
54UnicodeString CurrencySymbols::loadSymbol(UCurrNameStyle selector, UErrorCode& status) const {
55 const char16_t* isoCode = fCurrency.getISOCurrency();
56 int32_t symbolLen = 0;
57 const char16_t* symbol = ucurr_getName(
58 isoCode,
59 fLocaleName.data(),
60 selector,
61 nullptr /* isChoiceFormat */,
62 &symbolLen,
63 &status);
64 // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely!
65 // Otherwise, symbol points to a resource bundle, and we can use readonly-aliasing constructor.
66 if (symbol == isoCode) {
67 return UnicodeString(isoCode, 3);
68 } else {
69 return UnicodeString(TRUE, symbol, symbolLen);
70 }
71}
72
73UnicodeString CurrencySymbols::getIntlCurrencySymbol(UErrorCode&) const {
74 if (!fIntlCurrencySymbol.isBogus()) {
75 return fIntlCurrencySymbol;
76 }
77 // Note: Not safe to use readonly-aliasing constructor here because the buffer belongs to this object,
78 // which could be destructed or moved during the lifetime of the return value.
79 return UnicodeString(fCurrency.getISOCurrency(), 3);
80}
81
82UnicodeString CurrencySymbols::getPluralName(StandardPlural::Form plural, UErrorCode& status) const {
83 const char16_t* isoCode = fCurrency.getISOCurrency();
84 int32_t symbolLen = 0;
85 const char16_t* symbol = ucurr_getPluralName(
86 isoCode,
87 fLocaleName.data(),
88 nullptr /* isChoiceFormat */,
89 StandardPlural::getKeyword(plural),
90 &symbolLen,
91 &status);
92 // If given an unknown currency, ucurr_getName returns the input string, which we can't alias safely!
93 // Otherwise, symbol points to a resource bundle, and we can use readonly-aliasing constructor.
94 if (symbol == isoCode) {
95 return UnicodeString(isoCode, 3);
96 } else {
97 return UnicodeString(TRUE, symbol, symbolLen);
98 }
99}
100
101
102CurrencyUnit
103icu::number::impl::resolveCurrency(const DecimalFormatProperties& properties, const Locale& locale,
104 UErrorCode& status) {
105 if (!properties.currency.isNull()) {
106 return properties.currency.getNoError();
107 } else {
108 UErrorCode localStatus = U_ZERO_ERROR;
109 char16_t buf[4] = {};
110 ucurr_forLocale(locale.getName(), buf, 4, &localStatus);
111 if (U_SUCCESS(localStatus)) {
112 return CurrencyUnit(buf, status);
113 } else {
114 // Default currency (XXX)
115 return CurrencyUnit();
116 }
117 }
118}
119
120
121#endif /* #if !UCONFIG_NO_FORMATTING */
122