]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/dcfmtsym.cpp
ICU-59180.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / dcfmtsym.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f
A
3/*
4*******************************************************************************
f3c0d7a5 5* Copyright (C) 1997-2016, International Business Machines Corporation and
57a6839d 6* others. All Rights Reserved.
b75a7d8f
A
7*******************************************************************************
8*
9* File DCFMTSYM.CPP
10*
11* Modification History:
12*
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.
374ca955 18* 07/20/98 stephen Slightly modified initialization of monetarySeparator
b75a7d8f
A
19********************************************************************************
20*/
729e4ab9 21
b75a7d8f
A
22#include "unicode/utypes.h"
23
24#if !UCONFIG_NO_FORMATTING
25
26#include "unicode/dcfmtsym.h"
374ca955 27#include "unicode/ures.h"
b75a7d8f
A
28#include "unicode/decimfmt.h"
29#include "unicode/ucurr.h"
30#include "unicode/choicfmt.h"
729e4ab9
A
31#include "unicode/unistr.h"
32#include "unicode/numsys.h"
4388f060 33#include "unicode/unum.h"
57a6839d 34#include "unicode/utf16.h"
374ca955
A
35#include "ucurrimp.h"
36#include "cstring.h"
37#include "locbased.h"
73c04bcf 38#include "uresimp.h"
729e4ab9 39#include "ureslocs.h"
f3c0d7a5 40#include "charstr.h"
729e4ab9 41
b75a7d8f
A
42// *****************************************************************************
43// class DecimalFormatSymbols
44// *****************************************************************************
729e4ab9 45
b75a7d8f
A
46U_NAMESPACE_BEGIN
47
374ca955 48UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormatSymbols)
b75a7d8f 49
374ca955 50static const char gNumberElements[] = "NumberElements";
729e4ab9
A
51static const char gCurrencySpacingTag[] = "currencySpacing";
52static const char gBeforeCurrencyTag[] = "beforeCurrency";
53static const char gAfterCurrencyTag[] = "afterCurrency";
54static const char gCurrencyMatchTag[] = "currencyMatch";
55static const char gCurrencySudMatchTag[] = "surroundingMatch";
56static const char gCurrencyInsertBtnTag[] = "insertBetween";
f3c0d7a5
A
57static const char gLatn[] = "latn";
58static const char gSymbols[] = "symbols";
59static const char gNumberElementsLatnSymbols[] = "NumberElements/latn/symbols";
b75a7d8f
A
60
61static const UChar INTL_CURRENCY_SYMBOL_STR[] = {0xa4, 0xa4, 0};
62
f3c0d7a5
A
63// List of field names to be loaded from the data files.
64// These are parallel with the enum ENumberFormatSymbol in unicode/dcfmtsym.h.
65static const char *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] = {
66 "decimal",
67 "group",
68 "list",
69 "percentSign",
70 NULL, /* Native zero digit is deprecated from CLDR - get it from the numbering system */
71 NULL, /* Pattern digit character is deprecated from CLDR - use # by default always */
72 "minusSign",
73 "plusSign",
74 NULL, /* currency symbol - Wait until we know the currency before loading from CLDR */
75 NULL, /* intl currency symbol - Wait until we know the currency before loading from CLDR */
76 "currencyDecimal",
77 "exponential",
78 "perMille",
79 NULL, /* Escape padding character - not in CLDR */
80 "infinity",
81 "nan",
82 NULL, /* Significant digit symbol - not in CLDR */
83 "currencyGroup",
84 NULL, /* one digit - get it from the numbering system */
85 NULL, /* two digit - get it from the numbering system */
86 NULL, /* three digit - get it from the numbering system */
87 NULL, /* four digit - get it from the numbering system */
88 NULL, /* five digit - get it from the numbering system */
89 NULL, /* six digit - get it from the numbering system */
90 NULL, /* seven digit - get it from the numbering system */
91 NULL, /* eight digit - get it from the numbering system */
92 NULL, /* nine digit - get it from the numbering system */
93 "superscriptingExponent", /* Multiplication (x) symbol for exponents */
94};
95
b75a7d8f
A
96// -------------------------------------
97// Initializes this with the decimal format symbols in the default locale.
729e4ab9 98
b75a7d8f 99DecimalFormatSymbols::DecimalFormatSymbols(UErrorCode& status)
374ca955
A
100 : UObject(),
101 locale()
b75a7d8f 102{
374ca955 103 initialize(locale, status, TRUE);
b75a7d8f 104}
729e4ab9 105
b75a7d8f
A
106// -------------------------------------
107// Initializes this with the decimal format symbols in the desired locale.
729e4ab9 108
b75a7d8f 109DecimalFormatSymbols::DecimalFormatSymbols(const Locale& loc, UErrorCode& status)
374ca955
A
110 : UObject(),
111 locale(loc)
b75a7d8f 112{
374ca955 113 initialize(locale, status);
b75a7d8f 114}
729e4ab9 115
57a6839d
A
116DecimalFormatSymbols::DecimalFormatSymbols()
117 : UObject(),
118 locale(Locale::getRoot()),
119 currPattern(NULL) {
120 *validLocale = *actualLocale = 0;
121 initialize();
122}
123
124DecimalFormatSymbols*
125DecimalFormatSymbols::createWithLastResortData(UErrorCode& status) {
126 if (U_FAILURE(status)) { return NULL; }
127 DecimalFormatSymbols* sym = new DecimalFormatSymbols();
128 if (sym == NULL) {
129 status = U_MEMORY_ALLOCATION_ERROR;
130 }
131 return sym;
132}
133
b75a7d8f
A
134// -------------------------------------
135
136DecimalFormatSymbols::~DecimalFormatSymbols()
137{
138}
139
140// -------------------------------------
141// copy constructor
142
143DecimalFormatSymbols::DecimalFormatSymbols(const DecimalFormatSymbols &source)
144 : UObject(source)
145{
374ca955 146 *this = source;
b75a7d8f
A
147}
148
149// -------------------------------------
150// assignment operator
151
152DecimalFormatSymbols&
153DecimalFormatSymbols::operator=(const DecimalFormatSymbols& rhs)
154{
374ca955
A
155 if (this != &rhs) {
156 for(int32_t i = 0; i < (int32_t)kFormatSymbolCount; ++i) {
b75a7d8f
A
157 // fastCopyFrom is safe, see docs on fSymbols
158 fSymbols[(ENumberFormatSymbol)i].fastCopyFrom(rhs.fSymbols[(ENumberFormatSymbol)i]);
159 }
4388f060 160 for(int32_t i = 0; i < (int32_t)UNUM_CURRENCY_SPACING_COUNT; ++i) {
729e4ab9
A
161 currencySpcBeforeSym[i].fastCopyFrom(rhs.currencySpcBeforeSym[i]);
162 currencySpcAfterSym[i].fastCopyFrom(rhs.currencySpcAfterSym[i]);
163 }
374ca955
A
164 locale = rhs.locale;
165 uprv_strcpy(validLocale, rhs.validLocale);
166 uprv_strcpy(actualLocale, rhs.actualLocale);
2ca993e8
A
167 fIsCustomCurrencySymbol = rhs.fIsCustomCurrencySymbol;
168 fIsCustomIntlCurrencySymbol = rhs.fIsCustomIntlCurrencySymbol;
b75a7d8f
A
169 }
170 return *this;
171}
172
173// -------------------------------------
174
175UBool
176DecimalFormatSymbols::operator==(const DecimalFormatSymbols& that) const
177{
178 if (this == &that) {
179 return TRUE;
180 }
2ca993e8
A
181 if (fIsCustomCurrencySymbol != that.fIsCustomCurrencySymbol) {
182 return FALSE;
183 }
184 if (fIsCustomIntlCurrencySymbol != that.fIsCustomIntlCurrencySymbol) {
185 return FALSE;
186 }
374ca955 187 for(int32_t i = 0; i < (int32_t)kFormatSymbolCount; ++i) {
b75a7d8f
A
188 if(fSymbols[(ENumberFormatSymbol)i] != that.fSymbols[(ENumberFormatSymbol)i]) {
189 return FALSE;
190 }
191 }
4388f060 192 for(int32_t i = 0; i < (int32_t)UNUM_CURRENCY_SPACING_COUNT; ++i) {
729e4ab9
A
193 if(currencySpcBeforeSym[i] != that.currencySpcBeforeSym[i]) {
194 return FALSE;
195 }
196 if(currencySpcAfterSym[i] != that.currencySpcAfterSym[i]) {
197 return FALSE;
198 }
199 }
374ca955
A
200 return locale == that.locale &&
201 uprv_strcmp(validLocale, that.validLocale) == 0 &&
202 uprv_strcmp(actualLocale, that.actualLocale) == 0;
b75a7d8f 203}
729e4ab9 204
b75a7d8f 205// -------------------------------------
729e4ab9 206
f3c0d7a5
A
207namespace {
208
209/**
210 * Sink for enumerating all of the decimal format symbols (more specifically, anything
211 * under the "NumberElements.symbols" tree).
212 *
213 * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root):
214 * Only store a value if it is still missing, that is, it has not been overridden.
215 */
216struct DecFmtSymDataSink : public ResourceSink {
217
218 // Destination for data, modified via setters.
219 DecimalFormatSymbols& dfs;
220 // Boolean array of whether or not we have seen a particular symbol yet.
221 // Can't simpy check fSymbols because it is pre-populated with defaults.
222 UBool seenSymbol[DecimalFormatSymbols::kFormatSymbolCount];
223
224 // Constructor/Destructor
225 DecFmtSymDataSink(DecimalFormatSymbols& _dfs) : dfs(_dfs) {
226 uprv_memset(seenSymbol, FALSE, sizeof(seenSymbol));
227 }
228 virtual ~DecFmtSymDataSink();
229
230 virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/,
231 UErrorCode &errorCode) {
232 ResourceTable symbolsTable = value.getTable(errorCode);
233 if (U_FAILURE(errorCode)) { return; }
234 for (int32_t j = 0; symbolsTable.getKeyAndValue(j, key, value); ++j) {
235 for (int32_t i=0; i<DecimalFormatSymbols::kFormatSymbolCount; i++) {
236 if (gNumberElementKeys[i] != NULL && uprv_strcmp(key, gNumberElementKeys[i]) == 0) {
237 if (!seenSymbol[i]) {
238 seenSymbol[i] = TRUE;
239 dfs.setSymbol(
240 (DecimalFormatSymbols::ENumberFormatSymbol) i,
241 value.getUnicodeString(errorCode));
242 if (U_FAILURE(errorCode)) { return; }
243 }
244 break;
245 }
246 }
247 }
248 }
729e4ab9 249
f3c0d7a5
A
250 // Returns true if all the symbols have been seen.
251 UBool seenAll() {
252 for (int32_t i=0; i<DecimalFormatSymbols::kFormatSymbolCount; i++) {
253 if (!seenSymbol[i]) {
254 return FALSE;
255 }
256 }
257 return TRUE;
258 }
729e4ab9 259
f3c0d7a5
A
260 // If monetary decimal or grouping were not explicitly set, then set them to be the
261 // same as their non-monetary counterparts.
262 void resolveMissingMonetarySeparators(const UnicodeString* fSymbols) {
263 if (!seenSymbol[DecimalFormatSymbols::kMonetarySeparatorSymbol]) {
264 dfs.setSymbol(
265 DecimalFormatSymbols::kMonetarySeparatorSymbol,
266 fSymbols[DecimalFormatSymbols::kDecimalSeparatorSymbol]);
267 }
268 if (!seenSymbol[DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol]) {
269 dfs.setSymbol(
270 DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol,
271 fSymbols[DecimalFormatSymbols::kGroupingSeparatorSymbol]);
272 }
273 }
274};
275
276struct CurrencySpacingSink : public ResourceSink {
277 DecimalFormatSymbols& dfs;
278 UBool hasBeforeCurrency;
279 UBool hasAfterCurrency;
280
281 CurrencySpacingSink(DecimalFormatSymbols& _dfs)
282 : dfs(_dfs), hasBeforeCurrency(FALSE), hasAfterCurrency(FALSE) {}
283 virtual ~CurrencySpacingSink();
284
285 virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/,
286 UErrorCode &errorCode) {
287 ResourceTable spacingTypesTable = value.getTable(errorCode);
288 for (int32_t i = 0; spacingTypesTable.getKeyAndValue(i, key, value); ++i) {
289 UBool beforeCurrency;
290 if (uprv_strcmp(key, gBeforeCurrencyTag) == 0) {
291 beforeCurrency = TRUE;
292 hasBeforeCurrency = TRUE;
293 } else if (uprv_strcmp(key, gAfterCurrencyTag) == 0) {
294 beforeCurrency = FALSE;
295 hasAfterCurrency = TRUE;
296 } else {
297 continue;
298 }
729e4ab9 299
f3c0d7a5
A
300 ResourceTable patternsTable = value.getTable(errorCode);
301 for (int32_t j = 0; patternsTable.getKeyAndValue(j, key, value); ++j) {
302 UCurrencySpacing pattern;
303 if (uprv_strcmp(key, gCurrencyMatchTag) == 0) {
304 pattern = UNUM_CURRENCY_MATCH;
305 } else if (uprv_strcmp(key, gCurrencySudMatchTag) == 0) {
306 pattern = UNUM_CURRENCY_SURROUNDING_MATCH;
307 } else if (uprv_strcmp(key, gCurrencyInsertBtnTag) == 0) {
308 pattern = UNUM_CURRENCY_INSERT;
309 } else {
310 continue;
311 }
312
313 const UnicodeString& current = dfs.getPatternForCurrencySpacing(
314 pattern, beforeCurrency, errorCode);
315 if (current.isEmpty()) {
316 dfs.setPatternForCurrencySpacing(
317 pattern, beforeCurrency, value.getUnicodeString(errorCode));
318 }
319 }
320 }
321 }
322
323 void resolveMissing() {
324 // For consistency with Java, this method overwrites everything with the defaults unless
325 // both beforeCurrency and afterCurrency were found in CLDR.
326 static const char* defaults[] = { "[:letter:]", "[:digit:]", " " };
327 if (!hasBeforeCurrency || !hasAfterCurrency) {
328 for (UBool beforeCurrency = 0; beforeCurrency <= TRUE; beforeCurrency++) {
329 for (int32_t pattern = 0; pattern < UNUM_CURRENCY_SPACING_COUNT; pattern++) {
330 dfs.setPatternForCurrencySpacing((UCurrencySpacing)pattern,
331 beforeCurrency, UnicodeString(defaults[pattern], -1, US_INV));
332 }
333 }
b75a7d8f 334 }
57a6839d 335 }
f3c0d7a5
A
336};
337
338// Virtual destructors must be defined out of line.
339DecFmtSymDataSink::~DecFmtSymDataSink() {}
340CurrencySpacingSink::~CurrencySpacingSink() {}
341
342} // namespace
343
344void
345DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status, UBool useLastResortData)
346{
347 if (U_FAILURE(status)) { return; }
348 *validLocale = *actualLocale = 0;
349 currPattern = NULL;
729e4ab9 350
57a6839d
A
351 // First initialize all the symbols to the fallbacks for anything we can't find
352 initialize();
353
354 //
355 // Next get the numbering system for this locale and set zero digit
356 // and the digit string based on the numbering system for the locale
357 //
57a6839d 358 LocalPointer<NumberingSystem> ns(NumberingSystem::createInstance(loc, status));
f3c0d7a5 359 const char *nsName;
57a6839d
A
360 if (U_SUCCESS(status) && ns->getRadix() == 10 && !ns->isAlgorithmic()) {
361 nsName = ns->getName();
362 UnicodeString digitString(ns->getDescription());
363 int32_t digitIndex = 0;
364 UChar32 digit = digitString.char32At(0);
365 fSymbols[kZeroDigitSymbol].setTo(digit);
366 for (int32_t i = kOneDigitSymbol; i <= kNineDigitSymbol; ++i) {
367 digitIndex += U16_LENGTH(digit);
368 digit = digitString.char32At(digitIndex);
369 fSymbols[i].setTo(digit);
374ca955 370 }
57a6839d
A
371 } else {
372 nsName = gLatn;
373 }
b75a7d8f 374
f3c0d7a5
A
375 // Open resource bundles
376 const char* locStr = loc.getName();
377 LocalUResourceBundlePointer resource(ures_open(NULL, locStr, &status));
378 LocalUResourceBundlePointer numberElementsRes(
379 ures_getByKeyWithFallback(resource.getAlias(), gNumberElements, NULL, &status));
57a6839d 380
f3c0d7a5
A
381 if (U_FAILURE(status)) {
382 if ( useLastResortData ) {
383 status = U_USING_DEFAULT_WARNING;
384 initialize();
385 }
386 return;
57a6839d 387 }
729e4ab9 388
f3c0d7a5
A
389 // Set locale IDs
390 // TODO: Is there a way to do this without depending on the resource bundle instance?
391 U_LOCALE_BASED(locBased, *this);
392 locBased.setLocaleIDs(
393 ures_getLocaleByType(
394 numberElementsRes.getAlias(),
395 ULOC_VALID_LOCALE, &status),
396 ures_getLocaleByType(
397 numberElementsRes.getAlias(),
398 ULOC_ACTUAL_LOCALE, &status));
399
400 // Now load the rest of the data from the data sink.
401 // Start with loading this nsName if it is not Latin.
402 DecFmtSymDataSink sink(*this);
403 if (uprv_strcmp(nsName, gLatn) != 0) {
404 CharString path;
405 path.append(gNumberElements, status)
406 .append('/', status)
407 .append(nsName, status)
408 .append('/', status)
409 .append(gSymbols, status);
410 ures_getAllItemsWithFallback(resource.getAlias(), path.data(), sink, status);
411
412 // If no symbols exist for the given nsName and resource bundle, silently ignore
413 // and fall back to Latin.
414 if (status == U_MISSING_RESOURCE_ERROR) {
415 status = U_ZERO_ERROR;
416 } else if (U_FAILURE(status)) {
417 return;
729e4ab9 418 }
57a6839d 419 }
729e4ab9 420
f3c0d7a5
A
421 // Continue with Latin if necessary.
422 if (!sink.seenAll()) {
423 ures_getAllItemsWithFallback(resource.getAlias(), gNumberElementsLatnSymbols, sink, status);
424 if (U_FAILURE(status)) { return; }
57a6839d 425 }
729e4ab9 426
f3c0d7a5
A
427 // Let the monetary number separators equal the default number separators if necessary.
428 sink.resolveMissingMonetarySeparators(fSymbols);
429
57a6839d
A
430 // Obtain currency data from the currency API. This is strictly
431 // for backward compatibility; we don't use DecimalFormatSymbols
432 // for currency data anymore.
433 UErrorCode internalStatus = U_ZERO_ERROR; // don't propagate failures out
434 UChar curriso[4];
435 UnicodeString tempStr;
436 ucurr_forLocale(locStr, curriso, 4, &internalStatus);
437
438 uprv_getStaticCurrencyName(curriso, locStr, tempStr, internalStatus);
439 if (U_SUCCESS(internalStatus)) {
440 fSymbols[kIntlCurrencySymbol].setTo(curriso, -1);
441 fSymbols[kCurrencySymbol] = tempStr;
442 }
443 /* else use the default values. */
444
57a6839d
A
445 //load the currency data
446 UChar ucc[4]={0}; //Currency Codes are always 3 chars long
447 int32_t uccLen = 4;
448 const char* locName = loc.getName();
449 UErrorCode localStatus = U_ZERO_ERROR;
450 uccLen = ucurr_forLocale(locName, ucc, uccLen, &localStatus);
451
452 if(U_SUCCESS(localStatus) && uccLen > 0) {
453 char cc[4]={0};
454 u_UCharsToChars(ucc, cc, uccLen);
455 /* An explicit currency was requested */
456 LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &localStatus));
457 LocalUResourceBundlePointer currency(
458 ures_getByKeyWithFallback(currencyResource.getAlias(), "Currencies", NULL, &localStatus));
459 ures_getByKeyWithFallback(currency.getAlias(), cc, currency.getAlias(), &localStatus);
460 if(U_SUCCESS(localStatus) && ures_getSize(currency.getAlias())>2) { // the length is 3 if more data is present
461 ures_getByIndex(currency.getAlias(), 2, currency.getAlias(), &localStatus);
462 int32_t currPatternLen = 0;
463 currPattern =
464 ures_getStringByIndex(currency.getAlias(), (int32_t)0, &currPatternLen, &localStatus);
465 UnicodeString decimalSep =
466 ures_getUnicodeStringByIndex(currency.getAlias(), (int32_t)1, &localStatus);
467 UnicodeString groupingSep =
468 ures_getUnicodeStringByIndex(currency.getAlias(), (int32_t)2, &localStatus);
469 if(U_SUCCESS(localStatus)){
470 fSymbols[kMonetaryGroupingSeparatorSymbol] = groupingSep;
471 fSymbols[kMonetarySeparatorSymbol] = decimalSep;
472 //pattern.setTo(TRUE, currPattern, currPatternLen);
473 status = localStatus;
73c04bcf 474 }
73c04bcf 475 }
57a6839d
A
476 /* else An explicit currency was requested and is unknown or locale data is malformed. */
477 /* ucurr_* API will get the correct value later on. */
478 }
479 // else ignore the error if no currency
480
481 // Currency Spacing.
f3c0d7a5
A
482 LocalUResourceBundlePointer currencyResource(ures_open(U_ICUDATA_CURR, locStr, &status));
483 CurrencySpacingSink currencySink(*this);
484 ures_getAllItemsWithFallback(currencyResource.getAlias(), gCurrencySpacingTag, currencySink, status);
485 currencySink.resolveMissing();
486 if (U_FAILURE(status)) { return; }
b75a7d8f
A
487}
488
b75a7d8f
A
489void
490DecimalFormatSymbols::initialize() {
491 /*
492 * These strings used to be in static arrays, but the HP/UX aCC compiler
493 * cannot initialize a static array with class constructors.
494 * markus 2000may25
495 */
496 fSymbols[kDecimalSeparatorSymbol] = (UChar)0x2e; // '.' decimal separator
497 fSymbols[kGroupingSeparatorSymbol].remove(); // group (thousands) separator
498 fSymbols[kPatternSeparatorSymbol] = (UChar)0x3b; // ';' pattern separator
499 fSymbols[kPercentSymbol] = (UChar)0x25; // '%' percent sign
500 fSymbols[kZeroDigitSymbol] = (UChar)0x30; // '0' native 0 digit
729e4ab9
A
501 fSymbols[kOneDigitSymbol] = (UChar)0x31; // '1' native 1 digit
502 fSymbols[kTwoDigitSymbol] = (UChar)0x32; // '2' native 2 digit
503 fSymbols[kThreeDigitSymbol] = (UChar)0x33; // '3' native 3 digit
504 fSymbols[kFourDigitSymbol] = (UChar)0x34; // '4' native 4 digit
505 fSymbols[kFiveDigitSymbol] = (UChar)0x35; // '5' native 5 digit
506 fSymbols[kSixDigitSymbol] = (UChar)0x36; // '6' native 6 digit
507 fSymbols[kSevenDigitSymbol] = (UChar)0x37; // '7' native 7 digit
508 fSymbols[kEightDigitSymbol] = (UChar)0x38; // '8' native 8 digit
509 fSymbols[kNineDigitSymbol] = (UChar)0x39; // '9' native 9 digit
b75a7d8f 510 fSymbols[kDigitSymbol] = (UChar)0x23; // '#' pattern digit
b75a7d8f 511 fSymbols[kPlusSignSymbol] = (UChar)0x002b; // '+' plus sign
374ca955 512 fSymbols[kMinusSignSymbol] = (UChar)0x2d; // '-' minus sign
b75a7d8f 513 fSymbols[kCurrencySymbol] = (UChar)0xa4; // 'OX' currency symbol
4388f060 514 fSymbols[kIntlCurrencySymbol].setTo(TRUE, INTL_CURRENCY_SYMBOL_STR, 2);
b75a7d8f
A
515 fSymbols[kMonetarySeparatorSymbol] = (UChar)0x2e; // '.' monetary decimal separator
516 fSymbols[kExponentialSymbol] = (UChar)0x45; // 'E' exponential
517 fSymbols[kPerMillSymbol] = (UChar)0x2030; // '%o' per mill
518 fSymbols[kPadEscapeSymbol] = (UChar)0x2a; // '*' pad escape symbol
519 fSymbols[kInfinitySymbol] = (UChar)0x221e; // 'oo' infinite
520 fSymbols[kNaNSymbol] = (UChar)0xfffd; // SUB NaN
374ca955 521 fSymbols[kSignificantDigitSymbol] = (UChar)0x0040; // '@' significant digit
729e4ab9 522 fSymbols[kMonetaryGroupingSeparatorSymbol].remove(); //
b331163b 523 fSymbols[kExponentMultiplicationSymbol] = (UChar)0xd7; // 'x' multiplication symbol for exponents
2ca993e8
A
524 fIsCustomCurrencySymbol = FALSE;
525 fIsCustomIntlCurrencySymbol = FALSE;
526
374ca955
A
527}
528
729e4ab9 529Locale
374ca955
A
530DecimalFormatSymbols::getLocale(ULocDataLocaleType type, UErrorCode& status) const {
531 U_LOCALE_BASED(locBased, *this);
532 return locBased.getLocale(type, status);
b75a7d8f
A
533}
534
729e4ab9 535const UnicodeString&
4388f060 536DecimalFormatSymbols::getPatternForCurrencySpacing(UCurrencySpacing type,
729e4ab9
A
537 UBool beforeCurrency,
538 UErrorCode& status) const {
539 if (U_FAILURE(status)) {
540 return fNoSymbol; // always empty.
541 }
542 if (beforeCurrency) {
543 return currencySpcBeforeSym[(int32_t)type];
544 } else {
545 return currencySpcAfterSym[(int32_t)type];
546 }
547}
548
549void
4388f060 550DecimalFormatSymbols::setPatternForCurrencySpacing(UCurrencySpacing type,
729e4ab9
A
551 UBool beforeCurrency,
552 const UnicodeString& pattern) {
553 if (beforeCurrency) {
554 currencySpcBeforeSym[(int32_t)type] = pattern;
555 } else {
556 currencySpcAfterSym[(int32_t)type] = pattern;
557 }
558}
b75a7d8f
A
559U_NAMESPACE_END
560
561#endif /* #if !UCONFIG_NO_FORMATTING */
562
563//eof