michael@0: /* michael@0: ******************************************************************************** michael@0: * Copyright (C) 1997-2013, International Business Machines michael@0: * Corporation and others. All Rights Reserved. michael@0: ******************************************************************************** michael@0: * michael@0: * File DCFMTSYM.H michael@0: * michael@0: * Modification History: michael@0: * michael@0: * Date Name Description michael@0: * 02/19/97 aliu Converted from java. michael@0: * 03/18/97 clhuang Updated per C++ implementation. michael@0: * 03/27/97 helena Updated to pass the simple test after code review. michael@0: * 08/26/97 aliu Added currency/intl currency symbol support. michael@0: * 07/22/98 stephen Changed to match C++ style michael@0: * currencySymbol -> fCurrencySymbol michael@0: * Constants changed from CAPS to kCaps michael@0: * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes michael@0: * 09/22/00 grhoten Marked deprecation tags with a pointer to replacement michael@0: * functions. michael@0: ******************************************************************************** michael@0: */ michael@0: michael@0: #ifndef DCFMTSYM_H michael@0: #define DCFMTSYM_H michael@0: michael@0: #include "unicode/utypes.h" michael@0: #include "unicode/uchar.h" michael@0: michael@0: #if !UCONFIG_NO_FORMATTING michael@0: michael@0: #include "unicode/uobject.h" michael@0: #include "unicode/locid.h" michael@0: #include "unicode/unum.h" michael@0: michael@0: /** michael@0: * \file michael@0: * \brief C++ API: Symbols for formatting numbers. michael@0: */ michael@0: michael@0: michael@0: U_NAMESPACE_BEGIN michael@0: michael@0: /** michael@0: * This class represents the set of symbols needed by DecimalFormat michael@0: * to format numbers. DecimalFormat creates for itself an instance of michael@0: * DecimalFormatSymbols from its locale data. If you need to change any michael@0: * of these symbols, you can get the DecimalFormatSymbols object from michael@0: * your DecimalFormat and modify it. michael@0: *
michael@0: * Here are the special characters used in the parts of the michael@0: * subpattern, with notes on their usage. michael@0: *
michael@0: * \code michael@0: * Symbol Meaning michael@0: * 0 a digit michael@0: * # a digit, zero shows as absent michael@0: * . placeholder for decimal separator michael@0: * , placeholder for grouping separator. michael@0: * ; separates formats. michael@0: * - default negative prefix. michael@0: * % divide by 100 and show as percentage michael@0: * X any other characters can be used in the prefix or suffix michael@0: * ' used to quote special characters in a prefix or suffix. michael@0: * \endcode michael@0: *michael@0: * [Notes] michael@0: *
michael@0: * If there is no explicit negative subpattern, - is prefixed to the michael@0: * positive form. That is, "0.00" alone is equivalent to "0.00;-0.00". michael@0: *
michael@0: * The grouping separator is commonly used for thousands, but in some michael@0: * countries for ten-thousands. The interval is a constant number of michael@0: * digits between the grouping characters, such as 100,000,000 or 1,0000,0000. michael@0: * If you supply a pattern with multiple grouping characters, the interval michael@0: * between the last one and the end of the integer is the one that is michael@0: * used. So "#,##,###,####" == "######,####" == "##,####,####". michael@0: *
michael@0: * This class only handles localized digits where the 10 digits are
michael@0: * contiguous in Unicode, from 0 to 9. Other digits sets (such as
michael@0: * superscripts) would need a different subclass.
michael@0: */
michael@0: class U_I18N_API DecimalFormatSymbols : public UObject {
michael@0: public:
michael@0: /**
michael@0: * Constants for specifying a number format symbol.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: enum ENumberFormatSymbol {
michael@0: /** The decimal separator */
michael@0: kDecimalSeparatorSymbol,
michael@0: /** The grouping separator */
michael@0: kGroupingSeparatorSymbol,
michael@0: /** The pattern separator */
michael@0: kPatternSeparatorSymbol,
michael@0: /** The percent sign */
michael@0: kPercentSymbol,
michael@0: /** Zero*/
michael@0: kZeroDigitSymbol,
michael@0: /** Character representing a digit in the pattern */
michael@0: kDigitSymbol,
michael@0: /** The minus sign */
michael@0: kMinusSignSymbol,
michael@0: /** The plus sign */
michael@0: kPlusSignSymbol,
michael@0: /** The currency symbol */
michael@0: kCurrencySymbol,
michael@0: /** The international currency symbol */
michael@0: kIntlCurrencySymbol,
michael@0: /** The monetary separator */
michael@0: kMonetarySeparatorSymbol,
michael@0: /** The exponential symbol */
michael@0: kExponentialSymbol,
michael@0: /** Per mill symbol - replaces kPermillSymbol */
michael@0: kPerMillSymbol,
michael@0: /** Escape padding character */
michael@0: kPadEscapeSymbol,
michael@0: /** Infinity symbol */
michael@0: kInfinitySymbol,
michael@0: /** Nan symbol */
michael@0: kNaNSymbol,
michael@0: /** Significant digit symbol
michael@0: * @stable ICU 3.0 */
michael@0: kSignificantDigitSymbol,
michael@0: /** The monetary grouping separator
michael@0: * @stable ICU 3.6
michael@0: */
michael@0: kMonetaryGroupingSeparatorSymbol,
michael@0: /** One
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kOneDigitSymbol,
michael@0: /** Two
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kTwoDigitSymbol,
michael@0: /** Three
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kThreeDigitSymbol,
michael@0: /** Four
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kFourDigitSymbol,
michael@0: /** Five
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kFiveDigitSymbol,
michael@0: /** Six
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kSixDigitSymbol,
michael@0: /** Seven
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kSevenDigitSymbol,
michael@0: /** Eight
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kEightDigitSymbol,
michael@0: /** Nine
michael@0: * @stable ICU 4.6
michael@0: */
michael@0: kNineDigitSymbol,
michael@0: /** count symbol constants */
michael@0: kFormatSymbolCount
michael@0: };
michael@0:
michael@0: /**
michael@0: * Create a DecimalFormatSymbols object for the given locale.
michael@0: *
michael@0: * @param locale The locale to get symbols for.
michael@0: * @param status Input/output parameter, set to success or
michael@0: * failure code upon return.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: DecimalFormatSymbols(const Locale& locale, UErrorCode& status);
michael@0:
michael@0: /**
michael@0: * Create a DecimalFormatSymbols object for the default locale.
michael@0: * This constructor will not fail. If the resource file data is
michael@0: * not available, it will use hard-coded last-resort data and
michael@0: * set status to U_USING_FALLBACK_ERROR.
michael@0: *
michael@0: * @param status Input/output parameter, set to success or
michael@0: * failure code upon return.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: DecimalFormatSymbols(UErrorCode& status);
michael@0:
michael@0: #ifndef U_HIDE_DRAFT_API
michael@0: /**
michael@0: * Creates a DecimalFormatSymbols object with last-resort data.
michael@0: * Intended for callers who cache the symbols data and
michael@0: * set all symbols on the resulting object.
michael@0: *
michael@0: * The last-resort symbols are similar to those for the root data,
michael@0: * except that the grouping separators are empty,
michael@0: * the NaN symbol is U+FFFD rather than "NaN",
michael@0: * and the CurrencySpacing patterns are empty.
michael@0: *
michael@0: * @param status Input/output parameter, set to success or
michael@0: * failure code upon return.
michael@0: * @return last-resort symbols
michael@0: * @draft ICU 52
michael@0: */
michael@0: static DecimalFormatSymbols* createWithLastResortData(UErrorCode& status);
michael@0: #endif /* U_HIDE_DRAFT_API */
michael@0:
michael@0: /**
michael@0: * Copy constructor.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: DecimalFormatSymbols(const DecimalFormatSymbols&);
michael@0:
michael@0: /**
michael@0: * Assignment operator.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: DecimalFormatSymbols& operator=(const DecimalFormatSymbols&);
michael@0:
michael@0: /**
michael@0: * Destructor.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: virtual ~DecimalFormatSymbols();
michael@0:
michael@0: /**
michael@0: * Return true if another object is semantically equal to this one.
michael@0: *
michael@0: * @param other the object to be compared with.
michael@0: * @return true if another object is semantically equal to this one.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: UBool operator==(const DecimalFormatSymbols& other) const;
michael@0:
michael@0: /**
michael@0: * Return true if another object is semantically unequal to this one.
michael@0: *
michael@0: * @param other the object to be compared with.
michael@0: * @return true if another object is semantically unequal to this one.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: UBool operator!=(const DecimalFormatSymbols& other) const { return !operator==(other); }
michael@0:
michael@0: /**
michael@0: * Get one of the format symbols by its enum constant.
michael@0: * Each symbol is stored as a string so that graphemes
michael@0: * (characters with modifier letters) can be used.
michael@0: *
michael@0: * @param symbol Constant to indicate a number format symbol.
michael@0: * @return the format symbols by the param 'symbol'
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: inline UnicodeString getSymbol(ENumberFormatSymbol symbol) const;
michael@0:
michael@0: /**
michael@0: * Set one of the format symbols by its enum constant.
michael@0: * Each symbol is stored as a string so that graphemes
michael@0: * (characters with modifier letters) can be used.
michael@0: *
michael@0: * @param symbol Constant to indicate a number format symbol.
michael@0: * @param value value of the format symbol
michael@0: * @param propogateDigits If false, setting the zero digit will not automatically set 1-9.
michael@0: * The default behavior is to automatically set 1-9 if zero is being set and the value
michael@0: * it is being set to corresponds to a known Unicode zero digit.
michael@0: * @stable ICU 2.0
michael@0: */
michael@0: void setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits);
michael@0:
michael@0: /**
michael@0: * Returns the locale for which this object was constructed.
michael@0: * @stable ICU 2.6
michael@0: */
michael@0: inline Locale getLocale() const;
michael@0:
michael@0: /**
michael@0: * Returns the locale for this object. Two flavors are available:
michael@0: * valid and actual locale.
michael@0: * @stable ICU 2.8
michael@0: */
michael@0: Locale getLocale(ULocDataLocaleType type, UErrorCode& status) const;
michael@0:
michael@0: /**
michael@0: * Get pattern string for 'CurrencySpacing' that can be applied to
michael@0: * currency format.
michael@0: * This API gets the CurrencySpacing data from ResourceBundle. The pattern can
michael@0: * be empty if there is no data from current locale and its parent locales.
michael@0: *
michael@0: * @param type : UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT.
michael@0: * @param beforeCurrency : true if the pattern is for before currency symbol.
michael@0: * false if the pattern is for after currency symbol.
michael@0: * @param status: Input/output parameter, set to success or
michael@0: * failure code upon return.
michael@0: * @return pattern string for currencyMatch, surroundingMatch or spaceInsert.
michael@0: * Return empty string if there is no data for this locale and its parent
michael@0: * locales.
michael@0: * @stable ICU 4.8
michael@0: */
michael@0: const UnicodeString& getPatternForCurrencySpacing(UCurrencySpacing type,
michael@0: UBool beforeCurrency,
michael@0: UErrorCode& status) const;
michael@0: /**
michael@0: * Set pattern string for 'CurrencySpacing' that can be applied to
michael@0: * currency format.
michael@0: *
michael@0: * @param type : UNUM_CURRENCY_MATCH, UNUM_CURRENCY_SURROUNDING_MATCH or UNUM_CURRENCY_INSERT.
michael@0: * @param beforeCurrency : true if the pattern is for before currency symbol.
michael@0: * false if the pattern is for after currency symbol.
michael@0: * @param pattern : pattern string to override current setting.
michael@0: * @stable ICU 4.8
michael@0: */
michael@0: void setPatternForCurrencySpacing(UCurrencySpacing type,
michael@0: UBool beforeCurrency,
michael@0: const UnicodeString& pattern);
michael@0:
michael@0: /**
michael@0: * ICU "poor man's RTTI", returns a UClassID for the actual class.
michael@0: *
michael@0: * @stable ICU 2.2
michael@0: */
michael@0: virtual UClassID getDynamicClassID() const;
michael@0:
michael@0: /**
michael@0: * ICU "poor man's RTTI", returns a UClassID for this class.
michael@0: *
michael@0: * @stable ICU 2.2
michael@0: */
michael@0: static UClassID U_EXPORT2 getStaticClassID();
michael@0:
michael@0: private:
michael@0: DecimalFormatSymbols();
michael@0:
michael@0: /**
michael@0: * Initializes the symbols from the LocaleElements resource bundle.
michael@0: * Note: The organization of LocaleElements badly needs to be
michael@0: * cleaned up.
michael@0: *
michael@0: * @param locale The locale to get symbols for.
michael@0: * @param success Input/output parameter, set to success or
michael@0: * failure code upon return.
michael@0: * @param useLastResortData determine if use last resort data
michael@0: */
michael@0: void initialize(const Locale& locale, UErrorCode& success, UBool useLastResortData = FALSE);
michael@0:
michael@0: /**
michael@0: * Initialize the symbols with default values.
michael@0: */
michael@0: void initialize();
michael@0:
michael@0: void setCurrencyForSymbols();
michael@0:
michael@0: public:
michael@0: #ifndef U_HIDE_INTERNAL_API
michael@0: /**
michael@0: * _Internal_ function - more efficient version of getSymbol,
michael@0: * returning a const reference to one of the symbol strings.
michael@0: * The returned reference becomes invalid when the symbol is changed
michael@0: * or when the DecimalFormatSymbols are destroyed.
michael@0: * ### TODO markus 2002oct11: Consider proposing getConstSymbol() to be really public.
michael@0: *
michael@0: * @param symbol Constant to indicate a number format symbol.
michael@0: * @return the format symbol by the param 'symbol'
michael@0: * @internal
michael@0: */
michael@0: inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const;
michael@0:
michael@0: /**
michael@0: * Returns that pattern stored in currecy info. Internal API for use by NumberFormat API.
michael@0: * @internal
michael@0: */
michael@0: inline const UChar* getCurrencyPattern(void) const;
michael@0: #endif /* U_HIDE_INTERNAL_API */
michael@0:
michael@0: private:
michael@0: /**
michael@0: * Private symbol strings.
michael@0: * They are either loaded from a resource bundle or otherwise owned.
michael@0: * setSymbol() clones the symbol string.
michael@0: * Readonly aliases can only come from a resource bundle, so that we can always
michael@0: * use fastCopyFrom() with them.
michael@0: *
michael@0: * If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes
michael@0: * from private to protected,
michael@0: * or when fSymbols can be set any other way that allows them to be readonly aliases
michael@0: * to non-resource bundle strings,
michael@0: * then regular UnicodeString copies must be used instead of fastCopyFrom().
michael@0: *
michael@0: * @internal
michael@0: */
michael@0: UnicodeString fSymbols[kFormatSymbolCount];
michael@0:
michael@0: /**
michael@0: * Non-symbol variable for getConstSymbol(). Always empty.
michael@0: * @internal
michael@0: */
michael@0: UnicodeString fNoSymbol;
michael@0:
michael@0: Locale locale;
michael@0:
michael@0: char actualLocale[ULOC_FULLNAME_CAPACITY];
michael@0: char validLocale[ULOC_FULLNAME_CAPACITY];
michael@0: const UChar* currPattern;
michael@0:
michael@0: UnicodeString currencySpcBeforeSym[UNUM_CURRENCY_SPACING_COUNT];
michael@0: UnicodeString currencySpcAfterSym[UNUM_CURRENCY_SPACING_COUNT];
michael@0: };
michael@0:
michael@0: // -------------------------------------
michael@0:
michael@0: inline UnicodeString
michael@0: DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
michael@0: const UnicodeString *strPtr;
michael@0: if(symbol < kFormatSymbolCount) {
michael@0: strPtr = &fSymbols[symbol];
michael@0: } else {
michael@0: strPtr = &fNoSymbol;
michael@0: }
michael@0: return *strPtr;
michael@0: }
michael@0:
michael@0: #ifndef U_HIDE_INTERNAL_API
michael@0:
michael@0: inline const UnicodeString &
michael@0: DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const {
michael@0: const UnicodeString *strPtr;
michael@0: if(symbol < kFormatSymbolCount) {
michael@0: strPtr = &fSymbols[symbol];
michael@0: } else {
michael@0: strPtr = &fNoSymbol;
michael@0: }
michael@0: return *strPtr;
michael@0: }
michael@0:
michael@0: #endif /* U_HIDE_INTERNAL_API */
michael@0:
michael@0:
michael@0: // -------------------------------------
michael@0:
michael@0: inline void
michael@0: DecimalFormatSymbols::setSymbol(ENumberFormatSymbol symbol, const UnicodeString &value, const UBool propogateDigits = TRUE) {
michael@0: if(symbol