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