58 * Here are the special characters used in the parts of the 59 * subpattern, with notes on their usage. 60 *
61 * \code 62 * Symbol Meaning 63 * 0 a digit 64 * # a digit, zero shows as absent 65 * . placeholder for decimal separator 66 * , placeholder for grouping separator. 67 * ; separates formats. 68 * - default negative prefix. 69 * % divide by 100 and show as percentage 70 * X any other characters can be used in the prefix or suffix 71 * ' used to quote special characters in a prefix or suffix. 72 * \endcode 73 *
76 * If there is no explicit negative subpattern, - is prefixed to the 77 * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00". 78 *
79 * The grouping separator is commonly used for thousands, but in some 80 * countries for ten-thousands. The interval is a constant number of 81 * digits between the grouping characters, such as 100,000,000 or 1,0000,0000. 82 * If you supply a pattern with multiple grouping characters, the interval 83 * between the last one and the end of the integer is the one that is 84 * used. So "#,##,###,####" == "######,####" == "##,####,####". 85 */ 86 class U_I18N_API DecimalFormatSymbols : public UObject { 87 public: 88 /** 89 * Constants for specifying a number format symbol. 90 * @stable ICU 2.0 91 */ 92 enum ENumberFormatSymbol { 93 /** The decimal separator */ 94 kDecimalSeparatorSymbol, 95 /** The grouping separator */ 96 kGroupingSeparatorSymbol, 97 /** The pattern separator */ 98 kPatternSeparatorSymbol, 99 /** The percent sign */ 100 kPercentSymbol, 101 /** Zero*/ 102 kZeroDigitSymbol, 103 /** Character representing a digit in the pattern */ 104 kDigitSymbol, 105 /** The minus sign */ 106 kMinusSignSymbol, 107 /** The plus sign */ 108 kPlusSignSymbol, 109 /** The currency symbol */ 110 kCurrencySymbol, 111 /** The international currency symbol */ 112 kIntlCurrencySymbol, 113 /** The monetary separator */ 114 kMonetarySeparatorSymbol, 115 /** The exponential symbol */ 116 kExponentialSymbol, 117 /** Per mill symbol - replaces kPermillSymbol */ 118 kPerMillSymbol, 119 /** Escape padding character */ 120 kPadEscapeSymbol, 121 /** Infinity symbol */ 122 kInfinitySymbol, 123 /** Nan symbol */ 124 kNaNSymbol, 125 /** Significant digit symbol 126 * @stable ICU 3.0 */ 127 kSignificantDigitSymbol, 128 /** The monetary grouping separator 129 * @stable ICU 3.6 130 */ 131 kMonetaryGroupingSeparatorSymbol, 132 /** One 133 * @stable ICU 4.6 134 */ 135 kOneDigitSymbol, 136 /** Two 137 * @stable ICU 4.6 138 */ 139 kTwoDigitSymbol, 140 /** Three 141 * @stable ICU 4.6 142 */ 143 kThreeDigitSymbol, 144 /** Four 145 * @stable ICU 4.6 146 */ 147 kFourDigitSymbol, 148 /** Five 149 * @stable ICU 4.6 150 */ 151 kFiveDigitSymbol, 152 /** Six 153 * @stable ICU 4.6 154 */ 155 kSixDigitSymbol, 156 /** Seven 157 * @stable ICU 4.6 158 */ 159 kSevenDigitSymbol, 160 /** Eight 161 * @stable ICU 4.6 162 */ 163 kEightDigitSymbol, 164 /** Nine 165 * @stable ICU 4.6 166 */ 167 kNineDigitSymbol, 168 /** Multiplication sign. 169 * @stable ICU 54 170 */ 171 kExponentMultiplicationSymbol, 172 #ifndef U_HIDE_INTERNAL_API 173 /** Approximately sign. 174 * @internal 175 */ 176 kApproximatelySignSymbol, 177 #endif /* U_HIDE_INTERNAL_API */ 178 /** count symbol constants */ 179 kFormatSymbolCount = kExponentMultiplicationSymbol + 2 180 }; 181 182 /** 183 * Create a DecimalFormatSymbols object for the given locale. 184 * 185 * @param locale The locale to get symbols for. 186 * @param status Input/output parameter, set to success or 187 * failure code upon return. 188 * @stable ICU 2.0 189 */ 190 DecimalFormatSymbols(const Locale& locale, UErrorCode& status); 191 192 /** 193 * Creates a DecimalFormatSymbols instance for the given locale with digits and symbols 194 * corresponding to the given NumberingSystem. 195 * 196 * This constructor behaves equivalently to the normal constructor called with a locale having a 197 * "numbers=xxxx" keyword specifying the numbering system by name. 198 * 199 * In this constructor, the NumberingSystem argument will be used even if the locale has its own 200 * "numbers=xxxx" keyword. 201 * 202 * @param locale The locale to get symbols for. 203 * @param ns The numbering system. 204 * @param status Input/output parameter, set to success or 205 * failure code upon return. 206 * @stable ICU 60 207 */ 208 DecimalFormatSymbols(const Locale& locale, const NumberingSystem& ns, UErrorCode& status); 209 210 /** 211 * Create a DecimalFormatSymbols object for the default locale. 212 * This constructor will not fail. If the resource file data is 213 * not available, it will use hard-coded last-resort data and 214 * set status to U_USING_FALLBACK_ERROR. 215 * 216 * @param status Input/output parameter, set to success or 217 * failure code upon return. 218 * @stable ICU 2.0 219 */ 220 DecimalFormatSymbols(UErrorCode& status); 221 222 /** 223 * Creates a DecimalFormatSymbols object with last-resort data. 224 * Intended for callers who cache the symbols data and 225 * set all symbols on the resulting object. 226 * 227 * The last-resort symbols are similar to those for the root data, 228 * except that the grouping separators are empty, 229 * the NaN symbol is U+FFFD rather than "NaN", 230 * and the CurrencySpacing patterns are empty. 231 * 232 * @param status Input/output parameter, set to success or 233 * failure code upon return. 234 * @return last-resort symbols 235 * @stable ICU 52 236 */ 237 static DecimalFormatSymbols* createWithLastResortData(UErrorCode& status); 238 239 /** 240 * Copy constructor. 241 * @stable ICU 2.0 242 */ 243 DecimalFormatSymbols(const DecimalFormatSymbols&); 244 245 /** 246 * Assignment operator. 247 * @stable ICU 2.0 248 */ 249 DecimalFormatSymbols& operator=(const DecimalFormatSymbols&); 250 251 /** 252 * Destructor. 253 * @stable ICU 2.0 254 */ 255 virtual ~DecimalFormatSymbols(); 256 257 /** 258 * Return true if another object is semantically equal to this one. 259 * 260 * @param other the object to be compared with. 261 * @return true if another object is semantically equal to this one. 262 * @stable ICU 2.0 263 */ 264 bool operator==(const DecimalFormatSymbols& other) const; 265 266 /** 267 * Return true if another object is semantically unequal to this one. 268 * 269 * @param other the object to be compared with. 270 * @return true if another object is semantically unequal to this one. 271 * @stable ICU 2.0 272 */ 273 bool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); } 274 275 /** 276 * Get one of the format symbols by its enum constant. 277 * Each symbol is stored as a string so that graphemes 278 * (characters with modifier letters) can be used. 279 * 280 * @param symbol Constant to indicate a number format symbol. 281 * @return the format symbols by the param 'symbol' 282 * @stable ICU 2.0 283 */ 284 inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const; 285 286 /** 287 * Set one of the format symbols by its enum constant. 288 * Each symbol is stored as a string so that graphemes 289 * (characters with modifier letters) can be used. 290 * 291 * @param symbol Constant to indicate a number format symbol. 292 * @param value value of the format symbol 293 * @param propagateDigits If false, setting the zero digit will not automatically set 1-9. 294 * The default behavior is to automatically set 1-9 if zero is being set and the value 295 * it is being set to corresponds to a known Unicode zero digit. 296 * @stable ICU 2.0 297 */ 298 void setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propagateDigits); 299 300 #ifndef U_HIDE_INTERNAL_API 301 /** 302 * Loads symbols for the specified currency into this instance. 303 * 304 * This method is internal. If you think it should be public, file a ticket. 305 * 306 * @internal 307 */ 308 void setCurrency(const char16_t* currency, UErrorCode& status); 309 #endif // U_HIDE_INTERNAL_API 310 311 /** 312 * Returns the locale for which this object was constructed. 313 * @stable ICU 2.6 314 */ 315 inline Locale getLocale() const; 316 317 /** 318 * Returns the locale for this object. Two flavors are available: 319 * valid and actual locale. 320 * @stable ICU 2.8 321 */ 322 Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; 323 324 /** 325 * Get pattern string for 'CurrencySpacing' that can be applied to 326 * currency format. 327 * This API gets the CurrencySpacing data from ResourceBundle. The pattern can 328 * be empty if there is no data from current locale and its parent locales. 329 * 330 * @param type : UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT. 331 * @param beforeCurrency : true if the pattern is for before currency symbol. 332 * false if the pattern is for after currency symbol. 333 * @param status: Input/output parameter, set to success or 334 * failure code upon return. 335 * @return pattern string for currencyMatch, surroundingMatch or spaceInsert. 336 * Return empty string if there is no data for this locale and its parent 337 * locales. 338 * @stable ICU 4.8 339 */ 340 const UnicodeString& getPatternForCurrencySpacing(UCurrencySpacing type, 341 UBool beforeCurrency, 342 UErrorCode& status) const; 343 /** 344 * Set pattern string for 'CurrencySpacing' that can be applied to 345 * currency format. 346 * 347 * @param type : UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT. 348 * @param beforeCurrency : true if the pattern is for before currency symbol. 349 * false if the pattern is for after currency symbol. 350 * @param pattern : pattern string to override current setting. 351 * @stable ICU 4.8 352 */ 353 void setPatternForCurrencySpacing(UCurrencySpacing type, 354 UBool beforeCurrency, 355 const UnicodeString& pattern); 356 357 /** 358 * ICU "poor man's RTTI", returns a UClassID for the actual class. 359 * 360 * @stable ICU 2.2 361 */ 362 virtual UClassID getDynamicClassID() const override; 363 364 /** 365 * ICU "poor man's RTTI", returns a UClassID for this class. 366 * 367 * @stable ICU 2.2 368 */ 369 static UClassID U_EXPORT2 getStaticClassID(); 370 371 private: 372 DecimalFormatSymbols(); 373 374 /** 375 * Initializes the symbols from the LocaleElements resource bundle. 376 * Note: The organization of LocaleElements badly needs to be 377 * cleaned up. 378 * 379 * @param locale The locale to get symbols for. 380 * @param success Input/output parameter, set to success or 381 * failure code upon return. 382 * @param useLastResortData determine if use last resort data 383 * @param ns The NumberingSystem to use; otherwise, fall 384 * back to the locale. 385 */ 386 void initialize(const Locale& locale, UErrorCode& success, 387 UBool useLastResortData = false, const NumberingSystem* ns = nullptr); 388 389 /** 390 * Initialize the symbols with default values. 391 */ 392 void initialize(); 393 394 public: 395 396 #ifndef U_HIDE_INTERNAL_API 397 /** 398 * @internal For ICU use only 399 */ 400 inline UBool isCustomCurrencySymbol() const { 401 return fIsCustomCurrencySymbol; 402 } 403 404 /** 405 * @internal For ICU use only 406 */ 407 inline UBool isCustomIntlCurrencySymbol() const { 408 return fIsCustomIntlCurrencySymbol; 409 } 410 411 /** 412 * @internal For ICU use only 413 */ 414 inline UChar32 getCodePointZero() const { 415 return fCodePointZero; 416 } 417 #endif /* U_HIDE_INTERNAL_API */ 418 419 /** 420 * _Internal_ function - more efficient version of getSymbol, 421 * returning a const reference to one of the symbol strings. 422 * The returned reference becomes invalid when the symbol is changed 423 * or when the DecimalFormatSymbols are destroyed. 424 * Note: moved \#ifndef U_HIDE_INTERNAL_API after this, since this is needed for inline in DecimalFormat 425 * 426 * This is not currently stable API, but if you think it should be stable, 427 * post a comment on the following ticket and the ICU team will take a look: 428 * https://unicode-org.atlassian.net/browse/ICU-13580 429 * 430 * @param symbol Constant to indicate a number format symbol. 431 * @return the format symbol by the param 'symbol' 432 * @internal 433 */ 434 inline const UnicodeString& getConstSymbol(ENumberFormatSymbol symbol) const; 435 436 #ifndef U_HIDE_INTERNAL_API 437 /** 438 * Returns the const UnicodeString reference, like getConstSymbol, 439 * corresponding to the digit with the given value. This is equivalent 440 * to accessing the symbol from getConstSymbol with the corresponding 441 * key, such as kZeroDigitSymbol or kOneDigitSymbol. 442 * 443 * This is not currently stable API, but if you think it should be stable, 444 * post a comment on the following ticket and the ICU team will take a look: 445 * https://unicode-org.atlassian.net/browse/ICU-13580 446 * 447 * @param digit The digit, an integer between 0 and 9 inclusive. 448 * If outside the range 0 to 9, the zero digit is returned. 449 * @return the format symbol for the given digit. 450 * @internal This API is currently for ICU use only. 451 */ 452 inline const UnicodeString& getConstDigitSymbol(int32_t digit) const; 453 454 /** 455 * Returns that pattern stored in currency info. Internal API for use by NumberFormat API. 456 * @internal 457 */ 458 inline const char16_t* getCurrencyPattern(void) const; 459 460 /** 461 * Returns the numbering system with which this DecimalFormatSymbols was initialized. 462 * @internal 463 */ 464 inline const char* getNumberingSystemName(void) const; 465 #endif /* U_HIDE_INTERNAL_API */ 466 467 private: 468 /** 469 * Private symbol strings. 470 * They are either loaded from a resource bundle or otherwise owned. 471 * setSymbol() clones the symbol string. 472 * Readonly aliases can only come from a resource bundle, so that we can always 473 * use fastCopyFrom() with them. 474 * 475 * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes 476 * from private to protected, 477 * or when fSymbols can be set any other way that allows them to be readonly aliases 478 * to non-resource bundle strings, 479 * then regular UnicodeString copies must be used instead of fastCopyFrom(). 480 * 481 */ 482 UnicodeString fSymbols[kFormatSymbolCount]; 483 484 /** 485 * Non-symbol variable for getConstSymbol(). Always empty. 486 */ 487 UnicodeString fNoSymbol; 488 489 /** 490 * Dealing with code points is faster than dealing with strings when formatting. Because of 491 * this, we maintain a value containing the zero code point that is used whenever digitStrings 492 * represents a sequence of ten code points in order. 493 * 494 *
If the value stored here is positive, it means that the code point stored in this value 495 * corresponds to the digitStrings array, and codePointZero can be used instead of the 496 * digitStrings array for the purposes of efficient formatting; if -1, then digitStrings does 497 * *not* contain a sequence of code points, and it must be used directly. 498 * 499 *
It is assumed that codePointZero always shadows the value in digitStrings. codePointZero 500 * should never be set directly; rather, it should be updated only when digitStrings mutates. 501 * That is, the flow of information is digitStrings -> codePointZero, not the other way. 502 */ 503 UChar32 fCodePointZero; 504 505 Locale locale; 506 507 char actualLocale[ULOC_FULLNAME_CAPACITY]; 508 char validLocale[ULOC_FULLNAME_CAPACITY]; 509 const char16_t* currPattern = nullptr; 510 511 UnicodeString currencySpcBeforeSym[UNUM_CURRENCY_SPACING_COUNT]; 512 UnicodeString currencySpcAfterSym[UNUM_CURRENCY_SPACING_COUNT]; 513 UBool fIsCustomCurrencySymbol; 514 UBool fIsCustomIntlCurrencySymbol; 515 char nsName[kInternalNumSysNameCapacity+1] = {}; 516 }; 517 518 // ------------------------------------- 519 520 inline UnicodeString 521 DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const { 522 const UnicodeString *strPtr; 523 if(symbol < kFormatSymbolCount) { 524 strPtr = &fSymbols[symbol]; 525 } else { 526 strPtr = &fNoSymbol; 527 } 528 return *strPtr; 529 } 530 531 // See comments above for this function. Not hidden with #ifdef U_HIDE_INTERNAL_API 532 inline const UnicodeString & 533 DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const { 534 const UnicodeString *strPtr; 535 if(symbol < kFormatSymbolCount) { 536 strPtr = &fSymbols[symbol]; 537 } else { 538 strPtr = &fNoSymbol; 539 } 540 return *strPtr; 541 } 542 543 #ifndef U_HIDE_INTERNAL_API 544 inline const UnicodeString& DecimalFormatSymbols::getConstDigitSymbol(int32_t digit) const { 545 if (digit < 0 || digit > 9) { 546 digit = 0; 547 } 548 if (digit == 0) { 549 return fSymbols[kZeroDigitSymbol]; 550 } 551 ENumberFormatSymbol key = static_cast(kOneDigitSymbol + digit - 1); 552 return fSymbols[key]; 553 } 554 #endif /* U_HIDE_INTERNAL_API */ 555 556 // ------------------------------------- 557 558 inline void 559 DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propagateDigits = true) { 560 if (symbol == kCurrencySymbol) { 561 fIsCustomCurrencySymbol = true; 562 } 563 else if (symbol == kIntlCurrencySymbol) { 564 fIsCustomIntlCurrencySymbol = true; 565 } 566 if(symbol= kOneDigitSymbol && symbol <= kNineDigitSymbol) { 585 fCodePointZero = -1; 586 } 587 } 588 589 // ------------------------------------- 590 591 inline Locale 592 DecimalFormatSymbols::getLocale() const { 593 return locale; 594 } 595 596 #ifndef U_HIDE_INTERNAL_API 597 inline const char16_t* 598 DecimalFormatSymbols::getCurrencyPattern() const { 599 return currPattern; 600 } 601 inline const char* 602 DecimalFormatSymbols::getNumberingSystemName() const { 603 return nsName; 604 } 605 #endif /* U_HIDE_INTERNAL_API */ 606 607 U_NAMESPACE_END 608 609 #endif /* #if !UCONFIG_NO_FORMATTING */ 610 611 #endif /* U_SHOW_CPLUSPLUS_API */ 612 613 #endif // _DCFMTSYM 614 //eof