tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

dcfmtsym.h (21782B)


      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 
     32 #if U_SHOW_CPLUSPLUS_API
     33 
     34 #if !UCONFIG_NO_FORMATTING
     35 
     36 #include "unicode/uchar.h"
     37 #include "unicode/uobject.h"
     38 #include "unicode/locid.h"
     39 #include "unicode/numsys.h"
     40 #include "unicode/unum.h"
     41 #include "unicode/unistr.h"
     42 
     43 /**
     44 * \file
     45 * \brief C++ API: Symbols for formatting numbers.
     46 */
     47 
     48 
     49 U_NAMESPACE_BEGIN
     50 
     51 /**
     52 * This class represents the set of symbols needed by DecimalFormat
     53 * to format numbers. DecimalFormat creates for itself an instance of
     54 * DecimalFormatSymbols from its locale data.  If you need to change any
     55 * of these symbols, you can get the DecimalFormatSymbols object from
     56 * your DecimalFormat and modify it.
     57 * <P>
     58 * Here are the special characters used in the parts of the
     59 * subpattern, with notes on their usage.
     60 * <pre>
     61 * \code
     62 *        Symbol   Meaning
     63 *          0      a digit
     64 *          #      a digit, zero shows as absent
     65 *          .      placeholder for decimal separator
     66 *          ,      placeholder for grouping separator.
     67 *          ;      separates formats.
     68 *          -      default negative prefix.
     69 *          %      divide by 100 and show as percentage
     70 *          X      any other characters can be used in the prefix or suffix
     71 *          '      used to quote special characters in a prefix or suffix.
     72 * \endcode
     73 *  </pre>
     74 * [Notes]
     75 * <P>
     76 * If there is no explicit negative subpattern, - is prefixed to the
     77 * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00".
     78 * <P>
     79 * The grouping separator is commonly used for thousands, but in some
     80 * countries for ten-thousands. The interval is a constant number of
     81 * digits between the grouping characters, such as 100,000,000 or 1,0000,0000.
     82 * If you supply a pattern with multiple grouping characters, the interval
     83 * between the last one and the end of the integer is the one that is
     84 * used. So "#,##,###,####" == "######,####" == "##,####,####".
     85 */
     86 class U_I18N_API_CLASS DecimalFormatSymbols : public UObject {
     87 public:
     88    /**
     89     * Constants for specifying a number format symbol.
     90     * @stable ICU 2.0
     91     */
     92    enum ENumberFormatSymbol {
     93        /** The decimal separator */
     94        kDecimalSeparatorSymbol,
     95        /** The grouping separator */
     96        kGroupingSeparatorSymbol,
     97        /** The pattern separator */
     98        kPatternSeparatorSymbol,
     99        /** The percent sign */
    100        kPercentSymbol,
    101        /** Zero*/
    102        kZeroDigitSymbol,
    103        /** Character representing a digit in the pattern */
    104        kDigitSymbol,
    105        /** The minus sign */
    106        kMinusSignSymbol,
    107        /** The plus sign */
    108        kPlusSignSymbol,
    109        /** The currency symbol */
    110        kCurrencySymbol,
    111        /** The international currency symbol */
    112        kIntlCurrencySymbol,
    113        /** The monetary separator */
    114        kMonetarySeparatorSymbol,
    115        /** The exponential symbol */
    116        kExponentialSymbol,
    117        /** Per mill symbol - replaces kPermillSymbol */
    118        kPerMillSymbol,
    119        /** Escape padding character */
    120        kPadEscapeSymbol,
    121        /** Infinity symbol */
    122        kInfinitySymbol,
    123        /** Nan symbol */
    124        kNaNSymbol,
    125        /** Significant digit symbol
    126         * @stable ICU 3.0 */
    127        kSignificantDigitSymbol,
    128        /** The monetary grouping separator
    129         * @stable ICU 3.6
    130         */
    131        kMonetaryGroupingSeparatorSymbol,
    132        /** One
    133         * @stable ICU 4.6
    134         */
    135        kOneDigitSymbol,
    136        /** Two
    137         * @stable ICU 4.6
    138         */
    139        kTwoDigitSymbol,
    140        /** Three
    141         * @stable ICU 4.6
    142         */
    143        kThreeDigitSymbol,
    144        /** Four
    145         * @stable ICU 4.6
    146         */
    147        kFourDigitSymbol,
    148        /** Five
    149         * @stable ICU 4.6
    150         */
    151        kFiveDigitSymbol,
    152        /** Six
    153         * @stable ICU 4.6
    154         */
    155        kSixDigitSymbol,
    156        /** Seven
    157         * @stable ICU 4.6
    158         */
    159        kSevenDigitSymbol,
    160        /** Eight
    161         * @stable ICU 4.6
    162         */
    163        kEightDigitSymbol,
    164        /** Nine
    165         * @stable ICU 4.6
    166         */
    167        kNineDigitSymbol,
    168        /** Multiplication sign.
    169         * @stable ICU 54
    170         */
    171        kExponentMultiplicationSymbol,
    172 #ifndef U_HIDE_INTERNAL_API
    173        /** Approximately sign.
    174         * @internal
    175         */
    176        kApproximatelySignSymbol,
    177 #endif  /* U_HIDE_INTERNAL_API */
    178        /** count symbol constants */
    179        kFormatSymbolCount = kExponentMultiplicationSymbol + 2
    180    };
    181 
    182    /**
    183     * Create a DecimalFormatSymbols object for the given locale.
    184     *
    185     * @param locale    The locale to get symbols for.
    186     * @param status    Input/output parameter, set to success or
    187     *                  failure code upon return.
    188     * @stable ICU 2.0
    189     */
    190    U_I18N_API DecimalFormatSymbols(const Locale& locale, UErrorCode& status);
    191 
    192    /**
    193     * Creates a DecimalFormatSymbols instance for the given locale with digits and symbols
    194     * corresponding to the given NumberingSystem.
    195     *
    196     * This constructor behaves equivalently to the normal constructor called with a locale having a
    197     * "numbers=xxxx" keyword specifying the numbering system by name.
    198     *
    199     * In this constructor, the NumberingSystem argument will be used even if the locale has its own
    200     * "numbers=xxxx" keyword.
    201     *
    202     * @param locale    The locale to get symbols for.
    203     * @param ns        The numbering system.
    204     * @param status    Input/output parameter, set to success or
    205     *                  failure code upon return.
    206     * @stable ICU 60
    207     */
    208    U_I18N_API DecimalFormatSymbols(const Locale& locale, const NumberingSystem& ns, UErrorCode& status);
    209 
    210    /**
    211     * Create a DecimalFormatSymbols object for the default locale.
    212     * This constructor will not fail.  If the resource file data is
    213     * not available, it will use hard-coded last-resort data and
    214     * set status to U_USING_FALLBACK_ERROR.
    215     *
    216     * @param status    Input/output parameter, set to success or
    217     *                  failure code upon return.
    218     * @stable ICU 2.0
    219     */
    220    U_I18N_API DecimalFormatSymbols(UErrorCode& status);
    221 
    222    /**
    223     * Creates a DecimalFormatSymbols object with last-resort data.
    224     * Intended for callers who cache the symbols data and
    225     * set all symbols on the resulting object.
    226     *
    227     * The last-resort symbols are similar to those for the root data,
    228     * except that the grouping separators are empty,
    229     * the NaN symbol is U+FFFD rather than "NaN",
    230     * and the CurrencySpacing patterns are empty.
    231     *
    232     * @param status    Input/output parameter, set to success or
    233     *                  failure code upon return.
    234     * @return last-resort symbols
    235     * @stable ICU 52
    236     */
    237    U_I18N_API static DecimalFormatSymbols* createWithLastResortData(UErrorCode& status);
    238 
    239    /**
    240     * Copy constructor.
    241     * @stable ICU 2.0
    242     */
    243    U_I18N_API DecimalFormatSymbols(const DecimalFormatSymbols&);
    244 
    245    /**
    246     * Assignment operator.
    247     * @stable ICU 2.0
    248     */
    249    U_I18N_API DecimalFormatSymbols& operator=(const DecimalFormatSymbols&);
    250 
    251    /**
    252     * Destructor.
    253     * @stable ICU 2.0
    254     */
    255    U_I18N_API virtual ~DecimalFormatSymbols();
    256 
    257    /**
    258     * Return true if another object is semantically equal to this one.
    259     *
    260     * @param other    the object to be compared with.
    261     * @return         true if another object is semantically equal to this one.
    262     * @stable ICU 2.0
    263     */
    264    U_I18N_API bool operator==(const DecimalFormatSymbols& other) const;
    265 
    266    /**
    267     * Return true if another object is semantically unequal to this one.
    268     *
    269     * @param other    the object to be compared with.
    270     * @return         true if another object is semantically unequal to this one.
    271     * @stable ICU 2.0
    272     */
    273    U_I18N_API bool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); }
    274 
    275    /**
    276     * Get one of the format symbols by its enum constant.
    277     * Each symbol is stored as a string so that graphemes
    278     * (characters with modifier letters) can be used.
    279     *
    280     * @param symbol    Constant to indicate a number format symbol.
    281     * @return    the format symbols by the param 'symbol'
    282     * @stable ICU 2.0
    283     */
    284    U_I18N_API inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const;
    285 
    286    /**
    287     * Set one of the format symbols by its enum constant.
    288     * Each symbol is stored as a string so that graphemes
    289     * (characters with modifier letters) can be used.
    290     *
    291     * @param symbol    Constant to indicate a number format symbol.
    292     * @param value     value of the format symbol
    293     * @param propagateDigits If false, setting the zero digit will not automatically set 1-9.
    294     *     The default behavior is to automatically set 1-9 if zero is being set and the value
    295     *     it is being set to corresponds to a known Unicode zero digit.
    296     * @stable ICU 2.0
    297     */
    298    U_I18N_API void setSymbol(ENumberFormatSymbol symbol,
    299                              const UnicodeString& value,
    300                              const UBool propagateDigits);
    301 
    302 #ifndef U_HIDE_INTERNAL_API
    303    /**
    304     * Loads symbols for the specified currency into this instance.
    305     *
    306     * This method is internal. If you think it should be public, file a ticket.
    307     *
    308     * @internal
    309     */
    310    U_I18N_API void setCurrency(const char16_t* currency, UErrorCode& status);
    311 #endif  // U_HIDE_INTERNAL_API
    312 
    313    /**
    314     * Returns the locale for which this object was constructed.
    315     * @stable ICU 2.6
    316     */
    317    U_I18N_API inline Locale getLocale() const;
    318 
    319    /**
    320     * Returns the locale for this object. Two flavors are available:
    321     * valid and actual locale.
    322     * @stable ICU 2.8
    323     */
    324    U_I18N_API Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
    325 
    326    /**
    327      * Get pattern string for 'CurrencySpacing' that can be applied to
    328      * currency format.
    329      * This API gets the CurrencySpacing data from ResourceBundle. The pattern can
    330      * be empty if there is no data from current locale and its parent locales.
    331      *
    332      * @param type :  UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT.
    333      * @param beforeCurrency : true if the pattern is for before currency symbol.
    334      *                         false if the pattern is for after currency symbol.
    335      * @param status: Input/output parameter, set to success or
    336      *                  failure code upon return.
    337      * @return pattern string for currencyMatch, surroundingMatch or spaceInsert.
    338      *     Return empty string if there is no data for this locale and its parent
    339      *     locales.
    340      * @stable ICU 4.8
    341      */
    342    U_I18N_API const UnicodeString& getPatternForCurrencySpacing(UCurrencySpacing type,
    343                                                                 UBool beforeCurrency,
    344                                                                 UErrorCode& status) const;
    345 
    346    /**
    347      * Set pattern string for 'CurrencySpacing' that can be applied to
    348      * currency format.
    349      *
    350      * @param type : UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT.
    351      * @param beforeCurrency : true if the pattern is for before currency symbol.
    352      *                         false if the pattern is for after currency symbol.
    353      * @param pattern : pattern string to override current setting.
    354      * @stable ICU 4.8
    355      */
    356    U_I18N_API void setPatternForCurrencySpacing(UCurrencySpacing type,
    357                                                 UBool beforeCurrency,
    358                                                 const UnicodeString& pattern);
    359 
    360    /**
    361     * ICU "poor man's RTTI", returns a UClassID for the actual class.
    362     *
    363     * @stable ICU 2.2
    364     */
    365    U_I18N_API virtual UClassID getDynamicClassID() const override;
    366 
    367    /**
    368     * ICU "poor man's RTTI", returns a UClassID for this class.
    369     *
    370     * @stable ICU 2.2
    371     */
    372    U_I18N_API static UClassID getStaticClassID();
    373 
    374 private:
    375    DecimalFormatSymbols();
    376 
    377    /**
    378     * Initializes the symbols from the LocaleElements resource bundle.
    379     * Note: The organization of LocaleElements badly needs to be
    380     * cleaned up.
    381     *
    382     * @param locale               The locale to get symbols for.
    383     * @param success              Input/output parameter, set to success or
    384     *                             failure code upon return.
    385     * @param useLastResortData    determine if use last resort data
    386     * @param ns                   The NumberingSystem to use; otherwise, fall
    387     *                             back to the locale.
    388     */
    389    void initialize(const Locale& locale, UErrorCode& success,
    390                    UBool useLastResortData = false, const NumberingSystem* ns = nullptr);
    391 
    392    /**
    393     * Initialize the symbols with default values.
    394     */
    395    void initialize();
    396 
    397 public:
    398 
    399 #ifndef U_HIDE_INTERNAL_API
    400    /**
    401     * @internal For ICU use only
    402     */
    403    U_I18N_API inline UBool isCustomCurrencySymbol() const {
    404        return fIsCustomCurrencySymbol;
    405    }
    406 
    407    /**
    408     * @internal For ICU use only
    409     */
    410    U_I18N_API inline UBool isCustomIntlCurrencySymbol() const {
    411        return fIsCustomIntlCurrencySymbol;
    412    }
    413 
    414    /**
    415     * @internal For ICU use only
    416     */
    417    U_I18N_API inline UChar32 getCodePointZero() const {
    418        return fCodePointZero;
    419    }
    420 #endif  /* U_HIDE_INTERNAL_API */
    421 
    422    /**
    423     * _Internal_ function - more efficient version of getSymbol,
    424     * returning a const reference to one of the symbol strings.
    425     * The returned reference becomes invalid when the symbol is changed
    426     * or when the DecimalFormatSymbols are destroyed.
    427     * Note: moved \#ifndef U_HIDE_INTERNAL_API after this, since this is needed for inline in DecimalFormat
    428     *
    429     * This is not currently stable API, but if you think it should be stable,
    430     * post a comment on the following ticket and the ICU team will take a look:
    431     * https://unicode-org.atlassian.net/browse/ICU-13580
    432     *
    433     * @param symbol Constant to indicate a number format symbol.
    434     * @return the format symbol by the param 'symbol'
    435     * @internal
    436     */
    437    U_I18N_API inline const UnicodeString& getConstSymbol(ENumberFormatSymbol symbol) const;
    438 
    439 #ifndef U_HIDE_INTERNAL_API
    440    /**
    441     * Returns the const UnicodeString reference, like getConstSymbol,
    442     * corresponding to the digit with the given value.  This is equivalent
    443     * to accessing the symbol from getConstSymbol with the corresponding
    444     * key, such as kZeroDigitSymbol or kOneDigitSymbol.
    445     *
    446     * This is not currently stable API, but if you think it should be stable,
    447     * post a comment on the following ticket and the ICU team will take a look:
    448     * https://unicode-org.atlassian.net/browse/ICU-13580
    449     *
    450     * @param digit The digit, an integer between 0 and 9 inclusive.
    451     *              If outside the range 0 to 9, the zero digit is returned.
    452     * @return the format symbol for the given digit.
    453     * @internal This API is currently for ICU use only.
    454     */
    455    U_I18N_API inline const UnicodeString& getConstDigitSymbol(int32_t digit) const;
    456 
    457    /**
    458     * Returns that pattern stored in currency info. Internal API for use by NumberFormat API.
    459     * @internal
    460     */
    461    U_I18N_API inline const char16_t* getCurrencyPattern() const;
    462 
    463    /**
    464     * Returns the numbering system with which this DecimalFormatSymbols was initialized.
    465     * @internal
    466     */
    467    U_I18N_API inline const char* getNumberingSystemName() const;
    468 #endif  /* U_HIDE_INTERNAL_API */
    469 
    470 private:
    471    /**
    472     * Private symbol strings.
    473     * They are either loaded from a resource bundle or otherwise owned.
    474     * setSymbol() clones the symbol string.
    475     * Readonly aliases can only come from a resource bundle, so that we can always
    476     * use fastCopyFrom() with them.
    477     *
    478     * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes
    479     * from private to protected,
    480     * or when fSymbols can be set any other way that allows them to be readonly aliases
    481     * to non-resource bundle strings,
    482     * then regular UnicodeString copies must be used instead of fastCopyFrom().
    483     *
    484     */
    485    UnicodeString fSymbols[kFormatSymbolCount];
    486 
    487    /**
    488     * Non-symbol variable for getConstSymbol(). Always empty.
    489     */
    490    UnicodeString fNoSymbol;
    491 
    492    /**
    493     * Dealing with code points is faster than dealing with strings when formatting. Because of
    494     * this, we maintain a value containing the zero code point that is used whenever digitStrings
    495     * represents a sequence of ten code points in order.
    496     *
    497     * <p>If the value stored here is positive, it means that the code point stored in this value
    498     * corresponds to the digitStrings array, and codePointZero can be used instead of the
    499     * digitStrings array for the purposes of efficient formatting; if -1, then digitStrings does
    500     * *not* contain a sequence of code points, and it must be used directly.
    501     *
    502     * <p>It is assumed that codePointZero always shadows the value in digitStrings. codePointZero
    503     * should never be set directly; rather, it should be updated only when digitStrings mutates.
    504     * That is, the flow of information is digitStrings -> codePointZero, not the other way.
    505     */
    506    UChar32 fCodePointZero;
    507 
    508    Locale locale;
    509 
    510    Locale actualLocale;
    511    Locale validLocale;
    512    const char16_t* currPattern = nullptr;
    513 
    514    UnicodeString currencySpcBeforeSym[UNUM_CURRENCY_SPACING_COUNT];
    515    UnicodeString currencySpcAfterSym[UNUM_CURRENCY_SPACING_COUNT];
    516    UBool fIsCustomCurrencySymbol;
    517    UBool fIsCustomIntlCurrencySymbol;
    518    char nsName[kInternalNumSysNameCapacity+1] = {};
    519 };
    520 
    521 // -------------------------------------
    522 
    523 inline UnicodeString
    524 DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
    525    const UnicodeString *strPtr;
    526    if(symbol < kFormatSymbolCount) {
    527        strPtr = &fSymbols[symbol];
    528    } else {
    529        strPtr = &fNoSymbol;
    530    }
    531    return *strPtr;
    532 }
    533 
    534 // See comments above for this function. Not hidden with #ifdef U_HIDE_INTERNAL_API
    535 inline const UnicodeString &
    536 DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const {
    537    const UnicodeString *strPtr;
    538    if(symbol < kFormatSymbolCount) {
    539        strPtr = &fSymbols[symbol];
    540    } else {
    541        strPtr = &fNoSymbol;
    542    }
    543    return *strPtr;
    544 }
    545 
    546 #ifndef U_HIDE_INTERNAL_API
    547 inline const UnicodeString& DecimalFormatSymbols::getConstDigitSymbol(int32_t digit) const {
    548    if (digit < 0 || digit > 9) {
    549        digit = 0;
    550    }
    551    if (digit == 0) {
    552        return fSymbols[kZeroDigitSymbol];
    553    }
    554    ENumberFormatSymbol key = static_cast<ENumberFormatSymbol>(kOneDigitSymbol + digit - 1);
    555    return fSymbols[key];
    556 }
    557 #endif /* U_HIDE_INTERNAL_API */
    558 
    559 // -------------------------------------
    560 
    561 inline void
    562 DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propagateDigits = true) {
    563    if (symbol == kCurrencySymbol) {
    564        fIsCustomCurrencySymbol = true;
    565    }
    566    else if (symbol == kIntlCurrencySymbol) {
    567        fIsCustomIntlCurrencySymbol = true;
    568    }
    569    if(symbol<kFormatSymbolCount) {
    570        fSymbols[symbol]=value;
    571    }
    572 
    573    // If the zero digit is being set to a known zero digit according to Unicode,
    574    // then we automatically set the corresponding 1-9 digits
    575    // Also record updates to fCodePointZero. Be conservative if in doubt.
    576    if (symbol == kZeroDigitSymbol) {
    577        UChar32 sym = value.char32At(0);
    578        if ( propagateDigits && u_charDigitValue(sym) == 0 && value.countChar32() == 1 ) {
    579            fCodePointZero = sym;
    580            for ( int8_t i = 1 ; i<= 9 ; i++ ) {
    581                sym++;
    582                fSymbols[static_cast<int>(kOneDigitSymbol) + i - 1] = UnicodeString(sym);
    583            }
    584        } else {
    585            fCodePointZero = -1;
    586        }
    587    } else if (symbol >= kOneDigitSymbol && symbol <= kNineDigitSymbol) {
    588        fCodePointZero = -1;
    589    }
    590 }
    591 
    592 // -------------------------------------
    593 
    594 inline Locale
    595 DecimalFormatSymbols::getLocale() const {
    596    return locale;
    597 }
    598 
    599 #ifndef U_HIDE_INTERNAL_API
    600 inline const char16_t*
    601 DecimalFormatSymbols::getCurrencyPattern() const {
    602    return currPattern;
    603 }
    604 inline const char*
    605 DecimalFormatSymbols::getNumberingSystemName() const {
    606    return nsName;
    607 }
    608 #endif /* U_HIDE_INTERNAL_API */
    609 
    610 U_NAMESPACE_END
    611 
    612 #endif /* #if !UCONFIG_NO_FORMATTING */
    613 
    614 #endif /* U_SHOW_CPLUSPLUS_API */
    615 
    616 #endif // _DCFMTSYM
    617 //eof