• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
getSymbol(ENumberFormatSymbol symbol)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 &
getConstSymbol(ENumberFormatSymbol symbol)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
getLocale()454 DecimalFormatSymbols::getLocale() const {
455     return locale;
456 }
457 
458 inline const UChar*
getCurrencyPattern()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