• 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     /**
203      * Copy constructor.
204      * @stable ICU 2.0
205      */
206     DecimalFormatSymbols(const DecimalFormatSymbols&);
207 
208     /**
209      * Assignment operator.
210      * @stable ICU 2.0
211      */
212     DecimalFormatSymbols& operator=(const DecimalFormatSymbols&);
213 
214     /**
215      * Destructor.
216      * @stable ICU 2.0
217      */
218     virtual ~DecimalFormatSymbols();
219 
220     /**
221      * Return true if another object is semantically equal to this one.
222      *
223      * @param other    the object to be compared with.
224      * @return         true if another object is semantically equal to this one.
225      * @stable ICU 2.0
226      */
227     UBool operator==(const DecimalFormatSymbols& other) const;
228 
229     /**
230      * Return true if another object is semantically unequal to this one.
231      *
232      * @param other    the object to be compared with.
233      * @return         true if another object is semantically unequal to this one.
234      * @stable ICU 2.0
235      */
236     UBool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); }
237 
238     /**
239      * Get one of the format symbols by its enum constant.
240      * Each symbol is stored as a string so that graphemes
241      * (characters with modifier letters) can be used.
242      *
243      * @param symbol    Constant to indicate a number format symbol.
244      * @return    the format symbols by the param 'symbol'
245      * @stable ICU 2.0
246      */
247     inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const;
248 
249     /**
250      * Set one of the format symbols by its enum constant.
251      * Each symbol is stored as a string so that graphemes
252      * (characters with modifier letters) can be used.
253      *
254      * @param symbol    Constant to indicate a number format symbol.
255      * @param value     value of the format symbol
256      * @param propogateDigits If false, setting the zero digit will not automatically set 1-9.
257      *     The default behavior is to automatically set 1-9 if zero is being set and the value
258      *     it is being set to corresponds to a known Unicode zero digit.
259      * @stable ICU 2.0
260      */
261     void setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits);
262 
263     /**
264      * Returns the locale for which this object was constructed.
265      * @stable ICU 2.6
266      */
267     inline Locale getLocale() const;
268 
269     /**
270      * Returns the locale for this object. Two flavors are available:
271      * valid and actual locale.
272      * @stable ICU 2.8
273      */
274     Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
275 
276     /**
277       * Get pattern string for 'CurrencySpacing' that can be applied to
278       * currency format.
279       * This API gets the CurrencySpacing data from ResourceBundle. The pattern can
280       * be empty if there is no data from current locale and its parent locales.
281       *
282       * @param type :  kCurrencyMatch, kSurroundingMatch or kInsert.
283       * @param beforeCurrency : true if the pattern is for before currency symbol.
284       *                         false if the pattern is for after currency symbol.
285       * @param status: Input/output parameter, set to success or
286       *                  failure code upon return.
287       * @return pattern string for currencyMatch, surroundingMatch or spaceInsert.
288       *     Return empty string if there is no data for this locale and its parent
289       *     locales.
290       * @draft ICU 4.2
291       */
292      const UnicodeString& getPatternForCurrencySpacing(ECurrencySpacing type,
293                                                  UBool beforeCurrency,
294                                                  UErrorCode& status) const;
295      /**
296        * Set pattern string for 'CurrencySpacing' that can be applied to
297        * currency format.
298        *
299        * @param type : kCurrencyMatch, kSurroundingMatch or kInsert.
300        * @param beforeCurrency : true if the pattern is for before currency symbol.
301        *                         false if the pattern is for after currency symbol.
302        * @param pattern : pattern string to override current setting.
303        * @draft ICU 4.2
304        */
305      void setPatternForCurrencySpacing(ECurrencySpacing type,
306                                        UBool beforeCurrency,
307                                        const UnicodeString& pattern);
308 
309     /**
310      * ICU "poor man's RTTI", returns a UClassID for the actual class.
311      *
312      * @stable ICU 2.2
313      */
314     virtual UClassID getDynamicClassID() const;
315 
316     /**
317      * ICU "poor man's RTTI", returns a UClassID for this class.
318      *
319      * @stable ICU 2.2
320      */
321     static UClassID U_EXPORT2 getStaticClassID();
322 
323 private:
324     DecimalFormatSymbols(); // default constructor not implemented
325 
326     /**
327      * Initializes the symbols from the LocaleElements resource bundle.
328      * Note: The organization of LocaleElements badly needs to be
329      * cleaned up.
330      *
331      * @param locale               The locale to get symbols for.
332      * @param success              Input/output parameter, set to success or
333      *                             failure code upon return.
334      * @param useLastResortData    determine if use last resort data
335      */
336     void initialize(const Locale& locale, UErrorCode& success, UBool useLastResortData = FALSE);
337 
338     /**
339      * Initialize the symbols with default values.
340      */
341     void initialize();
342 
343     void setCurrencyForSymbols();
344 
345 public:
346     /**
347      * _Internal_ function - more efficient version of getSymbol,
348      * returning a const reference to one of the symbol strings.
349      * The returned reference becomes invalid when the symbol is changed
350      * or when the DecimalFormatSymbols are destroyed.
351      * ### TODO markus 2002oct11: Consider proposing getConstSymbol() to be really public.
352      *
353      * @param symbol Constant to indicate a number format symbol.
354      * @return the format symbol by the param 'symbol'
355      * @internal
356      */
357     inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const;
358 
359     /**
360      * Returns that pattern stored in currecy info. Internal API for use by NumberFormat API.
361      * @internal
362      */
363     inline const UChar* getCurrencyPattern(void) const;
364 
365 private:
366     /**
367      * Private symbol strings.
368      * They are either loaded from a resource bundle or otherwise owned.
369      * setSymbol() clones the symbol string.
370      * Readonly aliases can only come from a resource bundle, so that we can always
371      * use fastCopyFrom() with them.
372      *
373      * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes
374      * from private to protected,
375      * or when fSymbols can be set any other way that allows them to be readonly aliases
376      * to non-resource bundle strings,
377      * then regular UnicodeString copies must be used instead of fastCopyFrom().
378      *
379      * @internal
380      */
381     UnicodeString fSymbols[kFormatSymbolCount];
382 
383     /**
384      * Non-symbol variable for getConstSymbol(). Always empty.
385      * @internal
386      */
387     UnicodeString fNoSymbol;
388 
389     Locale locale;
390 
391     char actualLocale[ULOC_FULLNAME_CAPACITY];
392     char validLocale[ULOC_FULLNAME_CAPACITY];
393     const UChar* currPattern;
394 
395     UnicodeString currencySpcBeforeSym[kCurrencySpacingCount];
396     UnicodeString currencySpcAfterSym[kCurrencySpacingCount];
397 };
398 
399 // -------------------------------------
400 
401 inline UnicodeString
getSymbol(ENumberFormatSymbol symbol)402 DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
403     const UnicodeString *strPtr;
404     if(symbol < kFormatSymbolCount) {
405         strPtr = &fSymbols[symbol];
406     } else {
407         strPtr = &fNoSymbol;
408     }
409     return *strPtr;
410 }
411 
412 inline const UnicodeString &
getConstSymbol(ENumberFormatSymbol symbol)413 DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const {
414     const UnicodeString *strPtr;
415     if(symbol < kFormatSymbolCount) {
416         strPtr = &fSymbols[symbol];
417     } else {
418         strPtr = &fNoSymbol;
419     }
420     return *strPtr;
421 }
422 
423 // -------------------------------------
424 
425 inline void
426 DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits = TRUE) {
427     if(symbol<kFormatSymbolCount) {
428         fSymbols[symbol]=value;
429     }
430 
431     // If the zero digit is being set to a known zero digit according to Unicode,
432     // then we automatically set the corresponding 1-9 digits
433     if ( propogateDigits && symbol == kZeroDigitSymbol && value.countChar32() == 1 ) {
434         UChar32 sym = value.char32At(0);
435         if ( u_charDigitValue(sym) == 0 ) {
436             for ( int8_t i = 1 ; i<= 9 ; i++ ) {
437                 sym++;
438                 fSymbols[(int)kOneDigitSymbol+i-1] = UnicodeString(sym);
439             }
440         }
441     }
442 }
443 
444 // -------------------------------------
445 
446 inline Locale
getLocale()447 DecimalFormatSymbols::getLocale() const {
448     return locale;
449 }
450 
451 inline const UChar*
getCurrencyPattern()452 DecimalFormatSymbols::getCurrencyPattern() const {
453     return currPattern;
454 }
455 U_NAMESPACE_END
456 
457 #endif /* #if !UCONFIG_NO_FORMATTING */
458 
459 #endif // _DCFMTSYM
460 //eof
461