Proposal: Better support for currency formatting and parsing in ICU 3.0 (JB#2825)

Alan S Liu <[email protected]> Tue, 27 Apr 2004 17:01:30 -0700
Newsgroups gmane.comp.lib.icu.general
Message-ID <OFEFCC400B.31427491-ON88256E83.00836B08-88256E84.00000953@us.ibm.com>
Proposed changes to support currency parsing and formatting in ICU
3.0.

See: http://www.jtcsv.com/cgibin/icu-bugs?findid=2825

C++
===

Notes:

1. Boilerplate such as copy constructors, destructors, assignment
   operators, equality operators, getDynamicClassID, getStaticClassID,
   has been omitted in some cases for clarity.

2. Formattable is an existing class; it gets some new draft ICU 3.0
   methods that are listed below.

3. Measure, CurrencyAmount, MeasureUnit, CurrencyUnit, and
   MeasureFormat are new to 3.0.  They are marked draft ICU 3.0, as
   are all their methods.


class U_I18N_API Measure: public UObject {
 public:
    Measure(const Formattable& number, MeasureUnit* adoptedUnit,
            UErrorCode& ec);

    inline const Formattable& getNumber() const;

    inline const MeasureUnit& getUnit() const;
};


class U_I18N_API CurrencyAmount: public Measure {
 public:
    CurrencyAmount(const Formattable& amount, const UChar* isoCode,
                   UErrorCode &ec);

    CurrencyAmount(double amount, const UChar* isoCode,
                   UErrorCode &ec);

    inline const CurrencyUnit& getCurrency() const;

    inline const UChar* getISOCurrency() const;
};


class U_I18N_API MeasureUnit: public UObject {
 public:
    virtual UObject* clone() const = 0;

    virtual ~MeasureUnit();

 protected:
    MeasureUnit();
};


class U_I18N_API CurrencyUnit: public MeasureUnit {
 public:
    CurrencyUnit(const UChar* isoCode, UErrorCode &ec);

    inline const UChar* getISOCurrency() const;
};


class Formattable {
     /**
      * Creates a Formattable object that adopts the given UObject.
      * @param objectToAdopt the UObject to set this object to
      * @draft ICU 3.0
      */
    Formattable(UObject* objectToAdopt);
 
    enum Type {
        /**
         * Selector indicating a UObject value.  Use getObject to
         * retrieve the value.
         * @draft ICU 3.0
         */
        kObject
    };
 
    /**
     * Returns TRUE if the data type of this Formattable object
     * is kDouble, kLong, or kInt64.
     * @return TRUE if this is a pure numeric object
     * @draft ICU 3.0
     */
    UBool           isNumeric() const;
 
    /**
     * Returns a pointer to the UObject contained within this
     * formattable, or NULL if this object does not contain a UObject.
     * @return a UObject pointer, or NULL
     * @draft ICU 3.0
     */
    const UObject*  getObject() const;
 
    /**
     * Sets and adopts the UObject value of this object and changes
     * the type to kObject.  After this call, the caller must not
     * delete the given object.
     * @param objectToAdopt the UObject value to be adopted
     * @draft ICU 3.0
     */
    void            adoptObject(UObject* objectToAdopt);
};


class U_I18N_API MeasureFormat : public Format {
 public:
    static MeasureFormat* createCurrencyFormat(const Locale& locale,
                                               UErrorCode& ec);

    static MeasureFormat* createCurrencyFormat(UErrorCode& ec);
};


C: unum.h
=========

/**
 * Format a double currency amount using a UNumberFormat.
 * The double will be formatted according to the UNumberFormat's locale.
 * @param fmt the formatter to use
 * @param number the number to format
 * @param currency the 3-letter null-terminated ISO 4217 currency code
 * @param result a pointer to the buffer to receive the formatted number
 * @param resultLength the maximum number of UChars to write to result
 * @param pos a pointer to a UFieldPosition.  On input,
 * position->field is read.  On output, position->beginIndex and
 * position->endIndex indicate the beginning and ending indices of
 * field number position->field, if such a field exists.  This
 * parameter may be NULL, in which case it is ignored.
 * @param status a pointer to an input-output UErrorCode
 * @return the total buffer size needed; if greater than resultLength,
 * the output was truncated.
 * @see unum_formatDouble
 * @see unum_parseDoubleCurrency
 * @see UFieldPosition
 * @draft ICU 3.0
 */
U_DRAFT int32_t U_EXPORT2
unum_formatDoubleCurrency(const UNumberFormat* fmt,
                          double number,
                          UChar* currency,
                          UChar* result,
                          int32_t resultLength,
                          UFieldPosition* pos, /* ignored if 0 */
                          UErrorCode* status);

/**
 * Parse a string into a double and a currency using a UNumberFormat.
 * The string will be parsed according to the UNumberFormat's locale.
 * @param fmt the formatter to use
 * @param text the text to parse
 * @param textLength the length of text, or -1 if null-terminated
 * @param parsePos a pointer to an offset index into text at which to
 * begin parsing. On output, *parsePos will point after the last
 * parsed character.  This parameter may be 0, in which case parsing
 * begins at offset 0.
 * @param currency a pointer to the buffer to receive the parsed null-
 * terminated currency.  This buffer must have a capacity of at least
 * 4 UChars.
 * @param status a pointer to an input-output UErrorCode
 * @return the parsed double
 * @see unum_parseDouble
 * @see unum_formatDoubleCurrency
 * @draft ICU 3.0
 */
U_DRAFT double U_EXPORT2
unum_parseDoubleCurrency(const UNumberFormat* fmt,
                         const UChar* text,
                         int32_t textLength,
                         int32_t* parsePos, /* 0 = start */
                         UChar* currency,
                         UErrorCode* status);

Java
====

Notes:

1. The class com.ibm.icu.util.Currency is changed to extend
   MeasureUnit.  Otherwise its public API is unchanged.

2. Boilerplate methods such as equals, hashCode, clone have been
   omitted for clarity.

3. Measure, CurrencyAmount, MeasureUnit, and MeasureFormat are new to
   3.0.  They are marked draft ICU 3.0, as are all their methods.


public abstract class Measure {
 
    protected Measure(Number number, MeasureUnit unit);
 
    public Number getNumber();

    public MeasureUnit getUnit();
}


public class CurrencyAmount extends Measure {

    public CurrencyAmount(Number number, Currency currency);

    public CurrencyAmount(double number, Currency currency);
 
    public Currency getCurrency();
}


public abstract class MeasureUnit {
}


public abstract class MeasureFormat extends UFormat {

    public static MeasureFormat getCurrencyFormat(ULocale locale);

    public static MeasureFormat getCurrencyFormat();
}

[Alan S Liu/San Jose/IBM@IBMUS; [email protected];; IBM Globalization; 
5600 Cottle Road; San Jose, CA 95193;; (408) 256-3155]