Coverage Report

Created: 2025-06-13 06:38

/src/icu/icu4c/source/i18n/number_currencysymbols.cpp
Line
Count
Source (jump to first uncovered line)
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
227k
        : fCurrency(currency), fLocaleName(locale.getName(), status) {
22
227k
    fCurrencySymbol.setToBogus();
23
227k
    fIntlCurrencySymbol.setToBogus();
24
227k
}
25
26
CurrencySymbols::CurrencySymbols(CurrencyUnit currency, const Locale& locale,
27
                                 const DecimalFormatSymbols& symbols, UErrorCode& status)
28
227k
        : CurrencySymbols(currency, locale, status) {
29
    // If either of the overrides is present, save it in the local UnicodeString.
30
227k
    if (symbols.isCustomCurrencySymbol()) {
31
0
        fCurrencySymbol = symbols.getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
32
0
    }
33
227k
    if (symbols.isCustomIntlCurrencySymbol()) {
34
0
        fIntlCurrencySymbol = symbols.getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
35
0
    }
36
227k
}
37
38
55.4k
const char16_t* CurrencySymbols::getIsoCode() const {
39
55.4k
    return fCurrency.getISOCurrency();
40
55.4k
}
41
42
0
UnicodeString CurrencySymbols::getNarrowCurrencySymbol(UErrorCode& status) const {
43
    // Note: currently no override is available for narrow currency symbol
44
0
    return loadSymbol(UCURR_NARROW_SYMBOL_NAME, status);
45
0
}
46
47
0
UnicodeString CurrencySymbols::getFormalCurrencySymbol(UErrorCode& status) const {
48
    // Note: currently no override is available for formal currency symbol
49
0
    return loadSymbol(UCURR_FORMAL_SYMBOL_NAME, status);
50
0
}
51
52
0
UnicodeString CurrencySymbols::getVariantCurrencySymbol(UErrorCode& status) const {
53
    // Note: currently no override is available for variant currency symbol
54
0
    return loadSymbol(UCURR_VARIANT_SYMBOL_NAME, status);
55
0
}
56
57
55.4k
UnicodeString CurrencySymbols::getCurrencySymbol(UErrorCode& status) const {
58
55.4k
    if (!fCurrencySymbol.isBogus()) {
59
0
        return fCurrencySymbol;
60
0
    }
61
55.4k
    return loadSymbol(UCURR_SYMBOL_NAME, status);
62
55.4k
}
63
64
55.4k
UnicodeString CurrencySymbols::loadSymbol(UCurrNameStyle selector, UErrorCode& status) const {
65
55.4k
    const char16_t* isoCode = fCurrency.getISOCurrency();
66
55.4k
    int32_t symbolLen = 0;
67
55.4k
    const char16_t* symbol = ucurr_getName(
68
55.4k
            isoCode,
69
55.4k
            fLocaleName.data(),
70
55.4k
            selector,
71
55.4k
            nullptr /* isChoiceFormat */,
72
55.4k
            &symbolLen,
73
55.4k
            &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
55.4k
    if (symbol == isoCode) {
77
696
        return UnicodeString(isoCode, 3);
78
54.7k
    } else {
79
54.7k
        return UnicodeString(true, symbol, symbolLen);
80
54.7k
    }
81
55.4k
}
82
83
55.4k
UnicodeString CurrencySymbols::getIntlCurrencySymbol(UErrorCode&) const {
84
55.4k
    if (!fIntlCurrencySymbol.isBogus()) {
85
0
        return fIntlCurrencySymbol;
86
0
    }
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
55.4k
    return UnicodeString(fCurrency.getISOCurrency(), 3);
90
55.4k
}
91
92
443k
UnicodeString CurrencySymbols::getPluralName(StandardPlural::Form plural, UErrorCode& status) const {
93
443k
    const char16_t* isoCode = fCurrency.getISOCurrency();
94
443k
    int32_t symbolLen = 0;
95
443k
    const char16_t* symbol = ucurr_getPluralName(
96
443k
            isoCode,
97
443k
            fLocaleName.data(),
98
443k
            nullptr /* isChoiceFormat */,
99
443k
            StandardPlural::getKeyword(plural),
100
443k
            &symbolLen,
101
443k
            &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
443k
    if (symbol == isoCode) {
105
5.56k
        return UnicodeString(isoCode, 3);
106
438k
    } else {
107
438k
        return UnicodeString(true, symbol, symbolLen);
108
438k
    }
109
443k
}
110
111
41.5k
bool CurrencySymbols::hasEmptyCurrencySymbol() const {
112
41.5k
    return !fCurrencySymbol.isBogus() && fCurrencySymbol.isEmpty();
113
41.5k
}
114
115
116
CurrencyUnit
117
icu::number::impl::resolveCurrency(const DecimalFormatProperties& properties, const Locale& locale,
118
118k
                                   UErrorCode& status) {
119
118k
    if (!properties.currency.isNull()) {
120
0
        return properties.currency.getNoError();
121
118k
    } else {
122
118k
        UErrorCode localStatus = U_ZERO_ERROR;
123
118k
        char16_t buf[4] = {};
124
118k
        ucurr_forLocale(locale.getName(), buf, 4, &localStatus);
125
118k
        if (U_SUCCESS(localStatus)) {
126
83.6k
            return CurrencyUnit(buf, status);
127
83.6k
        } else {
128
            // Default currency (XXX)
129
34.7k
            return {};
130
34.7k
        }
131
118k
    }
132
118k
}
133
134
135
#endif /* #if !UCONFIG_NO_FORMATTING */