1/*
2********************************************************************************
3*   Copyright (C) 1997-2009, 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
30#if !UCONFIG_NO_FORMATTING
31
32#include "unicode/uobject.h"
33#include "unicode/locid.h"
34
35/**
36 * \file
37 * \brief C++ API: Symbols for formatting numbers.
38 */
39
40
41U_NAMESPACE_BEGIN
42
43/**
44 * This class represents the set of symbols needed by DecimalFormat
45 * to format numbers. DecimalFormat creates for itself an instance of
46 * DecimalFormatSymbols from its locale data.  If you need to change any
47 * of these symbols, you can get the DecimalFormatSymbols object from
48 * your DecimalFormat and modify it.
49 * <P>
50 * Here are the special characters used in the parts of the
51 * subpattern, with notes on their usage.
52 * <pre>
53 * \code
54 *        Symbol   Meaning
55 *          0      a digit
56 *          #      a digit, zero shows as absent
57 *          .      placeholder for decimal separator
58 *          ,      placeholder for grouping separator.
59 *          ;      separates formats.
60 *          -      default negative prefix.
61 *          %      divide by 100 and show as percentage
62 *          X      any other characters can be used in the prefix or suffix
63 *          '      used to quote special characters in a prefix or suffix.
64 * \endcode
65 *  </pre>
66 * [Notes]
67 * <P>
68 * If there is no explicit negative subpattern, - is prefixed to the
69 * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00".
70 * <P>
71 * The grouping separator is commonly used for thousands, but in some
72 * countries for ten-thousands. The interval is a constant number of
73 * digits between the grouping characters, such as 100,000,000 or 1,0000,0000.
74 * If you supply a pattern with multiple grouping characters, the interval
75 * between the last one and the end of the integer is the one that is
76 * used. So "#,##,###,####" == "######,####" == "##,####,####".
77 * <P>
78 * This class only handles localized digits where the 10 digits are
79 * contiguous in Unicode, from 0 to 9. Other digits sets (such as
80 * superscripts) would need a different subclass.
81 */
82class U_I18N_API DecimalFormatSymbols : public UObject {
83public:
84    /**
85     * Constants for specifying a number format symbol.
86     * @stable ICU 2.0
87     */
88    enum ENumberFormatSymbol {
89        /** The decimal separator */
90        kDecimalSeparatorSymbol,
91        /** The grouping separator */
92        kGroupingSeparatorSymbol,
93        /** The pattern separator */
94        kPatternSeparatorSymbol,
95        /** The percent sign */
96        kPercentSymbol,
97        /** Zero*/
98        kZeroDigitSymbol,
99        /** Character representing a digit in the pattern */
100        kDigitSymbol,
101        /** The minus sign */
102        kMinusSignSymbol,
103        /** The plus sign */
104        kPlusSignSymbol,
105        /** The currency symbol */
106        kCurrencySymbol,
107        /** The international currency symbol */
108        kIntlCurrencySymbol,
109        /** The monetary separator */
110        kMonetarySeparatorSymbol,
111        /** The exponential symbol */
112        kExponentialSymbol,
113        /** Per mill symbol - replaces kPermillSymbol */
114        kPerMillSymbol,
115        /** Escape padding character */
116        kPadEscapeSymbol,
117        /** Infinity symbol */
118        kInfinitySymbol,
119        /** Nan symbol */
120        kNaNSymbol,
121        /** Significant digit symbol
122         * @stable ICU 3.0 */
123        kSignificantDigitSymbol,
124        /** The monetary grouping separator
125         * @stable ICU 3.6
126         */
127        kMonetaryGroupingSeparatorSymbol,
128        /** count symbol constants */
129        kFormatSymbolCount
130    };
131
132    /**
133      * Constants for specifying currency spacing
134      * @draft ICU 4.2
135      */
136     enum ECurrencySpacing {
137       kCurrencyMatch,
138       kSurroundingMatch,
139       kInsert,
140       kCurrencySpacingCount
141     };
142
143    /**
144     * Create a DecimalFormatSymbols object for the given locale.
145     *
146     * @param locale    The locale to get symbols for.
147     * @param status    Input/output parameter, set to success or
148     *                  failure code upon return.
149     * @stable ICU 2.0
150     */
151    DecimalFormatSymbols(const Locale& locale, UErrorCode& status);
152
153    /**
154     * Create a DecimalFormatSymbols object for the default locale.
155     * This constructor will not fail.  If the resource file data is
156     * not available, it will use hard-coded last-resort data and
157     * set status to U_USING_FALLBACK_ERROR.
158     *
159     * @param status    Input/output parameter, set to success or
160     *                  failure code upon return.
161     * @stable ICU 2.0
162     */
163    DecimalFormatSymbols( UErrorCode& status);
164
165    /**
166     * Copy constructor.
167     * @stable ICU 2.0
168     */
169    DecimalFormatSymbols(const DecimalFormatSymbols&);
170
171    /**
172     * Assignment operator.
173     * @stable ICU 2.0
174     */
175    DecimalFormatSymbols& operator=(const DecimalFormatSymbols&);
176
177    /**
178     * Destructor.
179     * @stable ICU 2.0
180     */
181    virtual ~DecimalFormatSymbols();
182
183    /**
184     * Return true if another object is semantically equal to this one.
185     *
186     * @param other    the object to be compared with.
187     * @return         true if another object is semantically equal to this one.
188     * @stable ICU 2.0
189     */
190    UBool operator==(const DecimalFormatSymbols& other) const;
191
192    /**
193     * Return true if another object is semantically unequal to this one.
194     *
195     * @param other    the object to be compared with.
196     * @return         true if another object is semantically unequal to this one.
197     * @stable ICU 2.0
198     */
199    UBool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); }
200
201    /**
202     * Get one of the format symbols by its enum constant.
203     * Each symbol is stored as a string so that graphemes
204     * (characters with modifyer letters) can be used.
205     *
206     * @param symbol    Constant to indicate a number format symbol.
207     * @return    the format symbols by the param 'symbol'
208     * @stable ICU 2.0
209     */
210    inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const;
211
212    /**
213     * Set one of the format symbols by its enum constant.
214     * Each symbol is stored as a string so that graphemes
215     * (characters with modifyer letters) can be used.
216     *
217     * @param symbol    Constant to indicate a number format symbol.
218     * @param value     value of the format sybmol
219     * @stable ICU 2.0
220     */
221    void setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value);
222
223    /**
224     * Returns the locale for which this object was constructed.
225     * @stable ICU 2.6
226     */
227    inline Locale getLocale() const;
228
229    /**
230     * Returns the locale for this object. Two flavors are available:
231     * valid and actual locale.
232     * @stable ICU 2.8
233     */
234    Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
235
236    /**
237      * Get pattern string for 'CurrencySpacing' that can be applied to
238      * currency format.
239      * This API gets the CurrencySpacing data from ResourceBundle. The pattern can
240      * be empty if there is no data from current locale and its parent locales.
241      *
242      * @param type :  kCurrencyMatch, kSurroundingMatch or kInsert.
243      * @param beforeCurrency : true if the pattern is for before currency symbol.
244      *                         false if the pattern is for after currency symbol.
245      * @param status: Input/output parameter, set to success or
246      *                  failure code upon return.
247      * @return pattern string for currencyMatch, surroundingMatch or spaceInsert.
248      *     Return empty string if there is no data for this locale and its parent
249      *     locales.
250      * @draft ICU 4.2
251      */
252     const UnicodeString& getPatternForCurrencySpacing(ECurrencySpacing type,
253                                                 UBool beforeCurrency,
254                                                 UErrorCode& status) const;
255     /**
256       * Set pattern string for 'CurrencySpacing' that can be applied to
257       * currency format.
258       *
259       * @param type : kCurrencyMatch, kSurroundingMatch or kInsert.
260       * @param beforeCurrency : true if the pattern is for before currency symbol.
261       *                         false if the pattern is for after currency symbol.
262       * @param pattern : pattern string to override current setting.
263       * @draft ICU 4.2
264       */
265     void setPatternForCurrencySpacing(ECurrencySpacing type,
266                                       UBool beforeCurrency,
267                                       const UnicodeString& pattern);
268
269    /**
270     * ICU "poor man's RTTI", returns a UClassID for the actual class.
271     *
272     * @stable ICU 2.2
273     */
274    virtual UClassID getDynamicClassID() const;
275
276    /**
277     * ICU "poor man's RTTI", returns a UClassID for this class.
278     *
279     * @stable ICU 2.2
280     */
281    static UClassID U_EXPORT2 getStaticClassID();
282
283private:
284    DecimalFormatSymbols(); // default constructor not implemented
285
286    /**
287     * Initializes the symbols from the LocaleElements resource bundle.
288     * Note: The organization of LocaleElements badly needs to be
289     * cleaned up.
290     *
291     * @param locale               The locale to get symbols for.
292     * @param success              Input/output parameter, set to success or
293     *                             failure code upon return.
294     * @param useLastResortData    determine if use last resort data
295     */
296    void initialize(const Locale& locale, UErrorCode& success, UBool useLastResortData = FALSE);
297
298    /**
299     * Initialize the symbols from the given array of UnicodeStrings.
300     * The array must be of the correct size.
301     *
302     * @param numberElements    the number format symbols
303     * @param numberElementsLength length of numberElements
304     */
305    void initialize(const UChar** numberElements, int32_t *numberElementsStrLen, int32_t numberElementsLength);
306
307    /**
308     * Initialize the symbols with default values.
309     */
310    void initialize();
311
312    void setCurrencyForSymbols();
313
314public:
315    /**
316     * _Internal_ function - more efficient version of getSymbol,
317     * returning a const reference to one of the symbol strings.
318     * The returned reference becomes invalid when the symbol is changed
319     * or when the DecimalFormatSymbols are destroyed.
320     * ### TODO markus 2002oct11: Consider proposing getConstSymbol() to be really public.
321     *
322     * @param symbol Constant to indicate a number format symbol.
323     * @return the format symbol by the param 'symbol'
324     * @internal
325     */
326    inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const;
327
328    /**
329     * Returns that pattern stored in currecy info. Internal API for use by NumberFormat API.
330     * @internal
331     */
332    inline const UChar* getCurrencyPattern(void) const;
333
334private:
335    /**
336     * Private symbol strings.
337     * They are either loaded from a resource bundle or otherwise owned.
338     * setSymbol() clones the symbol string.
339     * Readonly aliases can only come from a resource bundle, so that we can always
340     * use fastCopyFrom() with them.
341     *
342     * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes
343     * from private to protected,
344     * or when fSymbols can be set any other way that allows them to be readonly aliases
345     * to non-resource bundle strings,
346     * then regular UnicodeString copies must be used instead of fastCopyFrom().
347     *
348     * @internal
349     */
350    UnicodeString fSymbols[kFormatSymbolCount];
351
352    /**
353     * Non-symbol variable for getConstSymbol(). Always empty.
354     * @internal
355     */
356    UnicodeString fNoSymbol;
357
358    Locale locale;
359
360    char actualLocale[ULOC_FULLNAME_CAPACITY];
361    char validLocale[ULOC_FULLNAME_CAPACITY];
362    const UChar* currPattern;
363
364    UnicodeString currencySpcBeforeSym[kCurrencySpacingCount];
365    UnicodeString currencySpcAfterSym[kCurrencySpacingCount];
366};
367
368// -------------------------------------
369
370inline UnicodeString
371DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
372    const UnicodeString *strPtr;
373    if(symbol < kFormatSymbolCount) {
374        strPtr = &fSymbols[symbol];
375    } else {
376        strPtr = &fNoSymbol;
377    }
378    return *strPtr;
379}
380
381inline const UnicodeString &
382DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const {
383    const UnicodeString *strPtr;
384    if(symbol < kFormatSymbolCount) {
385        strPtr = &fSymbols[symbol];
386    } else {
387        strPtr = &fNoSymbol;
388    }
389    return *strPtr;
390}
391
392// -------------------------------------
393
394inline void
395DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value) {
396    if(symbol<kFormatSymbolCount) {
397        fSymbols[symbol]=value;
398    }
399}
400
401// -------------------------------------
402
403inline Locale
404DecimalFormatSymbols::getLocale() const {
405    return locale;
406}
407
408inline const UChar*
409DecimalFormatSymbols::getCurrencyPattern() const {
410    return currPattern;
411}
412U_NAMESPACE_END
413
414#endif /* #if !UCONFIG_NO_FORMATTING */
415
416#endif // _DCFMTSYM
417//eof
418