1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 1997-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 *******************************************************************************
11 * Modification History:
13 * Date Name Description
14 * 02/19/97 aliu Converted from java.
15 * 03/18/97 clhuang Implemented with C++ APIs.
16 * 03/27/97 helena Updated to pass the simple test after code review.
17 * 08/26/97 aliu Added currency/intl currency symbol support.
18 * 07/20/98 stephen Slightly modified initialization of monetarySeparator
19 ********************************************************************************
22 #include "unicode/utypes.h"
24 #if !UCONFIG_NO_FORMATTING
26 #include "unicode/dcfmtsym.h"
27 #include "unicode/ures.h"
28 #include "unicode/decimfmt.h"
29 #include "unicode/ucurr.h"
30 #include "unicode/choicfmt.h"
31 #include "unicode/unistr.h"
32 #include "unicode/numsys.h"
33 #include "unicode/unum.h"
34 #include "unicode/utf16.h"
43 // *****************************************************************************
44 // class DecimalFormatSymbols
45 // *****************************************************************************
49 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormatSymbols
)
51 static const char gNumberElements
[] = "NumberElements";
52 static const char gCurrencySpacingTag
[] = "currencySpacing";
53 static const char gBeforeCurrencyTag
[] = "beforeCurrency";
54 static const char gAfterCurrencyTag
[] = "afterCurrency";
55 static const char gCurrencyMatchTag
[] = "currencyMatch";
56 static const char gCurrencySudMatchTag
[] = "surroundingMatch";
57 static const char gCurrencyInsertBtnTag
[] = "insertBetween";
58 static const char gLatn
[] = "latn";
59 static const char gSymbols
[] = "symbols";
60 static const char gNumberElementsLatnSymbols
[] = "NumberElements/latn/symbols";
62 static const UChar INTL_CURRENCY_SYMBOL_STR
[] = {0xa4, 0xa4, 0};
64 // List of field names to be loaded from the data files.
65 // These are parallel with the enum ENumberFormatSymbol in unicode/dcfmtsym.h.
66 static const char *gNumberElementKeys
[DecimalFormatSymbols::kFormatSymbolCount
] = {
69 NULL
, /* #11897: the <list> symbol is NOT the pattern separator symbol */
71 NULL
, /* Native zero digit is deprecated from CLDR - get it from the numbering system */
72 NULL
, /* Pattern digit character is deprecated from CLDR - use # by default always */
75 NULL
, /* currency symbol - Wait until we know the currency before loading from CLDR */
76 NULL
, /* intl currency symbol - Wait until we know the currency before loading from CLDR */
80 NULL
, /* Escape padding character - not in CLDR */
83 NULL
, /* Significant digit symbol - not in CLDR */
85 NULL
, /* one digit - get it from the numbering system */
86 NULL
, /* two digit - get it from the numbering system */
87 NULL
, /* three digit - get it from the numbering system */
88 NULL
, /* four digit - get it from the numbering system */
89 NULL
, /* five digit - get it from the numbering system */
90 NULL
, /* six digit - get it from the numbering system */
91 NULL
, /* seven digit - get it from the numbering system */
92 NULL
, /* eight digit - get it from the numbering system */
93 NULL
, /* nine digit - get it from the numbering system */
94 "superscriptingExponent", /* Multiplication (x) symbol for exponents */
97 // -------------------------------------
98 // Initializes this with the decimal format symbols in the default locale.
100 DecimalFormatSymbols::DecimalFormatSymbols(UErrorCode
& status
)
101 : UObject(), locale(), currPattern(NULL
) {
102 initialize(locale
, status
, TRUE
);
105 // -------------------------------------
106 // Initializes this with the decimal format symbols in the desired locale.
108 DecimalFormatSymbols::DecimalFormatSymbols(const Locale
& loc
, UErrorCode
& status
)
109 : UObject(), locale(loc
), currPattern(NULL
) {
110 initialize(locale
, status
);
113 DecimalFormatSymbols::DecimalFormatSymbols(const Locale
& loc
, const NumberingSystem
& ns
, UErrorCode
& status
)
114 : UObject(), locale(loc
), currPattern(NULL
) {
115 initialize(locale
, status
, FALSE
, &ns
);
118 DecimalFormatSymbols::DecimalFormatSymbols()
119 : UObject(), locale(Locale::getRoot()), currPattern(NULL
) {
120 *validLocale
= *actualLocale
= 0;
124 DecimalFormatSymbols
*
125 DecimalFormatSymbols::createWithLastResortData(UErrorCode
& status
) {
126 if (U_FAILURE(status
)) { return NULL
; }
127 DecimalFormatSymbols
* sym
= new DecimalFormatSymbols();
129 status
= U_MEMORY_ALLOCATION_ERROR
;
134 // -------------------------------------
136 DecimalFormatSymbols::~DecimalFormatSymbols()
140 // -------------------------------------
143 DecimalFormatSymbols::DecimalFormatSymbols(const DecimalFormatSymbols
&source
)
149 // -------------------------------------
150 // assignment operator
152 DecimalFormatSymbols
&
153 DecimalFormatSymbols::operator=(const DecimalFormatSymbols
& rhs
)
156 for(int32_t i
= 0; i
< (int32_t)kFormatSymbolCount
; ++i
) {
157 // fastCopyFrom is safe, see docs on fSymbols
158 fSymbols
[(ENumberFormatSymbol
)i
].fastCopyFrom(rhs
.fSymbols
[(ENumberFormatSymbol
)i
]);
160 for(int32_t i
= 0; i
< (int32_t)UNUM_CURRENCY_SPACING_COUNT
; ++i
) {
161 currencySpcBeforeSym
[i
].fastCopyFrom(rhs
.currencySpcBeforeSym
[i
]);
162 currencySpcAfterSym
[i
].fastCopyFrom(rhs
.currencySpcAfterSym
[i
]);
165 uprv_strcpy(validLocale
, rhs
.validLocale
);
166 uprv_strcpy(actualLocale
, rhs
.actualLocale
);
167 fIsCustomCurrencySymbol
= rhs
.fIsCustomCurrencySymbol
;
168 fIsCustomIntlCurrencySymbol
= rhs
.fIsCustomIntlCurrencySymbol
;
169 fCodePointZero
= rhs
.fCodePointZero
;
174 // -------------------------------------
177 DecimalFormatSymbols::operator==(const DecimalFormatSymbols
& that
) const
182 if (fIsCustomCurrencySymbol
!= that
.fIsCustomCurrencySymbol
) {
185 if (fIsCustomIntlCurrencySymbol
!= that
.fIsCustomIntlCurrencySymbol
) {
188 for(int32_t i
= 0; i
< (int32_t)kFormatSymbolCount
; ++i
) {
189 if(fSymbols
[(ENumberFormatSymbol
)i
] != that
.fSymbols
[(ENumberFormatSymbol
)i
]) {
193 for(int32_t i
= 0; i
< (int32_t)UNUM_CURRENCY_SPACING_COUNT
; ++i
) {
194 if(currencySpcBeforeSym
[i
] != that
.currencySpcBeforeSym
[i
]) {
197 if(currencySpcAfterSym
[i
] != that
.currencySpcAfterSym
[i
]) {
201 // No need to check fCodePointZero since it is based on fSymbols
202 return locale
== that
.locale
&&
203 uprv_strcmp(validLocale
, that
.validLocale
) == 0 &&
204 uprv_strcmp(actualLocale
, that
.actualLocale
) == 0;
207 // -------------------------------------
212 * Sink for enumerating all of the decimal format symbols (more specifically, anything
213 * under the "NumberElements.symbols" tree).
215 * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root):
216 * Only store a value if it is still missing, that is, it has not been overridden.
218 struct DecFmtSymDataSink
: public ResourceSink
{
220 // Destination for data, modified via setters.
221 DecimalFormatSymbols
& dfs
;
222 // Boolean array of whether or not we have seen a particular symbol yet.
223 // Can't simpy check fSymbols because it is pre-populated with defaults.
224 UBool seenSymbol
[DecimalFormatSymbols::kFormatSymbolCount
];
226 // Constructor/Destructor
227 DecFmtSymDataSink(DecimalFormatSymbols
& _dfs
) : dfs(_dfs
) {
228 uprv_memset(seenSymbol
, FALSE
, sizeof(seenSymbol
));
230 virtual ~DecFmtSymDataSink();
232 virtual void put(const char *key
, ResourceValue
&value
, UBool
/*noFallback*/,
233 UErrorCode
&errorCode
) {
234 ResourceTable symbolsTable
= value
.getTable(errorCode
);
235 if (U_FAILURE(errorCode
)) { return; }
236 for (int32_t j
= 0; symbolsTable
.getKeyAndValue(j
, key
, value
); ++j
) {
237 for (int32_t i
=0; i
<DecimalFormatSymbols::kFormatSymbolCount
; i
++) {
238 if (gNumberElementKeys
[i
] != NULL
&& uprv_strcmp(key
, gNumberElementKeys
[i
]) == 0) {
239 if (!seenSymbol
[i
]) {
240 seenSymbol
[i
] = TRUE
;
242 (DecimalFormatSymbols::ENumberFormatSymbol
) i
,
243 value
.getUnicodeString(errorCode
));
244 if (U_FAILURE(errorCode
)) { return; }
252 // Returns true if all the symbols have been seen.
254 for (int32_t i
=0; i
<DecimalFormatSymbols::kFormatSymbolCount
; i
++) {
255 if (!seenSymbol
[i
]) {
262 // If monetary decimal or grouping were not explicitly set, then set them to be the
263 // same as their non-monetary counterparts.
264 void resolveMissingMonetarySeparators(const UnicodeString
* fSymbols
) {
265 if (!seenSymbol
[DecimalFormatSymbols::kMonetarySeparatorSymbol
]) {
267 DecimalFormatSymbols::kMonetarySeparatorSymbol
,
268 fSymbols
[DecimalFormatSymbols::kDecimalSeparatorSymbol
]);
270 if (!seenSymbol
[DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
]) {
272 DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
,
273 fSymbols
[DecimalFormatSymbols::kGroupingSeparatorSymbol
]);
278 struct CurrencySpacingSink
: public ResourceSink
{
279 DecimalFormatSymbols
& dfs
;
280 UBool hasBeforeCurrency
;
281 UBool hasAfterCurrency
;
283 CurrencySpacingSink(DecimalFormatSymbols
& _dfs
)
284 : dfs(_dfs
), hasBeforeCurrency(FALSE
), hasAfterCurrency(FALSE
) {}
285 virtual ~CurrencySpacingSink();
287 virtual void put(const char *key
, ResourceValue
&value
, UBool
/*noFallback*/,
288 UErrorCode
&errorCode
) {
289 ResourceTable spacingTypesTable
= value
.getTable(errorCode
);
290 for (int32_t i
= 0; spacingTypesTable
.getKeyAndValue(i
, key
, value
); ++i
) {
291 UBool beforeCurrency
;
292 if (uprv_strcmp(key
, gBeforeCurrencyTag
) == 0) {
293 beforeCurrency
= TRUE
;
294 hasBeforeCurrency
= TRUE
;
295 } else if (uprv_strcmp(key
, gAfterCurrencyTag
) == 0) {
296 beforeCurrency
= FALSE
;
297 hasAfterCurrency
= TRUE
;
302 ResourceTable patternsTable
= value
.getTable(errorCode
);
303 for (int32_t j
= 0; patternsTable
.getKeyAndValue(j
, key
, value
); ++j
) {
304 UCurrencySpacing pattern
;
305 if (uprv_strcmp(key
, gCurrencyMatchTag
) == 0) {
306 pattern
= UNUM_CURRENCY_MATCH
;
307 } else if (uprv_strcmp(key
, gCurrencySudMatchTag
) == 0) {
308 pattern
= UNUM_CURRENCY_SURROUNDING_MATCH
;
309 } else if (uprv_strcmp(key
, gCurrencyInsertBtnTag
) == 0) {
310 pattern
= UNUM_CURRENCY_INSERT
;
315 const UnicodeString
& current
= dfs
.getPatternForCurrencySpacing(
316 pattern
, beforeCurrency
, errorCode
);
317 if (current
.isEmpty()) {
318 dfs
.setPatternForCurrencySpacing(
319 pattern
, beforeCurrency
, value
.getUnicodeString(errorCode
));
325 void resolveMissing() {
326 // For consistency with Java, this method overwrites everything with the defaults unless
327 // both beforeCurrency and afterCurrency were found in CLDR.
328 static const char* defaults
[] = { "[:letter:]", "[:digit:]", " " };
329 if (!hasBeforeCurrency
|| !hasAfterCurrency
) {
330 for (UBool beforeCurrency
= 0; beforeCurrency
<= TRUE
; beforeCurrency
++) {
331 for (int32_t pattern
= 0; pattern
< UNUM_CURRENCY_SPACING_COUNT
; pattern
++) {
332 dfs
.setPatternForCurrencySpacing((UCurrencySpacing
)pattern
,
333 beforeCurrency
, UnicodeString(defaults
[pattern
], -1, US_INV
));
340 // Virtual destructors must be defined out of line.
341 DecFmtSymDataSink::~DecFmtSymDataSink() {}
342 CurrencySpacingSink::~CurrencySpacingSink() {}
347 DecimalFormatSymbols::initialize(const Locale
& loc
, UErrorCode
& status
,
348 UBool useLastResortData
, const NumberingSystem
* ns
)
350 if (U_FAILURE(status
)) { return; }
351 *validLocale
= *actualLocale
= 0;
353 // First initialize all the symbols to the fallbacks for anything we can't find
357 // Next get the numbering system for this locale and set zero digit
358 // and the digit string based on the numbering system for the locale
360 LocalPointer
<NumberingSystem
> nsLocal
;
362 // Use the numbering system according to the locale.
363 // Save it into a LocalPointer so it gets cleaned up.
364 nsLocal
.adoptInstead(NumberingSystem::createInstance(loc
, status
));
365 ns
= nsLocal
.getAlias();
368 if (U_SUCCESS(status
) && ns
->getRadix() == 10 && !ns
->isAlgorithmic()) {
369 nsName
= ns
->getName();
370 UnicodeString
digitString(ns
->getDescription());
371 int32_t digitIndex
= 0;
372 UChar32 digit
= digitString
.char32At(0);
373 fSymbols
[kZeroDigitSymbol
].setTo(digit
);
374 for (int32_t i
= kOneDigitSymbol
; i
<= kNineDigitSymbol
; ++i
) {
375 digitIndex
+= U16_LENGTH(digit
);
376 digit
= digitString
.char32At(digitIndex
);
377 fSymbols
[i
].setTo(digit
);
383 // Open resource bundles
384 const char* locStr
= loc
.getName();
385 LocalUResourceBundlePointer
resource(ures_open(NULL
, locStr
, &status
));
386 LocalUResourceBundlePointer
numberElementsRes(
387 ures_getByKeyWithFallback(resource
.getAlias(), gNumberElements
, NULL
, &status
));
389 if (U_FAILURE(status
)) {
390 if ( useLastResortData
) {
391 status
= U_USING_DEFAULT_WARNING
;
398 // TODO: Is there a way to do this without depending on the resource bundle instance?
399 U_LOCALE_BASED(locBased
, *this);
400 locBased
.setLocaleIDs(
401 ures_getLocaleByType(
402 numberElementsRes
.getAlias(),
403 ULOC_VALID_LOCALE
, &status
),
404 ures_getLocaleByType(
405 numberElementsRes
.getAlias(),
406 ULOC_ACTUAL_LOCALE
, &status
));
408 // Now load the rest of the data from the data sink.
409 // Start with loading this nsName if it is not Latin.
410 DecFmtSymDataSink
sink(*this);
411 if (uprv_strcmp(nsName
, gLatn
) != 0) {
413 path
.append(gNumberElements
, status
)
415 .append(nsName
, status
)
417 .append(gSymbols
, status
);
418 ures_getAllItemsWithFallback(resource
.getAlias(), path
.data(), sink
, status
);
420 // If no symbols exist for the given nsName and resource bundle, silently ignore
421 // and fall back to Latin.
422 if (status
== U_MISSING_RESOURCE_ERROR
) {
423 status
= U_ZERO_ERROR
;
424 } else if (U_FAILURE(status
)) {
429 // Continue with Latin if necessary.
430 if (!sink
.seenAll()) {
431 ures_getAllItemsWithFallback(resource
.getAlias(), gNumberElementsLatnSymbols
, sink
, status
);
432 if (U_FAILURE(status
)) { return; }
435 // Let the monetary number separators equal the default number separators if necessary.
436 sink
.resolveMissingMonetarySeparators(fSymbols
);
438 // Resolve codePointZero
439 UChar32 tempCodePointZero
;
440 for (int32_t i
=0; i
<=9; i
++) {
441 const UnicodeString
& stringDigit
= getConstDigitSymbol(i
);
442 if (stringDigit
.countChar32() != 1) {
443 tempCodePointZero
= -1;
446 UChar32 cp
= stringDigit
.char32At(0);
448 tempCodePointZero
= cp
;
449 } else if (cp
!= tempCodePointZero
+ i
) {
450 tempCodePointZero
= -1;
454 fCodePointZero
= tempCodePointZero
;
456 // Obtain currency data from the currency API. This is strictly
457 // for backward compatibility; we don't use DecimalFormatSymbols
458 // for currency data anymore.
459 UErrorCode internalStatus
= U_ZERO_ERROR
; // don't propagate failures out
461 UnicodeString tempStr
;
462 int32_t currisoLength
= ucurr_forLocale(locStr
, curriso
, UPRV_LENGTHOF(curriso
), &internalStatus
);
463 if (U_SUCCESS(internalStatus
) && currisoLength
== 3) {
464 uprv_getStaticCurrencyName(curriso
, locStr
, tempStr
, internalStatus
);
465 if (U_SUCCESS(internalStatus
)) {
466 fSymbols
[kIntlCurrencySymbol
].setTo(curriso
, currisoLength
);
467 fSymbols
[kCurrencySymbol
] = tempStr
;
470 /* else use the default values. */
472 //load the currency data
473 UChar ucc
[4]={0}; //Currency Codes are always 3 chars long
475 const char* locName
= loc
.getName();
476 UErrorCode localStatus
= U_ZERO_ERROR
;
477 uccLen
= ucurr_forLocale(locName
, ucc
, uccLen
, &localStatus
);
479 // TODO: Currency pattern data loading is duplicated in number_formatimpl.cpp
480 if(U_SUCCESS(localStatus
) && uccLen
> 0) {
482 u_UCharsToChars(ucc
, cc
, uccLen
);
483 /* An explicit currency was requested */
484 LocalUResourceBundlePointer
currencyResource(ures_open(U_ICUDATA_CURR
, locStr
, &localStatus
));
485 LocalUResourceBundlePointer
currency(
486 ures_getByKeyWithFallback(currencyResource
.getAlias(), "Currencies", NULL
, &localStatus
));
487 ures_getByKeyWithFallback(currency
.getAlias(), cc
, currency
.getAlias(), &localStatus
);
488 if(U_SUCCESS(localStatus
) && ures_getSize(currency
.getAlias())>2) { // the length is 3 if more data is present
489 ures_getByIndex(currency
.getAlias(), 2, currency
.getAlias(), &localStatus
);
490 int32_t currPatternLen
= 0;
492 ures_getStringByIndex(currency
.getAlias(), (int32_t)0, &currPatternLen
, &localStatus
);
493 UnicodeString decimalSep
=
494 ures_getUnicodeStringByIndex(currency
.getAlias(), (int32_t)1, &localStatus
);
495 UnicodeString groupingSep
=
496 ures_getUnicodeStringByIndex(currency
.getAlias(), (int32_t)2, &localStatus
);
497 if(U_SUCCESS(localStatus
)){
498 fSymbols
[kMonetaryGroupingSeparatorSymbol
] = groupingSep
;
499 fSymbols
[kMonetarySeparatorSymbol
] = decimalSep
;
500 //pattern.setTo(TRUE, currPattern, currPatternLen);
501 status
= localStatus
;
504 /* else An explicit currency was requested and is unknown or locale data is malformed. */
505 /* ucurr_* API will get the correct value later on. */
507 // else ignore the error if no currency
510 LocalUResourceBundlePointer
currencyResource(ures_open(U_ICUDATA_CURR
, locStr
, &status
));
511 CurrencySpacingSink
currencySink(*this);
512 ures_getAllItemsWithFallback(currencyResource
.getAlias(), gCurrencySpacingTag
, currencySink
, status
);
513 currencySink
.resolveMissing();
514 if (U_FAILURE(status
)) { return; }
518 DecimalFormatSymbols::initialize() {
520 * These strings used to be in static arrays, but the HP/UX aCC compiler
521 * cannot initialize a static array with class constructors.
524 fSymbols
[kDecimalSeparatorSymbol
] = (UChar
)0x2e; // '.' decimal separator
525 fSymbols
[kGroupingSeparatorSymbol
].remove(); // group (thousands) separator
526 fSymbols
[kPatternSeparatorSymbol
] = (UChar
)0x3b; // ';' pattern separator
527 fSymbols
[kPercentSymbol
] = (UChar
)0x25; // '%' percent sign
528 fSymbols
[kZeroDigitSymbol
] = (UChar
)0x30; // '0' native 0 digit
529 fSymbols
[kOneDigitSymbol
] = (UChar
)0x31; // '1' native 1 digit
530 fSymbols
[kTwoDigitSymbol
] = (UChar
)0x32; // '2' native 2 digit
531 fSymbols
[kThreeDigitSymbol
] = (UChar
)0x33; // '3' native 3 digit
532 fSymbols
[kFourDigitSymbol
] = (UChar
)0x34; // '4' native 4 digit
533 fSymbols
[kFiveDigitSymbol
] = (UChar
)0x35; // '5' native 5 digit
534 fSymbols
[kSixDigitSymbol
] = (UChar
)0x36; // '6' native 6 digit
535 fSymbols
[kSevenDigitSymbol
] = (UChar
)0x37; // '7' native 7 digit
536 fSymbols
[kEightDigitSymbol
] = (UChar
)0x38; // '8' native 8 digit
537 fSymbols
[kNineDigitSymbol
] = (UChar
)0x39; // '9' native 9 digit
538 fSymbols
[kDigitSymbol
] = (UChar
)0x23; // '#' pattern digit
539 fSymbols
[kPlusSignSymbol
] = (UChar
)0x002b; // '+' plus sign
540 fSymbols
[kMinusSignSymbol
] = (UChar
)0x2d; // '-' minus sign
541 fSymbols
[kCurrencySymbol
] = (UChar
)0xa4; // 'OX' currency symbol
542 fSymbols
[kIntlCurrencySymbol
].setTo(TRUE
, INTL_CURRENCY_SYMBOL_STR
, 2);
543 fSymbols
[kMonetarySeparatorSymbol
] = (UChar
)0x2e; // '.' monetary decimal separator
544 fSymbols
[kExponentialSymbol
] = (UChar
)0x45; // 'E' exponential
545 fSymbols
[kPerMillSymbol
] = (UChar
)0x2030; // '%o' per mill
546 fSymbols
[kPadEscapeSymbol
] = (UChar
)0x2a; // '*' pad escape symbol
547 fSymbols
[kInfinitySymbol
] = (UChar
)0x221e; // 'oo' infinite
548 fSymbols
[kNaNSymbol
] = (UChar
)0xfffd; // SUB NaN
549 fSymbols
[kSignificantDigitSymbol
] = (UChar
)0x0040; // '@' significant digit
550 fSymbols
[kMonetaryGroupingSeparatorSymbol
].remove(); //
551 fSymbols
[kExponentMultiplicationSymbol
] = (UChar
)0xd7; // 'x' multiplication symbol for exponents
552 fIsCustomCurrencySymbol
= FALSE
;
553 fIsCustomIntlCurrencySymbol
= FALSE
;
554 fCodePointZero
= 0x30;
555 U_ASSERT(fCodePointZero
== fSymbols
[kZeroDigitSymbol
].char32At(0));
560 DecimalFormatSymbols::getLocale(ULocDataLocaleType type
, UErrorCode
& status
) const {
561 U_LOCALE_BASED(locBased
, *this);
562 return locBased
.getLocale(type
, status
);
566 DecimalFormatSymbols::getPatternForCurrencySpacing(UCurrencySpacing type
,
567 UBool beforeCurrency
,
568 UErrorCode
& status
) const {
569 if (U_FAILURE(status
)) {
570 return fNoSymbol
; // always empty.
572 if (beforeCurrency
) {
573 return currencySpcBeforeSym
[(int32_t)type
];
575 return currencySpcAfterSym
[(int32_t)type
];
580 DecimalFormatSymbols::setPatternForCurrencySpacing(UCurrencySpacing type
,
581 UBool beforeCurrency
,
582 const UnicodeString
& pattern
) {
583 if (beforeCurrency
) {
584 currencySpcBeforeSym
[(int32_t)type
] = pattern
;
586 currencySpcAfterSym
[(int32_t)type
] = pattern
;
591 #endif /* #if !UCONFIG_NO_FORMATTING */