Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/unicode/dcfmtsym.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // © 2016 and later: Unicode, Inc. and others.
0002 // License & terms of use: http://www.unicode.org/copyright.html
0003 /*
0004 ********************************************************************************
0005 *   Copyright (C) 1997-2016, International Business Machines
0006 *   Corporation and others.  All Rights Reserved.
0007 ********************************************************************************
0008 *
0009 * File DCFMTSYM.H
0010 *
0011 * Modification History:
0012 *
0013 *   Date        Name        Description
0014 *   02/19/97    aliu        Converted from java.
0015 *   03/18/97    clhuang     Updated per C++ implementation.
0016 *   03/27/97    helena      Updated to pass the simple test after code review.
0017 *   08/26/97    aliu        Added currency/intl currency symbol support.
0018 *   07/22/98    stephen     Changed to match C++ style
0019 *                            currencySymbol -> fCurrencySymbol
0020 *                            Constants changed from CAPS to kCaps
0021 *   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
0022 *   09/22/00    grhoten     Marked deprecation tags with a pointer to replacement
0023 *                            functions.
0024 ********************************************************************************
0025 */
0026 
0027 #ifndef DCFMTSYM_H
0028 #define DCFMTSYM_H
0029 
0030 #include "unicode/utypes.h"
0031 
0032 #if U_SHOW_CPLUSPLUS_API
0033 
0034 #if !UCONFIG_NO_FORMATTING
0035 
0036 #include "unicode/uchar.h"
0037 #include "unicode/uobject.h"
0038 #include "unicode/locid.h"
0039 #include "unicode/numsys.h"
0040 #include "unicode/unum.h"
0041 #include "unicode/unistr.h"
0042 
0043 /**
0044  * \file
0045  * \brief C++ API: Symbols for formatting numbers.
0046  */
0047 
0048 
0049 U_NAMESPACE_BEGIN
0050 
0051 /**
0052  * This class represents the set of symbols needed by DecimalFormat
0053  * to format numbers. DecimalFormat creates for itself an instance of
0054  * DecimalFormatSymbols from its locale data.  If you need to change any
0055  * of these symbols, you can get the DecimalFormatSymbols object from
0056  * your DecimalFormat and modify it.
0057  * <P>
0058  * Here are the special characters used in the parts of the
0059  * subpattern, with notes on their usage.
0060  * <pre>
0061  * \code
0062  *        Symbol   Meaning
0063  *          0      a digit
0064  *          #      a digit, zero shows as absent
0065  *          .      placeholder for decimal separator
0066  *          ,      placeholder for grouping separator.
0067  *          ;      separates formats.
0068  *          -      default negative prefix.
0069  *          %      divide by 100 and show as percentage
0070  *          X      any other characters can be used in the prefix or suffix
0071  *          '      used to quote special characters in a prefix or suffix.
0072  * \endcode
0073  *  </pre>
0074  * [Notes]
0075  * <P>
0076  * If there is no explicit negative subpattern, - is prefixed to the
0077  * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00".
0078  * <P>
0079  * The grouping separator is commonly used for thousands, but in some
0080  * countries for ten-thousands. The interval is a constant number of
0081  * digits between the grouping characters, such as 100,000,000 or 1,0000,0000.
0082  * If you supply a pattern with multiple grouping characters, the interval
0083  * between the last one and the end of the integer is the one that is
0084  * used. So "#,##,###,####" == "######,####" == "##,####,####".
0085  */
0086 class U_I18N_API DecimalFormatSymbols : public UObject {
0087 public:
0088     /**
0089      * Constants for specifying a number format symbol.
0090      * @stable ICU 2.0
0091      */
0092     enum ENumberFormatSymbol {
0093         /** The decimal separator */
0094         kDecimalSeparatorSymbol,
0095         /** The grouping separator */
0096         kGroupingSeparatorSymbol,
0097         /** The pattern separator */
0098         kPatternSeparatorSymbol,
0099         /** The percent sign */
0100         kPercentSymbol,
0101         /** Zero*/
0102         kZeroDigitSymbol,
0103         /** Character representing a digit in the pattern */
0104         kDigitSymbol,
0105         /** The minus sign */
0106         kMinusSignSymbol,
0107         /** The plus sign */
0108         kPlusSignSymbol,
0109         /** The currency symbol */
0110         kCurrencySymbol,
0111         /** The international currency symbol */
0112         kIntlCurrencySymbol,
0113         /** The monetary separator */
0114         kMonetarySeparatorSymbol,
0115         /** The exponential symbol */
0116         kExponentialSymbol,
0117         /** Per mill symbol - replaces kPermillSymbol */
0118         kPerMillSymbol,
0119         /** Escape padding character */
0120         kPadEscapeSymbol,
0121         /** Infinity symbol */
0122         kInfinitySymbol,
0123         /** Nan symbol */
0124         kNaNSymbol,
0125         /** Significant digit symbol
0126          * @stable ICU 3.0 */
0127         kSignificantDigitSymbol,
0128         /** The monetary grouping separator
0129          * @stable ICU 3.6
0130          */
0131         kMonetaryGroupingSeparatorSymbol,
0132         /** One
0133          * @stable ICU 4.6
0134          */
0135         kOneDigitSymbol,
0136         /** Two
0137          * @stable ICU 4.6
0138          */
0139         kTwoDigitSymbol,
0140         /** Three
0141          * @stable ICU 4.6
0142          */
0143         kThreeDigitSymbol,
0144         /** Four
0145          * @stable ICU 4.6
0146          */
0147         kFourDigitSymbol,
0148         /** Five
0149          * @stable ICU 4.6
0150          */
0151         kFiveDigitSymbol,
0152         /** Six
0153          * @stable ICU 4.6
0154          */
0155         kSixDigitSymbol,
0156         /** Seven
0157          * @stable ICU 4.6
0158          */
0159         kSevenDigitSymbol,
0160         /** Eight
0161          * @stable ICU 4.6
0162          */
0163         kEightDigitSymbol,
0164         /** Nine
0165          * @stable ICU 4.6
0166          */
0167         kNineDigitSymbol,
0168         /** Multiplication sign.
0169          * @stable ICU 54
0170          */
0171         kExponentMultiplicationSymbol,
0172 #ifndef U_HIDE_INTERNAL_API
0173         /** Approximately sign.
0174          * @internal
0175          */
0176         kApproximatelySignSymbol,
0177 #endif  /* U_HIDE_INTERNAL_API */
0178         /** count symbol constants */
0179         kFormatSymbolCount = kExponentMultiplicationSymbol + 2
0180     };
0181 
0182     /**
0183      * Create a DecimalFormatSymbols object for the given locale.
0184      *
0185      * @param locale    The locale to get symbols for.
0186      * @param status    Input/output parameter, set to success or
0187      *                  failure code upon return.
0188      * @stable ICU 2.0
0189      */
0190     DecimalFormatSymbols(const Locale& locale, UErrorCode& status);
0191 
0192     /**
0193      * Creates a DecimalFormatSymbols instance for the given locale with digits and symbols
0194      * corresponding to the given NumberingSystem.
0195      *
0196      * This constructor behaves equivalently to the normal constructor called with a locale having a
0197      * "numbers=xxxx" keyword specifying the numbering system by name.
0198      *
0199      * In this constructor, the NumberingSystem argument will be used even if the locale has its own
0200      * "numbers=xxxx" keyword.
0201      *
0202      * @param locale    The locale to get symbols for.
0203      * @param ns        The numbering system.
0204      * @param status    Input/output parameter, set to success or
0205      *                  failure code upon return.
0206      * @stable ICU 60
0207      */
0208     DecimalFormatSymbols(const Locale& locale, const NumberingSystem& ns, UErrorCode& status);
0209 
0210     /**
0211      * Create a DecimalFormatSymbols object for the default locale.
0212      * This constructor will not fail.  If the resource file data is
0213      * not available, it will use hard-coded last-resort data and
0214      * set status to U_USING_FALLBACK_ERROR.
0215      *
0216      * @param status    Input/output parameter, set to success or
0217      *                  failure code upon return.
0218      * @stable ICU 2.0
0219      */
0220     DecimalFormatSymbols(UErrorCode& status);
0221 
0222     /**
0223      * Creates a DecimalFormatSymbols object with last-resort data.
0224      * Intended for callers who cache the symbols data and
0225      * set all symbols on the resulting object.
0226      *
0227      * The last-resort symbols are similar to those for the root data,
0228      * except that the grouping separators are empty,
0229      * the NaN symbol is U+FFFD rather than "NaN",
0230      * and the CurrencySpacing patterns are empty.
0231      *
0232      * @param status    Input/output parameter, set to success or
0233      *                  failure code upon return.
0234      * @return last-resort symbols
0235      * @stable ICU 52
0236      */
0237     static DecimalFormatSymbols* createWithLastResortData(UErrorCode& status);
0238 
0239     /**
0240      * Copy constructor.
0241      * @stable ICU 2.0
0242      */
0243     DecimalFormatSymbols(const DecimalFormatSymbols&);
0244 
0245     /**
0246      * Assignment operator.
0247      * @stable ICU 2.0
0248      */
0249     DecimalFormatSymbols& operator=(const DecimalFormatSymbols&);
0250 
0251     /**
0252      * Destructor.
0253      * @stable ICU 2.0
0254      */
0255     virtual ~DecimalFormatSymbols();
0256 
0257     /**
0258      * Return true if another object is semantically equal to this one.
0259      *
0260      * @param other    the object to be compared with.
0261      * @return         true if another object is semantically equal to this one.
0262      * @stable ICU 2.0
0263      */
0264     bool operator==(const DecimalFormatSymbols& other) const;
0265 
0266     /**
0267      * Return true if another object is semantically unequal to this one.
0268      *
0269      * @param other    the object to be compared with.
0270      * @return         true if another object is semantically unequal to this one.
0271      * @stable ICU 2.0
0272      */
0273     bool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); }
0274 
0275     /**
0276      * Get one of the format symbols by its enum constant.
0277      * Each symbol is stored as a string so that graphemes
0278      * (characters with modifier letters) can be used.
0279      *
0280      * @param symbol    Constant to indicate a number format symbol.
0281      * @return    the format symbols by the param 'symbol'
0282      * @stable ICU 2.0
0283      */
0284     inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const;
0285 
0286     /**
0287      * Set one of the format symbols by its enum constant.
0288      * Each symbol is stored as a string so that graphemes
0289      * (characters with modifier letters) can be used.
0290      *
0291      * @param symbol    Constant to indicate a number format symbol.
0292      * @param value     value of the format symbol
0293      * @param propagateDigits If false, setting the zero digit will not automatically set 1-9.
0294      *     The default behavior is to automatically set 1-9 if zero is being set and the value
0295      *     it is being set to corresponds to a known Unicode zero digit.
0296      * @stable ICU 2.0
0297      */
0298     void setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propagateDigits);
0299 
0300 #ifndef U_HIDE_INTERNAL_API
0301     /**
0302      * Loads symbols for the specified currency into this instance.
0303      *
0304      * This method is internal. If you think it should be public, file a ticket.
0305      *
0306      * @internal
0307      */
0308     void setCurrency(const char16_t* currency, UErrorCode& status);
0309 #endif  // U_HIDE_INTERNAL_API
0310 
0311     /**
0312      * Returns the locale for which this object was constructed.
0313      * @stable ICU 2.6
0314      */
0315     inline Locale getLocale() const;
0316 
0317     /**
0318      * Returns the locale for this object. Two flavors are available:
0319      * valid and actual locale.
0320      * @stable ICU 2.8
0321      */
0322     Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
0323 
0324     /**
0325       * Get pattern string for 'CurrencySpacing' that can be applied to
0326       * currency format.
0327       * This API gets the CurrencySpacing data from ResourceBundle. The pattern can
0328       * be empty if there is no data from current locale and its parent locales.
0329       *
0330       * @param type :  UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT.
0331       * @param beforeCurrency : true if the pattern is for before currency symbol.
0332       *                         false if the pattern is for after currency symbol.
0333       * @param status: Input/output parameter, set to success or
0334       *                  failure code upon return.
0335       * @return pattern string for currencyMatch, surroundingMatch or spaceInsert.
0336       *     Return empty string if there is no data for this locale and its parent
0337       *     locales.
0338       * @stable ICU 4.8
0339       */
0340      const UnicodeString& getPatternForCurrencySpacing(UCurrencySpacing type,
0341                                                  UBool beforeCurrency,
0342                                                  UErrorCode& status) const;
0343      /**
0344        * Set pattern string for 'CurrencySpacing' that can be applied to
0345        * currency format.
0346        *
0347        * @param type : UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT.
0348        * @param beforeCurrency : true if the pattern is for before currency symbol.
0349        *                         false if the pattern is for after currency symbol.
0350        * @param pattern : pattern string to override current setting.
0351        * @stable ICU 4.8
0352        */
0353      void setPatternForCurrencySpacing(UCurrencySpacing type,
0354                                        UBool beforeCurrency,
0355                                        const UnicodeString& pattern);
0356 
0357     /**
0358      * ICU "poor man's RTTI", returns a UClassID for the actual class.
0359      *
0360      * @stable ICU 2.2
0361      */
0362     virtual UClassID getDynamicClassID() const override;
0363 
0364     /**
0365      * ICU "poor man's RTTI", returns a UClassID for this class.
0366      *
0367      * @stable ICU 2.2
0368      */
0369     static UClassID U_EXPORT2 getStaticClassID();
0370 
0371 private:
0372     DecimalFormatSymbols();
0373 
0374     /**
0375      * Initializes the symbols from the LocaleElements resource bundle.
0376      * Note: The organization of LocaleElements badly needs to be
0377      * cleaned up.
0378      *
0379      * @param locale               The locale to get symbols for.
0380      * @param success              Input/output parameter, set to success or
0381      *                             failure code upon return.
0382      * @param useLastResortData    determine if use last resort data
0383      * @param ns                   The NumberingSystem to use; otherwise, fall
0384      *                             back to the locale.
0385      */
0386     void initialize(const Locale& locale, UErrorCode& success,
0387                     UBool useLastResortData = false, const NumberingSystem* ns = nullptr);
0388 
0389     /**
0390      * Initialize the symbols with default values.
0391      */
0392     void initialize();
0393 
0394 public:
0395 
0396 #ifndef U_HIDE_INTERNAL_API
0397     /**
0398      * @internal For ICU use only
0399      */
0400     inline UBool isCustomCurrencySymbol() const {
0401         return fIsCustomCurrencySymbol;
0402     }
0403 
0404     /**
0405      * @internal For ICU use only
0406      */
0407     inline UBool isCustomIntlCurrencySymbol() const {
0408         return fIsCustomIntlCurrencySymbol;
0409     }
0410 
0411     /**
0412      * @internal For ICU use only
0413      */
0414     inline UChar32 getCodePointZero() const {
0415         return fCodePointZero;
0416     }
0417 #endif  /* U_HIDE_INTERNAL_API */
0418 
0419     /**
0420      * _Internal_ function - more efficient version of getSymbol,
0421      * returning a const reference to one of the symbol strings.
0422      * The returned reference becomes invalid when the symbol is changed
0423      * or when the DecimalFormatSymbols are destroyed.
0424      * Note: moved \#ifndef U_HIDE_INTERNAL_API after this, since this is needed for inline in DecimalFormat
0425      *
0426      * This is not currently stable API, but if you think it should be stable,
0427      * post a comment on the following ticket and the ICU team will take a look:
0428      * https://unicode-org.atlassian.net/browse/ICU-13580
0429      *
0430      * @param symbol Constant to indicate a number format symbol.
0431      * @return the format symbol by the param 'symbol'
0432      * @internal
0433      */
0434     inline const UnicodeString& getConstSymbol(ENumberFormatSymbol symbol) const;
0435 
0436 #ifndef U_HIDE_INTERNAL_API
0437     /**
0438      * Returns the const UnicodeString reference, like getConstSymbol,
0439      * corresponding to the digit with the given value.  This is equivalent
0440      * to accessing the symbol from getConstSymbol with the corresponding
0441      * key, such as kZeroDigitSymbol or kOneDigitSymbol.
0442      *
0443      * This is not currently stable API, but if you think it should be stable,
0444      * post a comment on the following ticket and the ICU team will take a look:
0445      * https://unicode-org.atlassian.net/browse/ICU-13580
0446      *
0447      * @param digit The digit, an integer between 0 and 9 inclusive.
0448      *              If outside the range 0 to 9, the zero digit is returned.
0449      * @return the format symbol for the given digit.
0450      * @internal This API is currently for ICU use only.
0451      */
0452     inline const UnicodeString& getConstDigitSymbol(int32_t digit) const;
0453 
0454     /**
0455      * Returns that pattern stored in currency info. Internal API for use by NumberFormat API.
0456      * @internal
0457      */
0458     inline const char16_t* getCurrencyPattern(void) const;
0459 
0460     /**
0461      * Returns the numbering system with which this DecimalFormatSymbols was initialized.
0462      * @internal
0463      */
0464     inline const char* getNumberingSystemName(void) const;
0465 #endif  /* U_HIDE_INTERNAL_API */
0466 
0467 private:
0468     /**
0469      * Private symbol strings.
0470      * They are either loaded from a resource bundle or otherwise owned.
0471      * setSymbol() clones the symbol string.
0472      * Readonly aliases can only come from a resource bundle, so that we can always
0473      * use fastCopyFrom() with them.
0474      *
0475      * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes
0476      * from private to protected,
0477      * or when fSymbols can be set any other way that allows them to be readonly aliases
0478      * to non-resource bundle strings,
0479      * then regular UnicodeString copies must be used instead of fastCopyFrom().
0480      *
0481      */
0482     UnicodeString fSymbols[kFormatSymbolCount];
0483 
0484     /**
0485      * Non-symbol variable for getConstSymbol(). Always empty.
0486      */
0487     UnicodeString fNoSymbol;
0488 
0489     /**
0490      * Dealing with code points is faster than dealing with strings when formatting. Because of
0491      * this, we maintain a value containing the zero code point that is used whenever digitStrings
0492      * represents a sequence of ten code points in order.
0493      *
0494      * <p>If the value stored here is positive, it means that the code point stored in this value
0495      * corresponds to the digitStrings array, and codePointZero can be used instead of the
0496      * digitStrings array for the purposes of efficient formatting; if -1, then digitStrings does
0497      * *not* contain a sequence of code points, and it must be used directly.
0498      *
0499      * <p>It is assumed that codePointZero always shadows the value in digitStrings. codePointZero
0500      * should never be set directly; rather, it should be updated only when digitStrings mutates.
0501      * That is, the flow of information is digitStrings -> codePointZero, not the other way.
0502      */
0503     UChar32 fCodePointZero;
0504 
0505     Locale locale;
0506 
0507     char actualLocale[ULOC_FULLNAME_CAPACITY];
0508     char validLocale[ULOC_FULLNAME_CAPACITY];
0509     const char16_t* currPattern = nullptr;
0510 
0511     UnicodeString currencySpcBeforeSym[UNUM_CURRENCY_SPACING_COUNT];
0512     UnicodeString currencySpcAfterSym[UNUM_CURRENCY_SPACING_COUNT];
0513     UBool fIsCustomCurrencySymbol;
0514     UBool fIsCustomIntlCurrencySymbol;
0515     char nsName[kInternalNumSysNameCapacity+1] = {};
0516 };
0517 
0518 // -------------------------------------
0519 
0520 inline UnicodeString
0521 DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
0522     const UnicodeString *strPtr;
0523     if(symbol < kFormatSymbolCount) {
0524         strPtr = &fSymbols[symbol];
0525     } else {
0526         strPtr = &fNoSymbol;
0527     }
0528     return *strPtr;
0529 }
0530 
0531 // See comments above for this function. Not hidden with #ifdef U_HIDE_INTERNAL_API
0532 inline const UnicodeString &
0533 DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const {
0534     const UnicodeString *strPtr;
0535     if(symbol < kFormatSymbolCount) {
0536         strPtr = &fSymbols[symbol];
0537     } else {
0538         strPtr = &fNoSymbol;
0539     }
0540     return *strPtr;
0541 }
0542 
0543 #ifndef U_HIDE_INTERNAL_API
0544 inline const UnicodeString& DecimalFormatSymbols::getConstDigitSymbol(int32_t digit) const {
0545     if (digit < 0 || digit > 9) {
0546         digit = 0;
0547     }
0548     if (digit == 0) {
0549         return fSymbols[kZeroDigitSymbol];
0550     }
0551     ENumberFormatSymbol key = static_cast<ENumberFormatSymbol>(kOneDigitSymbol + digit - 1);
0552     return fSymbols[key];
0553 }
0554 #endif /* U_HIDE_INTERNAL_API */
0555 
0556 // -------------------------------------
0557 
0558 inline void
0559 DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propagateDigits = true) {
0560     if (symbol == kCurrencySymbol) {
0561         fIsCustomCurrencySymbol = true;
0562     }
0563     else if (symbol == kIntlCurrencySymbol) {
0564         fIsCustomIntlCurrencySymbol = true;
0565     }
0566     if(symbol<kFormatSymbolCount) {
0567         fSymbols[symbol]=value;
0568     }
0569 
0570     // If the zero digit is being set to a known zero digit according to Unicode,
0571     // then we automatically set the corresponding 1-9 digits
0572     // Also record updates to fCodePointZero. Be conservative if in doubt.
0573     if (symbol == kZeroDigitSymbol) {
0574         UChar32 sym = value.char32At(0);
0575         if ( propagateDigits && u_charDigitValue(sym) == 0 && value.countChar32() == 1 ) {
0576             fCodePointZero = sym;
0577             for ( int8_t i = 1 ; i<= 9 ; i++ ) {
0578                 sym++;
0579                 fSymbols[(int)kOneDigitSymbol+i-1] = UnicodeString(sym);
0580             }
0581         } else {
0582             fCodePointZero = -1;
0583         }
0584     } else if (symbol >= kOneDigitSymbol && symbol <= kNineDigitSymbol) {
0585         fCodePointZero = -1;
0586     }
0587 }
0588 
0589 // -------------------------------------
0590 
0591 inline Locale
0592 DecimalFormatSymbols::getLocale() const {
0593     return locale;
0594 }
0595 
0596 #ifndef U_HIDE_INTERNAL_API
0597 inline const char16_t*
0598 DecimalFormatSymbols::getCurrencyPattern() const {
0599     return currPattern;
0600 }
0601 inline const char*
0602 DecimalFormatSymbols::getNumberingSystemName() const {
0603     return nsName;
0604 }
0605 #endif /* U_HIDE_INTERNAL_API */
0606 
0607 U_NAMESPACE_END
0608 
0609 #endif /* #if !UCONFIG_NO_FORMATTING */
0610 
0611 #endif /* U_SHOW_CPLUSPLUS_API */
0612 
0613 #endif // _DCFMTSYM
0614 //eof