1 /* 2 ******************************************************************************** 3 * Copyright (C) 1997-2010, International Business Machines 4 * Corporation and others. All Rights Reserved. 5 ******************************************************************************** 6 * 7 * File DCFMTSYM.H 8 * 9 * Modification History: 10 * 11 * Date Name Description 12 * 02/19/97 aliu Converted from java. 13 * 03/18/97 clhuang Updated per C++ implementation. 14 * 03/27/97 helena Updated to pass the simple test after code review. 15 * 08/26/97 aliu Added currency/intl currency symbol support. 16 * 07/22/98 stephen Changed to match C++ style 17 * currencySymbol -> fCurrencySymbol 18 * Constants changed from CAPS to kCaps 19 * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes 20 * 09/22/00 grhoten Marked deprecation tags with a pointer to replacement 21 * functions. 22 ******************************************************************************** 23 */ 24 25 #ifndef DCFMTSYM_H 26 #define DCFMTSYM_H 27 28 #include "unicode/utypes.h" 29 #include "unicode/uchar.h" 30 31 #if !UCONFIG_NO_FORMATTING 32 33 #include "unicode/uobject.h" 34 #include "unicode/locid.h" 35 36 /** 37 * \file 38 * \brief C++ API: Symbols for formatting numbers. 39 */ 40 41 42 U_NAMESPACE_BEGIN 43 44 /** 45 * This class represents the set of symbols needed by DecimalFormat 46 * to format numbers. DecimalFormat creates for itself an instance of 47 * DecimalFormatSymbols from its locale data. If you need to change any 48 * of these symbols, you can get the DecimalFormatSymbols object from 49 * your DecimalFormat and modify it. 50 * <P> 51 * Here are the special characters used in the parts of the 52 * subpattern, with notes on their usage. 53 * <pre> 54 * \code 55 * Symbol Meaning 56 * 0 a digit 57 * # a digit, zero shows as absent 58 * . placeholder for decimal separator 59 * , placeholder for grouping separator. 60 * ; separates formats. 61 * - default negative prefix. 62 * % divide by 100 and show as percentage 63 * X any other characters can be used in the prefix or suffix 64 * ' used to quote special characters in a prefix or suffix. 65 * \endcode 66 * </pre> 67 * [Notes] 68 * <P> 69 * If there is no explicit negative subpattern, - is prefixed to the 70 * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00". 71 * <P> 72 * The grouping separator is commonly used for thousands, but in some 73 * countries for ten-thousands. The interval is a constant number of 74 * digits between the grouping characters, such as 100,000,000 or 1,0000,0000. 75 * If you supply a pattern with multiple grouping characters, the interval 76 * between the last one and the end of the integer is the one that is 77 * used. So "#,##,###,####" == "######,####" == "##,####,####". 78 * <P> 79 * This class only handles localized digits where the 10 digits are 80 * contiguous in Unicode, from 0 to 9. Other digits sets (such as 81 * superscripts) would need a different subclass. 82 */ 83 class U_I18N_API DecimalFormatSymbols : public UObject { 84 public: 85 /** 86 * Constants for specifying a number format symbol. 87 * @stable ICU 2.0 88 */ 89 enum ENumberFormatSymbol { 90 /** The decimal separator */ 91 kDecimalSeparatorSymbol, 92 /** The grouping separator */ 93 kGroupingSeparatorSymbol, 94 /** The pattern separator */ 95 kPatternSeparatorSymbol, 96 /** The percent sign */ 97 kPercentSymbol, 98 /** Zero*/ 99 kZeroDigitSymbol, 100 /** Character representing a digit in the pattern */ 101 kDigitSymbol, 102 /** The minus sign */ 103 kMinusSignSymbol, 104 /** The plus sign */ 105 kPlusSignSymbol, 106 /** The currency symbol */ 107 kCurrencySymbol, 108 /** The international currency symbol */ 109 kIntlCurrencySymbol, 110 /** The monetary separator */ 111 kMonetarySeparatorSymbol, 112 /** The exponential symbol */ 113 kExponentialSymbol, 114 /** Per mill symbol - replaces kPermillSymbol */ 115 kPerMillSymbol, 116 /** Escape padding character */ 117 kPadEscapeSymbol, 118 /** Infinity symbol */ 119 kInfinitySymbol, 120 /** Nan symbol */ 121 kNaNSymbol, 122 /** Significant digit symbol 123 * @stable ICU 3.0 */ 124 kSignificantDigitSymbol, 125 /** The monetary grouping separator 126 * @stable ICU 3.6 127 */ 128 kMonetaryGroupingSeparatorSymbol, 129 /** One 130 * @draft ICU 4.6 131 */ 132 kOneDigitSymbol, 133 /** Two 134 * @draft ICU 4.6 135 */ 136 kTwoDigitSymbol, 137 /** Three 138 * @draft ICU 4.6 139 */ 140 kThreeDigitSymbol, 141 /** Four 142 * @draft ICU 4.6 143 */ 144 kFourDigitSymbol, 145 /** Five 146 * @draft ICU 4.6 147 */ 148 kFiveDigitSymbol, 149 /** Six 150 * @draft ICU 4.6 151 */ 152 kSixDigitSymbol, 153 /** Seven 154 * @draft ICU 4.6 155 */ 156 kSevenDigitSymbol, 157 /** Eight 158 * @draft ICU 4.6 159 */ 160 kEightDigitSymbol, 161 /** Nine 162 * @draft ICU 4.6 163 */ 164 kNineDigitSymbol, 165 /** count symbol constants */ 166 kFormatSymbolCount 167 }; 168 169 /** 170 * Constants for specifying currency spacing 171 * @draft ICU 4.2 172 */ 173 enum ECurrencySpacing { 174 kCurrencyMatch, 175 kSurroundingMatch, 176 kInsert, 177 kCurrencySpacingCount 178 }; 179 180 /** 181 * Create a DecimalFormatSymbols object for the given locale. 182 * 183 * @param locale The locale to get symbols for. 184 * @param status Input/output parameter, set to success or 185 * failure code upon return. 186 * @stable ICU 2.0 187 */ 188 DecimalFormatSymbols(const Locale& locale, UErrorCode& status); 189 190 /** 191 * Create a DecimalFormatSymbols object for the default locale. 192 * This constructor will not fail. If the resource file data is 193 * not available, it will use hard-coded last-resort data and 194 * set status to U_USING_FALLBACK_ERROR. 195 * 196 * @param status Input/output parameter, set to success or 197 * failure code upon return. 198 * @stable ICU 2.0 199 */ 200 DecimalFormatSymbols( UErrorCode& status); 201 202 // BEGIN android-added: we need a default constructor for performance. 203 // Proposed for ICU 4.8: http://icu-project.org/trac/ticket/7392 204 DecimalFormatSymbols(); 205 // END android-added 206 207 /** 208 * Copy constructor. 209 * @stable ICU 2.0 210 */ 211 DecimalFormatSymbols(const DecimalFormatSymbols&); 212 213 /** 214 * Assignment operator. 215 * @stable ICU 2.0 216 */ 217 DecimalFormatSymbols& operator=(const DecimalFormatSymbols&); 218 219 /** 220 * Destructor. 221 * @stable ICU 2.0 222 */ 223 virtual ~DecimalFormatSymbols(); 224 225 /** 226 * Return true if another object is semantically equal to this one. 227 * 228 * @param other the object to be compared with. 229 * @return true if another object is semantically equal to this one. 230 * @stable ICU 2.0 231 */ 232 UBool operator==(const DecimalFormatSymbols& other) const; 233 234 /** 235 * Return true if another object is semantically unequal to this one. 236 * 237 * @param other the object to be compared with. 238 * @return true if another object is semantically unequal to this one. 239 * @stable ICU 2.0 240 */ 241 UBool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); } 242 243 /** 244 * Get one of the format symbols by its enum constant. 245 * Each symbol is stored as a string so that graphemes 246 * (characters with modifier letters) can be used. 247 * 248 * @param symbol Constant to indicate a number format symbol. 249 * @return the format symbols by the param 'symbol' 250 * @stable ICU 2.0 251 */ 252 inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const; 253 254 /** 255 * Set one of the format symbols by its enum constant. 256 * Each symbol is stored as a string so that graphemes 257 * (characters with modifier letters) can be used. 258 * 259 * @param symbol Constant to indicate a number format symbol. 260 * @param value value of the format symbol 261 * @param propogateDigits If false, setting the zero digit will not automatically set 1-9. 262 * The default behavior is to automatically set 1-9 if zero is being set and the value 263 * it is being set to corresponds to a known Unicode zero digit. 264 * @stable ICU 2.0 265 */ 266 void setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits); 267 268 /** 269 * Returns the locale for which this object was constructed. 270 * @stable ICU 2.6 271 */ 272 inline Locale getLocale() const; 273 274 /** 275 * Returns the locale for this object. Two flavors are available: 276 * valid and actual locale. 277 * @stable ICU 2.8 278 */ 279 Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const; 280 281 /** 282 * Get pattern string for 'CurrencySpacing' that can be applied to 283 * currency format. 284 * This API gets the CurrencySpacing data from ResourceBundle. The pattern can 285 * be empty if there is no data from current locale and its parent locales. 286 * 287 * @param type : kCurrencyMatch, kSurroundingMatch or kInsert. 288 * @param beforeCurrency : true if the pattern is for before currency symbol. 289 * false if the pattern is for after currency symbol. 290 * @param status: Input/output parameter, set to success or 291 * failure code upon return. 292 * @return pattern string for currencyMatch, surroundingMatch or spaceInsert. 293 * Return empty string if there is no data for this locale and its parent 294 * locales. 295 * @draft ICU 4.2 296 */ 297 const UnicodeString& getPatternForCurrencySpacing(ECurrencySpacing type, 298 UBool beforeCurrency, 299 UErrorCode& status) const; 300 /** 301 * Set pattern string for 'CurrencySpacing' that can be applied to 302 * currency format. 303 * 304 * @param type : kCurrencyMatch, kSurroundingMatch or kInsert. 305 * @param beforeCurrency : true if the pattern is for before currency symbol. 306 * false if the pattern is for after currency symbol. 307 * @param pattern : pattern string to override current setting. 308 * @draft ICU 4.2 309 */ 310 void setPatternForCurrencySpacing(ECurrencySpacing type, 311 UBool beforeCurrency, 312 const UnicodeString& pattern); 313 314 /** 315 * ICU "poor man's RTTI", returns a UClassID for the actual class. 316 * 317 * @stable ICU 2.2 318 */ 319 virtual UClassID getDynamicClassID() const; 320 321 /** 322 * ICU "poor man's RTTI", returns a UClassID for this class. 323 * 324 * @stable ICU 2.2 325 */ 326 static UClassID U_EXPORT2 getStaticClassID(); 327 328 private: 329 // BEGIN android-removed: we need a default constructor for performance. 330 // DecimalFormatSymbols(); // default constructor not implemented 331 // END android-removed 332 333 /** 334 * Initializes the symbols from the LocaleElements resource bundle. 335 * Note: The organization of LocaleElements badly needs to be 336 * cleaned up. 337 * 338 * @param locale The locale to get symbols for. 339 * @param success Input/output parameter, set to success or 340 * failure code upon return. 341 * @param useLastResortData determine if use last resort data 342 */ 343 void initialize(const Locale& locale, UErrorCode& success, UBool useLastResortData = FALSE); 344 345 /** 346 * Initialize the symbols with default values. 347 */ 348 void initialize(); 349 350 void setCurrencyForSymbols(); 351 352 public: 353 /** 354 * _Internal_ function - more efficient version of getSymbol, 355 * returning a const reference to one of the symbol strings. 356 * The returned reference becomes invalid when the symbol is changed 357 * or when the DecimalFormatSymbols are destroyed. 358 * ### TODO markus 2002oct11: Consider proposing getConstSymbol() to be really public. 359 * 360 * @param symbol Constant to indicate a number format symbol. 361 * @return the format symbol by the param 'symbol' 362 * @internal 363 */ 364 inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const; 365 366 /** 367 * Returns that pattern stored in currecy info. Internal API for use by NumberFormat API. 368 * @internal 369 */ 370 inline const UChar* getCurrencyPattern(void) const; 371 372 private: 373 /** 374 * Private symbol strings. 375 * They are either loaded from a resource bundle or otherwise owned. 376 * setSymbol() clones the symbol string. 377 * Readonly aliases can only come from a resource bundle, so that we can always 378 * use fastCopyFrom() with them. 379 * 380 * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes 381 * from private to protected, 382 * or when fSymbols can be set any other way that allows them to be readonly aliases 383 * to non-resource bundle strings, 384 * then regular UnicodeString copies must be used instead of fastCopyFrom(). 385 * 386 * @internal 387 */ 388 UnicodeString fSymbols[kFormatSymbolCount]; 389 390 /** 391 * Non-symbol variable for getConstSymbol(). Always empty. 392 * @internal 393 */ 394 UnicodeString fNoSymbol; 395 396 Locale locale; 397 398 char actualLocale[ULOC_FULLNAME_CAPACITY]; 399 char validLocale[ULOC_FULLNAME_CAPACITY]; 400 const UChar* currPattern; 401 402 UnicodeString currencySpcBeforeSym[kCurrencySpacingCount]; 403 UnicodeString currencySpcAfterSym[kCurrencySpacingCount]; 404 }; 405 406 // ------------------------------------- 407 408 inline UnicodeString 409 DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const { 410 const UnicodeString *strPtr; 411 if(symbol < kFormatSymbolCount) { 412 strPtr = &fSymbols[symbol]; 413 } else { 414 strPtr = &fNoSymbol; 415 } 416 return *strPtr; 417 } 418 419 inline const UnicodeString & 420 DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const { 421 const UnicodeString *strPtr; 422 if(symbol < kFormatSymbolCount) { 423 strPtr = &fSymbols[symbol]; 424 } else { 425 strPtr = &fNoSymbol; 426 } 427 return *strPtr; 428 } 429 430 // ------------------------------------- 431 432 inline void 433 DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits = TRUE) { 434 if(symbol<kFormatSymbolCount) { 435 fSymbols[symbol]=value; 436 } 437 438 // If the zero digit is being set to a known zero digit according to Unicode, 439 // then we automatically set the corresponding 1-9 digits 440 if ( propogateDigits && symbol == kZeroDigitSymbol && value.countChar32() == 1 ) { 441 UChar32 sym = value.char32At(0); 442 if ( u_charDigitValue(sym) == 0 ) { 443 for ( int8_t i = 1 ; i<= 9 ; i++ ) { 444 sym++; 445 fSymbols[(int)kOneDigitSymbol+i-1] = UnicodeString(sym); 446 } 447 } 448 } 449 } 450 451 // ------------------------------------- 452 453 inline Locale 454 DecimalFormatSymbols::getLocale() const { 455 return locale; 456 } 457 458 inline const UChar* 459 DecimalFormatSymbols::getCurrencyPattern() const { 460 return currPattern; 461 } 462 U_NAMESPACE_END 463 464 #endif /* #if !UCONFIG_NO_FORMATTING */ 465 466 #endif // _DCFMTSYM 467 //eof 468