]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/unicode/decimfmt.h
ICU-491.11.1.tar.gz
[apple/icu.git] / icuSources / i18n / unicode / decimfmt.h
index 296906fb7d732b0bb4f2467914b3a86f23833622..2d54306f0cf3ef9a483818b2afc668897fa74a12 100644 (file)
@@ -1,6 +1,6 @@
 /*
 ********************************************************************************
-*   Copyright (C) 1997-2006, International Business Machines
+*   Copyright (C) 1997-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 ********************************************************************************
 *
 *    07/20/98    stephen        Changed documentation
 ********************************************************************************
 */
+
 #ifndef DECIMFMT_H
 #define DECIMFMT_H
+
 #include "unicode/utypes.h"
 /**
- * \file 
+ * \file
  * \brief C++ API: Formats decimal numbers.
  */
+
 #if !UCONFIG_NO_FORMATTING
 
 #include "unicode/dcfmtsym.h"
 #include "unicode/numfmt.h"
 #include "unicode/locid.h"
+#include "unicode/fpositer.h"
+#include "unicode/stringpiece.h"
+#include "unicode/curramt.h"
 
 U_NAMESPACE_BEGIN
 
 class DigitList;
 class ChoiceFormat;
+class CurrencyPluralInfo;
+class Hashtable;
+class UnicodeSet;
+class FieldPositionHandler;
 
 /**
  * DecimalFormat is a concrete subclass of NumberFormat that formats decimal
@@ -47,8 +54,8 @@ class ChoiceFormat;
  * and format numbers in any locale, including support for Western, Arabic, or
  * Indic digits.  It also supports different flavors of numbers, including
  * integers ("123"), fixed-point numbers ("123.4"), scientific notation
- * ("1.23E4"), percentages ("12%"), and currency amounts ("$123").  All of these
- * flavors can be easily localized.
+ * ("1.23E4"), percentages ("12%"), and currency amounts ("$123", "USD123",
+ * "123 US dollars").  All of these flavors can be easily localized.
  *
  * <p>To obtain a NumberFormat for a specific locale (including the default
  * locale) call one of NumberFormat's factory methods such as
@@ -62,11 +69,11 @@ class ChoiceFormat;
  *     // Normally we would have a GUI with a menu for this
  *     int32_t locCount;
  *     const Locale* locales = NumberFormat::getAvailableLocales(locCount);
- * 
+ *
  *     double myNumber = -1234.56;
  *     UErrorCode success = U_ZERO_ERROR;
  *     NumberFormat* form;
- * 
+ *
  *     // Print out a number with the localized number, currency and percent
  *     // format for each locale.
  *     UnicodeString countryName;
@@ -95,11 +102,32 @@ class ChoiceFormat;
  *                 cout << locales[i].getDisplayName(displayName) << ": " << pattern;
  *                 cout << "  ->  " << form->format(myNumber,str) << endl;
  *                 form->parse(form->format(myNumber,str), fmtable, success);
- *                 delete form;  
+ *                 delete form;
  *             }
  *         }
  *     }
  * \endcode
+ * <P>
+ * Another example use createInstance(style)
+ * <P>
+ * <pre>
+ * <strong>// Print out a number using the localized number, currency,
+ * // percent, scientific, integer, iso currency, and plural currency
+ * // format for each locale</strong>
+ * Locale* locale = new Locale("en", "US");
+ * double myNumber = 1234.56;
+ * UErrorCode success = U_ZERO_ERROR;
+ * UnicodeString str;
+ * Formattable fmtable;
+ * for (int j=NumberFormat::kNumberStyle;
+ *      j<=NumberFormat::kPluralCurrencyStyle;
+ *      ++j) {
+ *     NumberFormat* format = NumberFormat::createInstance(locale, j, success);
+ *     str.remove();
+ *     cout << "format result " << form->format(myNumber, str) << endl;
+ *     format->parse(form->format(myNumber, str), fmtable, success);
+ * }</pre>
+ *
  *
  * <p><strong>Patterns</strong>
  *
@@ -110,7 +138,7 @@ class ChoiceFormat;
  * digits.  The symbols are stored in a DecimalFormatSymbols
  * object.  When using the NumberFormat factory methods, the
  * pattern and symbols are read from ICU's locale data.
- * 
+ *
  * <p><strong>Special Pattern Characters</strong>
  *
  * <p>Many characters in a pattern are taken literally; they are matched during
@@ -208,6 +236,8 @@ class ChoiceFormat;
  *     <td>No
  *     <td>Currency sign, replaced by currency symbol.  If
  *         doubled, replaced by international currency symbol.
+ *         If tripled, replaced by currency plural names, for example,
+ *         "US dollar" or "US dollars" for America.
  *         If present in a pattern, the monetary decimal separator
  *         is used instead of the decimal separator.
  *   <tr valign=top bgcolor="#eeeeff">
@@ -288,7 +318,7 @@ class ChoiceFormat;
  * </pre>
  * The first subpattern is for positive numbers. The second (optional)
  * subpattern is for negative numbers.
- * 
+ *
  * <p>Not indicated in the BNF syntax above:
  *
  * <ul><li>The grouping separator ',' can occur inside the integer and
@@ -303,7 +333,7 @@ class ChoiceFormat;
  *     locales they differ. For example, the pattern
  *     &quot;#,##,###&quot; formats the number 123456789 as
  *     &quot;12,34,56,789&quot;.</li>
- * 
+ *
  * <li>The pad specifier <code>padSpec</code> may appear before the prefix,
  * after the prefix, before the suffix, after the suffix, or not at all.
  *
@@ -322,6 +352,12 @@ class ChoiceFormat;
  *
  * <p>During parsing, grouping separators are ignored.
  *
+ * <p>For currency parsing, the formatter is able to parse every currency
+ * style formats no matter which style the formatter is constructed with.
+ * For example, a formatter instance gotten from
+ * NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can parse
+ * formats such as "USD1.00" and "3.00 US dollars".
+ *
  * <p>If parse(UnicodeString&,Formattable&,ParsePosition&)
  * fails to parse a string, it leaves the parse position unchanged.
  * The convenience method parse(UnicodeString&,Formattable&,UErrorCode&)
@@ -346,10 +382,10 @@ class ChoiceFormat;
  * is set to 5.
  *
  * <li>If the number of actual fraction digits exceeds the <em>maximum
- * fraction digits</em>, then half-even rounding it performed to the
+ * fraction digits</em>, then rounding is performed to the
  * maximum fraction digits.  For example, 0.125 is formatted as "0.12"
  * if the maximum fraction digits is 2.  This behavior can be changed
- * by specifying a rounding increment and a rounding mode.
+ * by specifying a rounding increment and/or a rounding mode.
  *
  * <li>If the number of actual fraction digits is less than the
  * <em>minimum fraction digits</em>, then trailing zeros are added.
@@ -574,13 +610,17 @@ class ChoiceFormat;
  * increment in the pattern itself.  "#,#50" specifies a rounding increment of
  * 50.  "#,##0.05" specifies a rounding increment of 0.05.
  *
+ * <p>In the absense of an explicit rounding increment numbers are
+ * rounded to their formatted width.
+ *
  * <ul>
  * <li>Rounding only affects the string produced by formatting.  It does
  * not affect parsing or change any numerical values.
  *
  * <li>A <em>rounding mode</em> determines how values are rounded; see
- * DecimalFormat::ERoundingMode.  Rounding increments specified in
- * patterns use the default mode, DecimalFormat::kRoundHalfEven.
+ * DecimalFormat::ERoundingMode.  The default rounding mode is
+ * DecimalFormat::kRoundHalfEven.  The rounding mode can only be set
+ * through the API; it can not be set with a pattern.
  *
  * <li>Some locales use rounding in their currency formats to reflect the
  * smallest currency denomination.
@@ -615,9 +655,13 @@ public:
                              towards the nearest even integer if equidistant */
         kRoundHalfDown, /**< Round towards the nearest integer, or
                              towards zero if equidistant */
-        kRoundHalfUp    /**< Round towards the nearest integer, or
+        kRoundHalfUp,   /**< Round towards the nearest integer, or
                              away from zero if equidistant */
-        // We don't support ROUND_UNNECESSARY
+        /**
+          *  Return U_FORMAT_INEXACT_ERROR if number does not format exactly. 
+          *  @stable ICU 4.8 
+          */
+        kRoundUnnecessary
     };
 
     /**
@@ -685,6 +729,25 @@ public:
                     DecimalFormatSymbols* symbolsToAdopt,
                     UErrorCode& status);
 
+#ifndef U_HIDE_INTERNAL_API
+    /**
+     * This API is for ICU use only.
+     * Create a DecimalFormat from the given pattern, symbols, and style.
+     *
+     * @param pattern           a non-localized pattern string
+     * @param symbolsToAdopt    the set of symbols to be used.  The caller should not
+     *                          delete this object after making this call.
+     * @param style             style of decimal format
+     * @param status            Output param set to success/failure code. If the
+     *                          pattern is invalid this will be set to a failure code.
+     * @internal ICU 4.2
+     */
+    DecimalFormat(  const UnicodeString& pattern,
+                    DecimalFormatSymbols* symbolsToAdopt,
+                    UNumberFormatStyle style,
+                    UErrorCode& status);
+#endif  /* U_HIDE_INTERNAL_API */
+
     /**
      * Create a DecimalFormat from the given pattern and symbols.
      * Use this constructor when you need to completely customize the
@@ -699,7 +762,7 @@ public:
      * @param pattern           a non-localized pattern string
      * @param symbolsToAdopt    the set of symbols to be used.  The caller should not
      *                          delete this object after making this call.
-     * @param parseError        Output param to receive errors occured during parsing 
+     * @param parseError        Output param to receive errors occured during parsing
      * @param status            Output param set to success/failure code. If the
      *                          pattern is invalid this will be set to a failure code.
      * @stable ICU 2.0
@@ -731,7 +794,7 @@ public:
 
     /**
      * Copy constructor.
-     * 
+     *
      * @param source    the DecimalFormat object to be copied from.
      * @stable ICU 2.0
      */
@@ -770,6 +833,9 @@ public:
      */
     virtual UBool operator==(const Format& other) const;
 
+
+    using NumberFormat::format;
+
     /**
      * Format a double or long number using base-10 representation.
      *
@@ -780,10 +846,29 @@ public:
      *                  On output: the offsets of the alignment field.
      * @return          Reference to 'appendTo' parameter.
      * @stable ICU 2.0
-    */
+     */
     virtual UnicodeString& format(double number,
                                   UnicodeString& appendTo,
                                   FieldPosition& pos) const;
+
+    /**
+     * Format a double or long number using base-10 representation.
+     *
+     * @param number    The value to be formatted.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param posIter   On return, can be used to iterate over positions
+     *                  of fields generated by this format call.
+     *                  Can be NULL.
+     * @param status    Output param filled with success/failure status.
+     * @return          Reference to 'appendTo' parameter.
+     * @stable 4.4
+     */
+    virtual UnicodeString& format(double number,
+                                  UnicodeString& appendTo,
+                                  FieldPositionIterator* posIter,
+                                  UErrorCode& status) const;
+
     /**
      * Format a long number using base-10 representation.
      *
@@ -798,6 +883,25 @@ public:
     virtual UnicodeString& format(int32_t number,
                                   UnicodeString& appendTo,
                                   FieldPosition& pos) const;
+
+    /**
+     * Format a long number using base-10 representation.
+     *
+     * @param number    The value to be formatted.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param posIter   On return, can be used to iterate over positions
+     *                  of fields generated by this format call.
+     *                  Can be NULL.
+     * @param status    Output param filled with success/failure status.
+     * @return          Reference to 'appendTo' parameter.
+     * @stable 4.4
+     */
+    virtual UnicodeString& format(int32_t number,
+                                  UnicodeString& appendTo,
+                                  FieldPositionIterator* posIter,
+                                  UErrorCode& status) const;
+
     /**
      * Format an int64 number using base-10 representation.
      *
@@ -813,6 +917,87 @@ public:
                                   UnicodeString& appendTo,
                                   FieldPosition& pos) const;
 
+    /**
+     * Format an int64 number using base-10 representation.
+     *
+     * @param number    The value to be formatted.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param posIter   On return, can be used to iterate over positions
+     *                  of fields generated by this format call.
+     *                  Can be NULL.
+     * @param status    Output param filled with success/failure status.
+     * @return          Reference to 'appendTo' parameter.
+     * @stable 4.4
+     */
+    virtual UnicodeString& format(int64_t number,
+                                  UnicodeString& appendTo,
+                                  FieldPositionIterator* posIter,
+                                  UErrorCode& status) const;
+
+    /**
+     * Format a decimal number.
+     * The syntax of the unformatted number is a "numeric string"
+     * as defined in the Decimal Arithmetic Specification, available at
+     * http://speleotrove.com/decimal
+     *
+     * @param number    The unformatted number, as a string.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param posIter   On return, can be used to iterate over positions
+     *                  of fields generated by this format call.
+     *                  Can be NULL.
+     * @param status    Output param filled with success/failure status.
+     * @return          Reference to 'appendTo' parameter.
+     * @stable 4.4
+     */
+    virtual UnicodeString& format(const StringPiece &number,
+                                  UnicodeString& appendTo,
+                                  FieldPositionIterator* posIter,
+                                  UErrorCode& status) const;
+
+
+    /**
+     * Format a decimal number. 
+     * The number is a DigitList wrapper onto a floating point decimal number.
+     * The default implementation in NumberFormat converts the decimal number
+     * to a double and formats that.
+     *
+     * @param number    The number, a DigitList format Decimal Floating Point.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param posIter   On return, can be used to iterate over positions
+     *                  of fields generated by this format call.
+     * @param status    Output param filled with success/failure status.
+     * @return          Reference to 'appendTo' parameter.
+     * @internal
+     */
+    virtual UnicodeString& format(const DigitList &number,
+                                  UnicodeString& appendTo,
+                                  FieldPositionIterator* posIter,
+                                  UErrorCode& status) const;
+
+    /**
+     * Format a decimal number. 
+     * The number is a DigitList wrapper onto a floating point decimal number.
+     * The default implementation in NumberFormat converts the decimal number
+     * to a double and formats that.  
+     *
+     * @param number    The number, a DigitList format Decimal Floating Point.
+     * @param appendTo  Output parameter to receive result.
+     *                  Result is appended to existing contents.
+     * @param pos       On input: an alignment field, if desired.
+     *                  On output: the offsets of the alignment field.
+     * @param status    Output param filled with success/failure status.
+     * @return          Reference to 'appendTo' parameter.
+     * @internal
+     */
+    virtual UnicodeString& format(const DigitList &number,
+                                  UnicodeString& appendTo,
+                                  FieldPosition& pos,
+                                  UErrorCode& status) const;
+
+
     /**
      * Format a Formattable using base-10 representation.
      *
@@ -909,7 +1094,7 @@ public:
                        ParsePosition& parsePosition) const;
 
     // Declare here again to get rid of function hiding problems.
-    /** 
+    /**
      * Parse the given string using this object's choices.
      *
      * @param text           The text to be parsed.
@@ -917,10 +1102,11 @@ public:
      * @param status    Output parameter filled in with success or failure status.
      * @stable ICU 2.0
      */
-    virtual void parse(const UnicodeString& text, 
-                       Formattable& result, 
+    virtual void parse(const UnicodeString& text,
+                       Formattable& result,
                        UErrorCode& status) const;
 
+/* Cannot use #ifndef U_HIDE_DRAFT_API for the following draft method since it is virtual */
     /**
      * Parses text from the given string as a currency amount.  Unlike
      * the parse() method, this method will attempt to parse a generic
@@ -931,18 +1117,17 @@ public:
      * (U+00A4) in its prefix or suffix.
      *
      * @param text the string to parse
-     * @param result output parameter to receive result. This will have
-     * its currency set to the parsed ISO currency code.
-     * @param pos input-output position; on input, the position within
-     * text to match; must have 0 <= pos.getIndex() < text.length();
-     * on output, the position after the last matched character. If
-     * the parse fails, the position in unchanged upon output.
-     * @return a reference to result
-     * @internal
+     * @param pos  input-output position; on input, the position within text
+     *             to match; must have 0 <= pos.getIndex() < text.length();
+     *             on output, the position after the last matched character.
+     *             If the parse fails, the position in unchanged upon output.
+     * @return     if parse succeeds, a pointer to a newly-created CurrencyAmount
+     *             object (owned by the caller) containing information about
+     *             the parsed currency; if parse fails, this is NULL.
+     * @draft ICU 49
      */
-    virtual Formattable& parseCurrency(const UnicodeString& text,
-                                       Formattable& result,
-                                       ParsePosition& pos) const;
+    virtual CurrencyAmount* parseCurrency(const UnicodeString& text,
+                                          ParsePosition& pos) const;
 
     /**
      * Returns the decimal format symbols, which is generally not changed
@@ -970,6 +1155,31 @@ public:
     virtual void setDecimalFormatSymbols(const DecimalFormatSymbols& symbols);
 
 
+    /**
+     * Returns the currency plural format information,
+     * which is generally not changed by the programmer or user.
+     * @return desired CurrencyPluralInfo
+     * @stable ICU 4.2
+     */
+    virtual const CurrencyPluralInfo* getCurrencyPluralInfo(void) const;
+
+    /**
+     * Sets the currency plural format information,
+     * which is generally not changed by the programmer or user.
+     * @param toAdopt CurrencyPluralInfo to be adopted.
+     * @stable ICU 4.2
+     */
+    virtual void adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt);
+
+    /**
+     * Sets the currency plural format information,
+     * which is generally not changed by the programmer or user.
+     * @param info Currency Plural Info.
+     * @stable ICU 4.2
+     */
+    virtual void setCurrencyPluralInfo(const CurrencyPluralInfo& info);
+
+
     /**
      * Get the positive prefix.
      *
@@ -1072,8 +1282,8 @@ public:
 
     /**
      * Get the rounding increment.
-     * @return A positive rounding increment, or 0.0 if rounding
-     * is not in effect.
+     * @return A positive rounding increment, or 0.0 if rounding
+     * increment is not in effect.
      * @see #setRoundingIncrement
      * @see #getRoundingMode
      * @see #setRoundingMode
@@ -1082,9 +1292,9 @@ public:
     virtual double getRoundingIncrement(void) const;
 
     /**
-     * Set the rounding increment.  This method also controls whether
-     * rounding is enabled.
-     * @param newValue A positive rounding increment, or 0.0 to disable rounding.
+     * Set the rounding increment.  In the absence of a rounding increment,
+     *    numbers will be rounded to the number of digits displayed.
+     * @param newValue A positive rounding increment.
      * Negative increments are equivalent to 0.0.
      * @see #getRoundingIncrement
      * @see #getRoundingMode
@@ -1104,8 +1314,7 @@ public:
     virtual ERoundingMode getRoundingMode(void) const;
 
     /**
-     * Set the rounding mode.  This has no effect unless the rounding
-     * increment is greater than zero.
+     * Set the rounding mode.  
      * @param roundingMode A rounding mode
      * @see #setRoundingIncrement
      * @see #getRoundingIncrement
@@ -1185,10 +1394,7 @@ public:
      * @see #setPadCharacter
      * @see #getPadCharacterString
      * @see #setPadPosition
-     * @see #kPadBeforePrefix
-     * @see #kPadAfterPrefix
-     * @see #kPadBeforeSuffix
-     * @see #kPadAfterSuffix
+     * @see #EPadPosition
      * @stable ICU 2.0
      */
     virtual EPadPosition getPadPosition(void) const;
@@ -1206,10 +1412,7 @@ public:
      * @see #setPadCharacter
      * @see #getPadCharacterString
      * @see #getPadPosition
-     * @see #kPadBeforePrefix
-     * @see #kPadAfterPrefix
-     * @see #kPadBeforeSuffix
-     * @see #kPadAfterSuffix
+     * @see #EPadPosition
      * @stable ICU 2.0
      */
     virtual void setPadPosition(EPadPosition padPos);
@@ -1400,7 +1603,7 @@ public:
      * @stable ICU 2.0
      */
     virtual UnicodeString& toLocalizedPattern(UnicodeString& result) const;
+
     /**
      * Apply the given pattern to this Format object.  A pattern is a
      * short-hand specification for the various formatting properties.
@@ -1423,7 +1626,7 @@ public:
      * these are presumed to be set in the positive pattern.
      *
      * @param pattern    The pattern to be applied.
-     * @param parseError Struct to recieve information on position 
+     * @param parseError Struct to recieve information on position
      *                   of error if an error is encountered
      * @param status     Output param set to success/failure code on
      *                   exit. If the pattern is invalid, this will be
@@ -1440,7 +1643,7 @@ public:
      *                  exit. If the pattern is invalid, this will be
      *                  set to a failure result.
      * @stable ICU 2.0
-     */  
+     */
     virtual void applyPattern(const UnicodeString& pattern,
                              UErrorCode& status);
 
@@ -1467,7 +1670,7 @@ public:
      * these are presumed to be set in the positive pattern.
      *
      * @param pattern   The localized pattern to be applied.
-     * @param parseError Struct to recieve information on position 
+     * @param parseError Struct to recieve information on position
      *                   of error if an error is encountered
      * @param status    Output param set to success/failure code on
      *                  exit. If the pattern is invalid, this will be
@@ -1495,7 +1698,7 @@ public:
      * Sets the maximum number of digits allowed in the integer portion of a
      * number. This override limits the integer digit count to 309.
      *
-     * @param newValue    the new value of the maximum number of digits 
+     * @param newValue    the new value of the maximum number of digits
      *                      allowed in the integer portion of a number.
      * @see NumberFormat#setMaximumIntegerDigits
      * @stable ICU 2.0
@@ -1505,8 +1708,8 @@ public:
     /**
      * Sets the minimum number of digits allowed in the integer portion of a
      * number. This override limits the integer digit count to 309.
-     * 
-     * @param newValue    the new value of the minimum number of digits 
+     *
+     * @param newValue    the new value of the minimum number of digits
      *                      allowed in the integer portion of a number.
      * @see NumberFormat#setMinimumIntegerDigits
      * @stable ICU 2.0
@@ -1517,7 +1720,7 @@ public:
      * Sets the maximum number of digits allowed in the fraction portion of a
      * number. This override limits the fraction digit count to 340.
      *
-     * @param newValue    the new value of the maximum number of digits 
+     * @param newValue    the new value of the maximum number of digits
      *                    allowed in the fraction portion of a number.
      * @see NumberFormat#setMaximumFractionDigits
      * @stable ICU 2.0
@@ -1528,7 +1731,7 @@ public:
      * Sets the minimum number of digits allowed in the fraction portion of a
      * number. This override limits the fraction digit count to 340.
      *
-     * @param newValue    the new value of the minimum number of digits 
+     * @param newValue    the new value of the minimum number of digits
      *                    allowed in the fraction portion of a number.
      * @see NumberFormat#setMinimumFractionDigits
      * @stable ICU 2.0
@@ -1559,7 +1762,7 @@ public:
      * to one.  If the maximum significant digits count is less than
      * <code>min</code>, then it is set to <code>min</code>. This
      * value has no effect unless areSignificantDigits() returns true.
-     * @param min the fewest significant digits to be shown 
+     * @param min the fewest significant digits to be shown
      * @stable ICU 3.0
      */
     void setMinimumSignificantDigits(int32_t min);
@@ -1571,7 +1774,7 @@ public:
      * than <code>max</code>, then it is set to <code>max</code>.
      * This value has no effect unless areSignificantDigits() returns
      * true.
-     * @param max the most significant digits to be shown 
+     * @param max the most significant digits to be shown
      * @stable ICU 3.0
      */
     void setMaximumSignificantDigits(int32_t max);
@@ -1651,9 +1854,16 @@ public:
     virtual UClassID getDynamicClassID(void) const;
 
 private:
+
     DecimalFormat(); // default constructor not implemented
 
-    int32_t precision(UBool isIntegral) const;
+    int32_t precision() const;
+
+    /**
+     *   Initialize all fields of a new DecimalFormatter.
+     *      Common code for use by constructors.
+     */
+    void init();
 
     /**
      * Do real work of constructing a new DecimalFormat.
@@ -1678,7 +1888,7 @@ private:
      * Does the real work of applying a pattern.
      * @param pattern    The pattern to be applied.
      * @param localized  If true, the pattern is localized; else false.
-     * @param parseError Struct to recieve information on position 
+     * @param parseError Struct to recieve information on position
      *                   of error if an error is encountered
      * @param status     Output param set to success/failure code on
      *                   exit. If the pattern is invalid, this will be
@@ -1688,61 +1898,122 @@ private:
                             UBool localized,
                             UParseError& parseError,
                             UErrorCode& status);
+
+    /*
+     * similar to applyPattern, but without re-gen affix for currency
+     */
+    void applyPatternInternally(const UnicodeString& pluralCount,
+                                const UnicodeString& pattern,
+                                UBool localized,
+                                UParseError& parseError,
+                                UErrorCode& status);
+
+    /*
+     * only apply pattern without expand affixes
+     */
+    void applyPatternWithoutExpandAffix(const UnicodeString& pattern,
+                                        UBool localized,
+                                        UParseError& parseError,
+                                        UErrorCode& status);
+
+
+    /*
+     * expand affixes (after apply patter) and re-compute fFormatWidth
+     */
+    void expandAffixAdjustWidth(const UnicodeString* pluralCount);
+
+
     /**
      * Do the work of formatting a number, either a double or a long.
      *
      * @param appendTo       Output parameter to receive result.
      *                       Result is appended to existing contents.
-     * @param fieldPosition  On input: an alignment field, if desired.
-     *                       On output: the offsets of the alignment field.
+     * @param handler        Records information about field positions.
      * @param digits         the digits to be formatted.
      * @param isInteger      if TRUE format the digits as Integer.
      * @return               Reference to 'appendTo' parameter.
      */
     UnicodeString& subformat(UnicodeString& appendTo,
-                             FieldPosition& fieldPosition,
-                             DigitList& digits,
-                             UBool         isInteger) const;
+                             FieldPositionHandler& handler,
+                             DigitList&     digits,
+                             UBool          isInteger) const;
+
 
     void parse(const UnicodeString& text,
                Formattable& result,
                ParsePosition& pos,
-               UBool parseCurrency) const;
+               UChar* currency) const;
 
     enum {
         fgStatusInfinite,
         fgStatusLength      // Leave last in list.
     } StatusFlags;
 
-    UBool subparse(const UnicodeString& text, ParsePosition& parsePosition,
+    UBool subparse(const UnicodeString& text,
+                   const UnicodeString* negPrefix,
+                   const UnicodeString* negSuffix,
+                   const UnicodeString* posPrefix,
+                   const UnicodeString* posSuffix,
+                   UBool currencyParsing,
+                   int8_t type,
+                   ParsePosition& parsePosition,
                    DigitList& digits, UBool* status,
                    UChar* currency) const;
 
+    // Mixed style parsing for currency.
+    // It parses against the current currency pattern
+    // using complex affix comparison
+    // parses against the currency plural patterns using complex affix comparison,
+    // and parses against the current pattern using simple affix comparison.
+    UBool parseForCurrency(const UnicodeString& text,
+                           ParsePosition& parsePosition,
+                           DigitList& digits,
+                           UBool* status,
+                           UChar* currency) const;
+
     int32_t skipPadding(const UnicodeString& text, int32_t position) const;
 
     int32_t compareAffix(const UnicodeString& input,
                          int32_t pos,
                          UBool isNegative,
                          UBool isPrefix,
+                         const UnicodeString* affixPat,
+                         UBool currencyParsing,
+                         int8_t type,
                          UChar* currency) const;
-    
+
     static int32_t compareSimpleAffix(const UnicodeString& affix,
                                       const UnicodeString& input,
-                                      int32_t pos);
-    
-    static int32_t skipRuleWhiteSpace(const UnicodeString& text, int32_t pos);
-    
+                                      int32_t pos,
+                                      UBool lenient);
+
+    static int32_t skipPatternWhiteSpace(const UnicodeString& text, int32_t pos);
+
     static int32_t skipUWhiteSpace(const UnicodeString& text, int32_t pos);
-    
+
     int32_t compareComplexAffix(const UnicodeString& affixPat,
                                 const UnicodeString& input,
                                 int32_t pos,
+                                int8_t type,
                                 UChar* currency) const;
 
     static int32_t match(const UnicodeString& text, int32_t pos, UChar32 ch);
 
     static int32_t match(const UnicodeString& text, int32_t pos, const UnicodeString& str);
 
+    static UBool matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol,
+                             UnicodeSet *sset, UChar32 schar);
+
+    static UBool matchDecimal(UChar32 symbolChar,
+                            UBool sawDecimal,  UChar32 sawDecimalChar,
+                             const UnicodeSet *sset, UChar32 schar);
+
+    static UBool matchGrouping(UChar32 groupingChar,
+                            UBool sawGrouping, UChar32 sawGroupingChar,
+                             const UnicodeSet *sset,
+                             UChar32 decimalChar, const UnicodeSet *decimalSet,
+                             UChar32 schar);
+
     /**
      * Get a decimal format symbol.
      * Returns a const reference to the symbol string.
@@ -1750,15 +2021,18 @@ private:
      */
     inline const UnicodeString &getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const;
 
-    int32_t appendAffix(UnicodeString& buf, double number,
-                        UBool isNegative, UBool isPrefix) const;
+    int32_t appendAffix(UnicodeString& buf,
+                        double number,
+                        FieldPositionHandler& handler,
+                        UBool isNegative,
+                        UBool isPrefix) const;
 
     /**
      * Append an affix to the given UnicodeString, using quotes if
      * there are special characters.  Single quotes themselves must be
      * escaped in either case.
      */
-    void appendAffixPattern(UnicodeString& appendTo, const UnicodeString& affix, 
+    void appendAffixPattern(UnicodeString& appendTo, const UnicodeString& affix,
                             UBool localized) const;
 
     void appendAffixPattern(UnicodeString& appendTo,
@@ -1768,26 +2042,75 @@ private:
     void expandAffix(const UnicodeString& pattern,
                      UnicodeString& affix,
                      double number,
-                     UBool doFormat) const;
+                     FieldPositionHandler& handler,
+                     UBool doFormat,
+                     const UnicodeString* pluralCount) const;
 
-    void expandAffixes();
-    
-    static double round(double a, ERoundingMode mode, UBool isNegative);
+    void expandAffixes(const UnicodeString* pluralCount);
 
     void addPadding(UnicodeString& appendTo,
-                    FieldPosition& fieldPosition,
+                    FieldPositionHandler& handler,
                     int32_t prefixLen, int32_t suffixLen) const;
 
     UBool isGroupingPosition(int32_t pos) const;
 
     void setCurrencyForSymbols();
 
+    // similar to setCurrency without re-compute the affixes for currency.
+    // If currency changes, the affix pattern for currency is not changed,
+    // but the affix will be changed. So, affixes need to be
+    // re-computed in setCurrency(), but not in setCurrencyInternally().
+    virtual void setCurrencyInternally(const UChar* theCurrency, UErrorCode& ec);
+
+    // set up currency affix patterns for mix parsing.
+    // The patterns saved here are the affix patterns of default currency
+    // pattern and the unique affix patterns of the plural currency patterns.
+    // Those patterns are used by parseForCurrency().
+    void setupCurrencyAffixPatterns(UErrorCode& status);
+
+    // set up the currency affixes used in currency plural formatting.
+    // It sets up both fAffixesForCurrency for currency pattern if the current
+    // pattern contains 3 currency signs,
+    // and it sets up fPluralAffixesForCurrency for currency plural patterns.
+    void setupCurrencyAffixes(const UnicodeString& pattern,
+                              UBool setupForCurrentPattern,
+                              UBool setupForPluralPattern,
+                              UErrorCode& status);
+
+    // hashtable operations
+    Hashtable* initHashForAffixPattern(UErrorCode& status);
+    Hashtable* initHashForAffix(UErrorCode& status);
+
+    void deleteHashForAffixPattern();
+    void deleteHashForAffix(Hashtable*& table);
+
+    void copyHashForAffixPattern(const Hashtable* source,
+                                 Hashtable* target, UErrorCode& status);
+    void copyHashForAffix(const Hashtable* source,
+                          Hashtable* target, UErrorCode& status);
+
+    UnicodeString& _format(int64_t number,
+                           UnicodeString& appendTo,
+                           FieldPositionHandler& handler) const;
+    UnicodeString& _format(double number,
+                           UnicodeString& appendTo,
+                           FieldPositionHandler& handler) const;
+    UnicodeString& _format(const DigitList &number,
+                           UnicodeString& appendTo,
+                           FieldPositionHandler& handler,
+                           UErrorCode &status) const;
+
+    // currency sign count
+    enum {
+        fgCurrencySignCountZero,
+        fgCurrencySignCountInSymbolFormat,
+        fgCurrencySignCountInISOFormat,
+        fgCurrencySignCountInPluralFormat
+    } CurrencySignCount;
+
     /**
      * Constants.
      */
-    //static const int8_t fgMaxDigit; // The largest digit, in this case 9
-
-    /*transient*/ //DigitList* fDigitList;
 
     UnicodeString           fPositivePrefix;
     UnicodeString           fPositiveSuffix;
@@ -1805,11 +2128,10 @@ private:
      */
     ChoiceFormat*           fCurrencyChoice;
 
-    int32_t                 fMultiplier;
+    DigitList *             fMultiplier;   // NULL for multiplier of one
     int32_t                 fGroupingSize;
     int32_t                 fGroupingSize2;
     UBool                   fDecimalSeparatorAlwaysShown;
-    /*transient*/ UBool     fIsCurrencyFormat;
     DecimalFormatSymbols*   fSymbols;
 
     UBool                   fUseSignificantDigits;
@@ -1820,18 +2142,124 @@ private:
     int8_t                  fMinExponentDigits;
     UBool                   fExponentSignAlwaysShown;
 
-    /* If fRoundingIncrement is NULL, there is no rounding.  Otherwise, round to
-     * fRoundingIncrement.getDouble().  Since this operation may be expensive,
-     * we cache the result in fRoundingDouble.  All methods that update
-     * fRoundingIncrement also update fRoundingDouble. */
-    DigitList*              fRoundingIncrement;
-    /*transient*/ double    fRoundingDouble;
+    DigitList*              fRoundingIncrement;  // NULL if no rounding increment specified.
     ERoundingMode           fRoundingMode;
 
     UChar32                 fPad;
     int32_t                 fFormatWidth;
     EPadPosition            fPadPosition;
 
+    /*
+     * Following are used for currency format
+     */
+    // pattern used in this formatter
+    UnicodeString fFormatPattern;
+    // style is only valid when decimal formatter is constructed by
+    // DecimalFormat(pattern, decimalFormatSymbol, style)
+    int fStyle;
+    /*
+     * Represents whether this is a currency format, and which
+     * currency format style.
+     * 0: not currency format type;
+     * 1: currency style -- symbol name, such as "$" for US dollar.
+     * 2: currency style -- ISO name, such as USD for US dollar.
+     * 3: currency style -- plural long name, such as "US Dollar" for
+     *                      "1.00 US Dollar", or "US Dollars" for
+     *                      "3.00 US Dollars".
+     */
+    int fCurrencySignCount;
+
+
+    /* For currency parsing purose,
+     * Need to remember all prefix patterns and suffix patterns of
+     * every currency format pattern,
+     * including the pattern of default currecny style
+     * and plural currency style. And the patterns are set through applyPattern.
+     */
+    // TODO: innerclass?
+    /* This is not needed in the class declaration, so it is moved into decimfmp.cpp
+    struct AffixPatternsForCurrency : public UMemory {
+        // negative prefix pattern
+        UnicodeString negPrefixPatternForCurrency;
+        // negative suffix pattern
+        UnicodeString negSuffixPatternForCurrency;
+        // positive prefix pattern
+        UnicodeString posPrefixPatternForCurrency;
+        // positive suffix pattern
+        UnicodeString posSuffixPatternForCurrency;
+        int8_t patternType;
+
+        AffixPatternsForCurrency(const UnicodeString& negPrefix,
+                                 const UnicodeString& negSuffix,
+                                 const UnicodeString& posPrefix,
+                                 const UnicodeString& posSuffix,
+                                 int8_t type) {
+            negPrefixPatternForCurrency = negPrefix;
+            negSuffixPatternForCurrency = negSuffix;
+            posPrefixPatternForCurrency = posPrefix;
+            posSuffixPatternForCurrency = posSuffix;
+            patternType = type;
+        }
+    };
+    */
+
+    /* affix for currency formatting when the currency sign in the pattern
+     * equals to 3, such as the pattern contains 3 currency sign or
+     * the formatter style is currency plural format style.
+     */
+    /* This is not needed in the class declaration, so it is moved into decimfmp.cpp
+    struct AffixesForCurrency : public UMemory {
+        // negative prefix
+        UnicodeString negPrefixForCurrency;
+        // negative suffix
+        UnicodeString negSuffixForCurrency;
+        // positive prefix
+        UnicodeString posPrefixForCurrency;
+        // positive suffix
+        UnicodeString posSuffixForCurrency;
+
+        int32_t formatWidth;
+
+        AffixesForCurrency(const UnicodeString& negPrefix,
+                           const UnicodeString& negSuffix,
+                           const UnicodeString& posPrefix,
+                           const UnicodeString& posSuffix) {
+            negPrefixForCurrency = negPrefix;
+            negSuffixForCurrency = negSuffix;
+            posPrefixForCurrency = posPrefix;
+            posSuffixForCurrency = posSuffix;
+        }
+    };
+    */
+
+    // Affix pattern set for currency.
+    // It is a set of AffixPatternsForCurrency,
+    // each element of the set saves the negative prefix pattern,
+    // negative suffix pattern, positive prefix pattern,
+    // and positive suffix  pattern of a pattern.
+    // It is used for currency mixed style parsing.
+    // It is actually is a set.
+    // The set contains the default currency pattern from the locale,
+    // and the currency plural patterns.
+    // Since it is a set, it does not contain duplicated items.
+    // For example, if 2 currency plural patterns are the same, only one pattern
+    // is included in the set. When parsing, we do not check whether the plural
+    // count match or not.
+    Hashtable* fAffixPatternsForCurrency;
+
+    // Following 2 are affixes for currency.
+    // It is a hash map from plural count to AffixesForCurrency.
+    // AffixesForCurrency saves the negative prefix,
+    // negative suffix, positive prefix, and positive suffix of a pattern.
+    // It is used during currency formatting only when the currency sign count
+    // is 3. In which case, the affixes are getting from here, not
+    // from the fNegativePrefix etc.
+    Hashtable* fAffixesForCurrency;  // for current pattern
+    Hashtable* fPluralAffixesForCurrency;  // for plural pattern
+
+    // Information needed for DecimalFormat to format/parse currency plural.
+    CurrencyPluralInfo* fCurrencyPluralInfo;
+
 protected:
 
     /**
@@ -1844,13 +2272,13 @@ protected:
      */
     virtual void getEffectiveCurrency(UChar* result, UErrorCode& ec) const;
 
-  /** number of integer digits 
+  /** number of integer digits
    * @stable ICU 2.4
-   */  
+   */
     static const int32_t  kDoubleIntegerDigits;
-  /** number of fraction digits 
+  /** number of fraction digits
    * @stable ICU 2.4
-   */  
+   */
     static const int32_t  kDoubleFractionDigits;
 
     /**
@@ -1889,10 +2317,12 @@ DecimalFormat::format(int32_t number,
     return format((int64_t)number, appendTo, pos);
 }
 
+#ifndef U_HIDE_INTERNAL_API
 inline const UnicodeString &
 DecimalFormat::getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
     return fSymbols->getConstSymbol(symbol);
 }
+#endif
 
 U_NAMESPACE_END