clone();
+ }
+ return *this;
+}
+
+Measure::~Measure() {
+ delete unit;
+}
+
+UBool Measure::operator==(const UObject& other) const {
+ const Measure* m = (const Measure*) &other;
+ return getDynamicClassID() == other.getDynamicClassID() &&
+ number == m->getNumber() &&
+ *unit == m->getUnit();
+}
+
+//----------------------------------------------------------------------
+// MeasureUnit implementation
+
+MeasureUnit:: MeasureUnit() {}
+
+MeasureUnit::~MeasureUnit() {}
+
+U_NAMESPACE_END
+
+#endif // !UCONFIG_NO_FORMATTING
diff --git a/icu4c/source/i18n/numfmt.cpp b/icu4c/source/i18n/numfmt.cpp
index 3a59f6306a0..5785b8aee88 100644
--- a/icu4c/source/i18n/numfmt.cpp
+++ b/icu4c/source/i18n/numfmt.cpp
@@ -33,6 +33,7 @@
#include "unicode/decimfmt.h"
#include "unicode/ustring.h"
#include "unicode/ucurr.h"
+#include "unicode/curramt.h"
#include "uhash.h"
#include "iculserv.h"
#include "ucln_in.h"
@@ -222,29 +223,34 @@ NumberFormat::format(const Formattable& obj,
if (U_FAILURE(status)) return appendTo;
NumberFormat* nonconst = (NumberFormat*) this;
+ const Formattable* n = &obj;
UChar save[4];
UBool setCurr = FALSE;
- const UChar *curr = obj.getCurrency(); // most commonly curr==NULL
- if (curr != NULL) {
- // getCurrency() returns a pointer to internal storage, so we
+ const UObject* o = obj.getObject(); // most commonly o==NULL
+ if (o != NULL &&
+ o->getDynamicClassID() == CurrencyAmount::getStaticClassID()) {
+ // getISOCurrency() returns a pointer to internal storage, so we
// copy it to retain it across the call to setCurrency().
+ const CurrencyAmount* amt = (const CurrencyAmount*) o;
+ const UChar* curr = amt->getISOCurrency();
u_strcpy(save, getCurrency());
setCurr = (u_strcmp(curr, save) != 0);
if (setCurr) {
nonconst->setCurrency(curr, status);
}
+ n = &amt->getNumber();
}
- switch (obj.getType()) {
+ switch (n->getType()) {
case Formattable::kDouble:
- format(obj.getDouble(), appendTo, pos);
+ format(n->getDouble(), appendTo, pos);
break;
case Formattable::kLong:
- format(obj.getLong(), appendTo, pos);
+ format(n->getLong(), appendTo, pos);
break;
case Formattable::kInt64:
- format(obj.getInt64(), appendTo, pos);
+ format(n->getInt64(), appendTo, pos);
break;
default:
status = U_INVALID_FORMAT_ERROR;
@@ -342,7 +348,11 @@ Formattable& NumberFormat::parseCurrency(const UnicodeString& text,
UErrorCode ec = U_ZERO_ERROR;
getEffectiveCurrency(curr, ec);
if (U_SUCCESS(ec)) {
- result.setCurrency(curr);
+ Formattable n(result);
+ result.adoptObject(new CurrencyAmount(n, curr, ec));
+ if (U_FAILURE(ec)) {
+ pos.setIndex(start); // indicate failure
+ }
}
}
return result;
diff --git a/icu4c/source/i18n/unicode/curramt.h b/icu4c/source/i18n/unicode/curramt.h
new file mode 100644
index 00000000000..66feeffd215
--- /dev/null
+++ b/icu4c/source/i18n/unicode/curramt.h
@@ -0,0 +1,124 @@
+/*
+**********************************************************************
+* Copyright (c) 2004, International Business Machines
+* Corporation and others. All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: April 26, 2004
+* Since: ICU 3.0
+**********************************************************************
+*/
+#ifndef __CURRENCYAMOUNT_H__
+#define __CURRENCYAMOUNT_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/measure.h"
+#include "unicode/currunit.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * A currency together with a numeric amount, such as 200 USD.
+ *
+ * @author Alan Liu
+ * @internal
+ */
+class U_I18N_API CurrencyAmount: public Measure {
+ public:
+ /**
+ * Construct an object with the given numeric amount and the given
+ * ISO currency code.
+ * @param amount a numeric object; amount.isNumeric() must be TRUE
+ * @param isoCode the 3-letter ISO 4217 currency code; must not be
+ * NULL and must have length 3
+ * @param ec input-output error code. If the amount or the isoCode
+ * is invalid, then this will be set to a failing value.
+ * @internal
+ */
+ CurrencyAmount(const Formattable& amount, const UChar* isoCode,
+ UErrorCode &ec);
+
+ /**
+ * Construct an object with the given numeric amount and the given
+ * ISO currency code.
+ * @param amount the amount of the given currency
+ * @param isoCode the 3-letter ISO 4217 currency code; must not be
+ * NULL and must have length 3
+ * @param ec input-output error code. If the isoCode is invalid,
+ * then this will be set to a failing value.
+ * @internal
+ */
+ CurrencyAmount(double amount, const UChar* isoCode,
+ UErrorCode &ec);
+
+ /**
+ * Copy constructor
+ * @internal
+ */
+ CurrencyAmount(const CurrencyAmount& other);
+
+ /**
+ * Assignment operator
+ * @internal
+ */
+ CurrencyAmount& operator=(const CurrencyAmount& other);
+
+ /**
+ * Return a polymorphic clone of this object. The result will
+ * have the same class as returned by getDynamicClassID().
+ * @internal
+ */
+ virtual UObject* clone() const;
+
+ /**
+ * Destructor
+ * @internal
+ */
+ virtual ~CurrencyAmount();
+
+ /**
+ * Returns a unique class ID for this object POLYMORPHICALLY.
+ * This method implements a simple form of RTTI used by ICU.
+ * @return The class ID for this object. All objects of a given
+ * class have the same class ID. Objects of other classes have
+ * different class IDs.
+ * @internal
+ */
+ virtual UClassID getDynamicClassID() const;
+
+ /**
+ * Returns the class ID for this class. This is used to compare to
+ * the return value of getDynamicClassID().
+ * @return The class ID for all objects of this class.
+ * @internal
+ */
+ static UClassID getStaticClassID();
+
+ /**
+ * Return the currency unit object of this object.
+ * @internal
+ */
+ inline const CurrencyUnit& getCurrency() const;
+
+ /**
+ * Return the ISO currency code of this object.
+ * @internal
+ */
+ inline const UChar* getISOCurrency() const;
+};
+
+inline const CurrencyUnit& CurrencyAmount::getCurrency() const {
+ return (const CurrencyUnit&) getUnit();
+}
+
+inline const UChar* CurrencyAmount::getISOCurrency() const {
+ return getCurrency().getISOCurrency();
+}
+
+U_NAMESPACE_END
+
+#endif // !UCONFIG_NO_FORMATTING
+#endif // __CURRENCYAMOUNT_H__
diff --git a/icu4c/source/i18n/unicode/currunit.h b/icu4c/source/i18n/unicode/currunit.h
new file mode 100644
index 00000000000..17014b2cdd5
--- /dev/null
+++ b/icu4c/source/i18n/unicode/currunit.h
@@ -0,0 +1,112 @@
+/*
+**********************************************************************
+* Copyright (c) 2004, International Business Machines
+* Corporation and others. All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: April 26, 2004
+* Since: ICU 3.0
+**********************************************************************
+*/
+#ifndef __CURRENCYUNIT_H__
+#define __CURRENCYUNIT_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/measunit.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * A unit of currency, such as USD (U.S. dollars) or JPY (Japanese
+ * yen). This class is a thin wrapper over a UChar string that
+ * subclasses MeasureUnit, for use with Measure and MeasureFormat.
+ *
+ * @author Alan Liu
+ * @internal
+ */
+class U_I18N_API CurrencyUnit: public MeasureUnit {
+ public:
+ /**
+ * Construct an object with the given ISO currency code.
+ * @param isoCode the 3-letter ISO 4217 currency code; must not be
+ * NULL and must have length 3
+ * @param ec input-output error code. If the isoCode is invalid,
+ * then this will be set to a failing value.
+ * @internal
+ */
+ CurrencyUnit(const UChar* isoCode, UErrorCode &ec);
+
+ /**
+ * Copy constructor
+ * @internal
+ */
+ CurrencyUnit(const CurrencyUnit& other);
+
+ /**
+ * Assignment operator
+ * @internal
+ */
+ CurrencyUnit& operator=(const CurrencyUnit& other);
+
+ /**
+ * Return a polymorphic clone of this object. The result will
+ * have the same class as returned by getDynamicClassID().
+ * @internal
+ */
+ virtual UObject* clone() const;
+
+ /**
+ * Destructor
+ * @internal
+ */
+ virtual ~CurrencyUnit();
+
+ /**
+ * Equality operator. Return true if this object is equal
+ * to the given object.
+ * @internal
+ */
+ UBool operator==(const UObject& other) const;
+
+ /**
+ * Returns a unique class ID for this object POLYMORPHICALLY.
+ * This method implements a simple form of RTTI used by ICU.
+ * @return The class ID for this object. All objects of a given
+ * class have the same class ID. Objects of other classes have
+ * different class IDs.
+ * @internal
+ */
+ virtual UClassID getDynamicClassID() const;
+
+ /**
+ * Returns the class ID for this class. This is used to compare to
+ * the return value of getDynamicClassID().
+ * @return The class ID for all objects of this class.
+ * @internal
+ */
+ static UClassID getStaticClassID();
+
+ /**
+ * Return the ISO currency code of this object.
+ * @internal
+ */
+ inline const UChar* getISOCurrency() const;
+
+ private:
+ /**
+ * The ISO 4217 code of this object.
+ */
+ UChar isoCode[4];
+};
+
+inline const UChar* CurrencyUnit::getISOCurrency() const {
+ return isoCode;
+}
+
+U_NAMESPACE_END
+
+#endif // !UCONFIG_NO_FORMATTING
+#endif // __CURRENCYUNIT_H__
diff --git a/icu4c/source/i18n/unicode/fmtable.h b/icu4c/source/i18n/unicode/fmtable.h
index 90afb5201b4..8db065ffee9 100644
--- a/icu4c/source/i18n/unicode/fmtable.h
+++ b/icu4c/source/i18n/unicode/fmtable.h
@@ -98,30 +98,6 @@ public:
*/
Formattable(int64_t ll);
- /**
- * Creates a Formattable for a currency amount.
- * @param n the numeric value
- * @param currency the currency code
- * @draft ICU 3.0
- */
- Formattable(double n, const UChar* currency);
-
- /**
- * Creates a Formattable for a currency amount.
- * @param n the numeric value
- * @param currency the currency code
- * @draft ICU 3.0
- */
- Formattable(int32_t n, const UChar* currency);
-
- /**
- * Creates a Formattable for a currency amount.
- * @param n the numeric value
- * @param currency the currency code
- * @draft ICU 3.0
- */
- Formattable(int64_t n, const UChar* currency);
-
/**
* Creates a Formattable object with a char string pointer.
* Assumes that the char string is null terminated.
@@ -152,6 +128,13 @@ public:
*/
Formattable(const Formattable* arrayToCopy, int32_t count);
+ /**
+ * 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);
+
/**
* Copy constructor.
* @stable ICU 2.0
@@ -202,22 +185,60 @@ public:
Formattable *clone() const;
/**
- * The list of possible data types of this Formattable object.
+ * Selector for flavor of data type contained within a
+ * Formattable object. Formattable is a union of several
+ * different types, and at any time contains exactly one type.
* @stable ICU 2.4
*/
enum Type {
- /** @stable ICU 2.4 */
- kDate, // Date
- /** @stable ICU 2.4 */
- kDouble, // double
- /** @stable ICU 2.4 */
- kLong, // long
- /** @stable ICU 2.4 */
- kString, // UnicodeString
- /** @stable ICU 2.4 */
- kArray, // Formattable[]
- /** @draft ICU 2.8 */
- kInt64 // int64
+ /**
+ * Selector indicating a UDate value. Use getDate to retrieve
+ * the value.
+ * @stable ICU 2.4
+ */
+ kDate,
+
+ /**
+ * Selector indicating a double value. Use getDouble to
+ * retrieve the value.
+ * @stable ICU 2.4
+ */
+ kDouble,
+
+ /**
+ * Selector indicating a 32-bit integer value. Use getLong to
+ * retrieve the value.
+ * @stable ICU 2.4
+ */
+ kLong,
+
+ /**
+ * Selector indicating a UnicodeString value. Use getString
+ * to retrieve the value.
+ * @stable ICU 2.4
+ */
+ kString,
+
+ /**
+ * Selector indicating an array of Formattables. Use getArray
+ * to retrieve the value.
+ * @stable ICU 2.4
+ */
+ kArray,
+
+ /**
+ * Selector indicating a 64-bit integer value. Use getInt64
+ * to retrieve the value.
+ * @draft ICU 2.8
+ */
+ kInt64,
+
+ /**
+ * Selector indicating a UObject value. Use getObject to
+ * retrieve the value.
+ * @draft ICU 3.0
+ */
+ kObject
};
/**
@@ -227,6 +248,14 @@ public:
*/
Type getType(void) const;
+ /**
+ * 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;
+
/**
* Gets the double value of this object. If this object is not of type
* kDouble then the result is undefined.
@@ -238,8 +267,11 @@ public:
/**
* Gets the double value of this object. If this object is of type
* long or int64 then a casting conversion is peformed, with
- * possible loss of precision. If the type is not a numeric type,
- * 0 is returned and the status is set to U_INVALID_FORMAT_ERROR.
+ * possible loss of precision. If the type is kObject and the
+ * object is a Measure, then the result of
+ * getNumber().getDouble(status) is returned. If this object is
+ * neither a numeric type nor a Measure, then 0 is returned and
+ * the status is set to U_INVALID_FORMAT_ERROR.
* @param status the error code
* @return the double value of this object.
* @draft ICU 3.0
@@ -261,9 +293,11 @@ public:
* U_INVALID_FORMAT_ERROR. If this object is of type kInt64 and
* it fits within a long, then no precision is lost. If it is of
* type kDouble, then a casting conversion is peformed, with
- * truncation of any fractional part. If the type is not a
- * numeric type, 0 is returned and the status is set to
- * U_INVALID_FORMAT_ERROR.
+ * truncation of any fractional part. If the type is kObject and
+ * the object is a Measure, then the result of
+ * getNumber().getLong(status) is returned. If this object is
+ * neither a numeric type nor a Measure, then 0 is returned and
+ * the status is set to U_INVALID_FORMAT_ERROR.
* @param status the error code
* @return the long value of this object.
* @draft ICU 3.0
@@ -285,8 +319,10 @@ public:
* and the status is set to U_INVALID_FORMAT_ERROR. If the
* magnitude fits in an int64, then a casting conversion is
* peformed, with truncation of any fractional part. If the type
- * is not a numeric type, 0 is returned and the status is set to
- * U_INVALID_FORMAT_ERROR.
+ * is kObject and the object is a Measure, then the result of
+ * getNumber().getDouble(status) is returned. If this object is
+ * neither a numeric type nor a Measure, then 0 is returned and
+ * the status is set to U_INVALID_FORMAT_ERROR.
* @param status the error code
* @return the int64 value of this object.
* @draft ICU 3.0
@@ -401,13 +437,12 @@ public:
Formattable& operator[](int32_t index) { return fValue.fArrayAndCount.fArray[index]; }
/**
- * Returns the currency of this object, or NULL if this object has
- * no associated currency. Any type may have a currency, although
- * this is intended for use with numeric types.
- * @return a null-terminated 3-letter ISO 4217 code, or NULL
+ * 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 UChar* getCurrency() const;
+ const UObject* getObject() const;
/**
* Sets the double value of this object and changes the type to
@@ -474,15 +509,13 @@ public:
void adoptArray(Formattable* array, int32_t count);
/**
- * Sets the currency of this object. Only numeric types may have
- * a currency. If isoCode is NULL then the currency is removed
- * from this object. Any type may have a currency, although
- * this is intended for use with numeric types.
- * @param currency a null-terminated 3-letter ISO 4217 code, or NULL.
- * If longer than 3 characters, the extra characters are ignored.
+ * 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 setCurrency(const UChar* currency);
+ void adoptObject(UObject* objectToAdopt);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
@@ -525,19 +558,18 @@ private:
UnicodeString* getBogus() const;
union {
+ UObject* fObject;
UnicodeString* fString;
double fDouble;
int64_t fInt64;
UDate fDate;
- struct
- {
- Formattable* fArray;
- int32_t fCount;
+ struct {
+ Formattable* fArray;
+ int32_t fCount;
} fArrayAndCount;
- } fValue;
+ } fValue;
Type fType;
- UChar fCurrency[4];
UnicodeString fBogus; // Bogus string when it's needed.
};
diff --git a/icu4c/source/i18n/unicode/measunit.h b/icu4c/source/i18n/unicode/measunit.h
new file mode 100644
index 00000000000..fc4b92d9877
--- /dev/null
+++ b/icu4c/source/i18n/unicode/measunit.h
@@ -0,0 +1,65 @@
+/*
+**********************************************************************
+* Copyright (c) 2004, International Business Machines
+* Corporation and others. All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: April 26, 2004
+* Since: ICU 3.0
+**********************************************************************
+*/
+#ifndef __MEASUREUNIT_H__
+#define __MEASUREUNIT_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/fmtable.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * A unit such as length, mass, volume, currency, etc. A unit is
+ * coupled with a numeric amount to produce a Measure.
+ *
+ * This is an abstract class.
+ *
+ * @author Alan Liu
+ * @internal
+ */
+class U_I18N_API MeasureUnit: public UObject {
+ public:
+ /**
+ * Return a polymorphic clone of this object. The result will
+ * have the same class as returned by getDynamicClassID().
+ * @internal
+ */
+ virtual UObject* clone() const = 0;
+
+ /**
+ * Destructor
+ * @internal
+ */
+ virtual ~MeasureUnit();
+
+ /**
+ * Equality operator. Return true if this object is equal
+ * to the given object.
+ * @internal
+ */
+ virtual UBool operator==(const UObject& other) const = 0;
+
+ protected:
+ /**
+ * Default constructor.
+ */
+ MeasureUnit();
+};
+
+U_NAMESPACE_END
+
+// NOTE: There is no measunit.cpp. For implementation, see measure.cpp. [alan]
+
+#endif // !UCONFIG_NO_FORMATTING
+#endif // __MEASUREUNIT_H__
diff --git a/icu4c/source/i18n/unicode/measure.h b/icu4c/source/i18n/unicode/measure.h
new file mode 100644
index 00000000000..73ad0b8d1ca
--- /dev/null
+++ b/icu4c/source/i18n/unicode/measure.h
@@ -0,0 +1,125 @@
+/*
+**********************************************************************
+* Copyright (c) 2004, International Business Machines
+* Corporation and others. All Rights Reserved.
+**********************************************************************
+* Author: Alan Liu
+* Created: April 26, 2004
+* Since: ICU 3.0
+**********************************************************************
+*/
+#ifndef __MEASURE_H__
+#define __MEASURE_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/fmtable.h"
+
+U_NAMESPACE_BEGIN
+
+class MeasureUnit;
+
+/**
+ * An amount of a specified unit, consisting of a number and a Unit.
+ * For example, a length measure consists of a number and a length
+ * unit, such as feet or meters. This is an abstract class.
+ * Subclasses specify a concrete Unit type.
+ *
+ *
Measure objects are parsed and formatted by subclasses of
+ * MeasureFormat.
+ *
+ *
Measure objects are immutable.
+ *
+ *
This is an abstract class.
+ *
+ * @author Alan Liu
+ * @draft ICU 3.0
+ */
+class U_I18N_API Measure: public UObject {
+ public:
+ /**
+ * Construct an object with the given numeric amount and the given
+ * unit. After this call, the caller must not delete the given
+ * unit object.
+ * @param amount a numeric object; amount.isNumeric() must be TRUE
+ * @param adpoptedUnit the unit object, which must not be NULL
+ * @param ec input-output error code. If the amount or the unit
+ * is invalid, then this will be set to a failing value.
+ * @internal
+ */
+ Measure(const Formattable& number, MeasureUnit* adoptedUnit,
+ UErrorCode& ec);
+
+ /**
+ * Copy constructor
+ * @internal
+ */
+ Measure(const Measure& other);
+
+ /**
+ * Assignment operator
+ * @internal
+ */
+ Measure& operator=(const Measure& other);
+
+ /**
+ * Return a polymorphic clone of this object. The result will
+ * have the same class as returned by getDynamicClassID().
+ * @internal
+ */
+ virtual UObject* clone() const = 0;
+
+ /**
+ * Destructor
+ * @internal
+ */
+ virtual ~Measure();
+
+ /**
+ * Equality operator. Return true if this object is equal
+ * to the given object.
+ * @internal
+ */
+ UBool operator==(const UObject& other) const;
+
+ /**
+ * Return a reference to the numeric value of this object. The
+ * numeric value may be of any numeric type supported by
+ * Formattable.
+ * @internal
+ */
+ inline const Formattable& getNumber() const;
+
+ /**
+ * Return a reference to the unit of this object.
+ * @internal
+ */
+ inline const MeasureUnit& getUnit() const;
+
+ private:
+ /**
+ * The numeric value of this object, e.g. 2.54 or 100.
+ */
+ Formattable number;
+
+ /**
+ * The unit of this object, e.g., "millimeter" or "JPY". This is
+ * owned by this object.
+ */
+ MeasureUnit* unit;
+};
+
+inline const Formattable& Measure::getNumber() const {
+ return number;
+}
+
+inline const MeasureUnit& Measure::getUnit() const {
+ return *unit;
+}
+
+U_NAMESPACE_END
+
+#endif // !UCONFIG_NO_FORMATTING
+#endif // __MEASURE_H__
diff --git a/icu4c/source/i18n/unum.cpp b/icu4c/source/i18n/unum.cpp
index 9224077514d..6415c3c96fc 100644
--- a/icu4c/source/i18n/unum.cpp
+++ b/icu4c/source/i18n/unum.cpp
@@ -23,6 +23,7 @@
#include "unicode/ustring.h"
#include "unicode/fmtable.h"
#include "unicode/dcfmtsym.h"
+#include "unicode/curramt.h"
#include "uassert.h"
#include "cpputils.h"
@@ -270,8 +271,8 @@ unum_formatDoubleCurrency(const UNumberFormat* fmt,
if (pos != 0) {
fp.setField(pos->field);
}
-
- Formattable n(number, currency);
+
+ Formattable n(new CurrencyAmount(number, currency, *status));
((const NumberFormat*)fmt)->format(n, res, fp, *status);
if (pos != 0) {
@@ -363,8 +364,10 @@ unum_parseDoubleCurrency(const UNumberFormat* fmt,
Formattable res;
parseRes(res, fmt, text, textLength, parsePos, TRUE, status);
currency[0] = 0;
- if (res.getCurrency() != 0) {
- u_strcpy(currency, res.getCurrency());
+ if (res.getType() == Formattable::kObject &&
+ res.getObject()->getDynamicClassID() == CurrencyAmount::getStaticClassID()) {
+ const CurrencyAmount* c = (const CurrencyAmount*) res.getObject();
+ u_strcpy(currency, c->getISOCurrency());
}
return res.getDouble(*status);
}
diff --git a/icu4c/source/test/intltest/intltest.cpp b/icu4c/source/test/intltest/intltest.cpp
index 55d5159d3c0..5acb716e78e 100644
--- a/icu4c/source/test/intltest/intltest.cpp
+++ b/icu4c/source/test/intltest/intltest.cpp
@@ -23,6 +23,7 @@
#include "unicode/ucnv.h"
#include "unicode/uclean.h"
#include "unicode/timezone.h"
+#include "unicode/curramt.h"
#include "intltest.h"
#include "caltztst.h"
@@ -115,17 +116,10 @@ operator+(const UnicodeString& left,
#if !UCONFIG_NO_FORMATTING
/**
- * Originally coded this as operator+, but that makes the expression
- * + char* ambiguous. - liu
+ * Return a string display for for this, without surrounding braces.
*/
-UnicodeString toString(const Formattable& f) {
+UnicodeString _toString(const Formattable& f) {
UnicodeString s;
- UnicodeString close;
- const UChar* currency = f.getCurrency();
- if (currency != NULL) {
- close.append((UChar)0x2f/*/*/).append(currency);
- }
- close.append((UChar)0x5d/*]*/);
switch (f.getType()) {
case Formattable::kDate:
{
@@ -134,48 +128,68 @@ UnicodeString toString(const Formattable& f) {
if (U_SUCCESS(status)) {
FieldPosition pos;
fmt.format(f.getDate(), s, pos);
- s.insert(0, "[Date:");
- s.append(close);
+ s.insert(0, "Date:");
} else {
- s = UnicodeString("[Error creating date format]");
+ s = UnicodeString("Error creating date format]");
}
}
break;
case Formattable::kDouble:
- s = UnicodeString("[double:") + f.getDouble() + close;
+ s = UnicodeString("double:") + f.getDouble();
break;
case Formattable::kLong:
- s = UnicodeString("[long:") + f.getLong() + close;
+ s = UnicodeString("long:") + f.getLong();
break;
case Formattable::kInt64:
- s = UnicodeString("[int64:") + Int64ToUnicodeString(f.getInt64()) + close;
+ s = UnicodeString("int64:") + Int64ToUnicodeString(f.getInt64());
break;
case Formattable::kString:
f.getString(s);
- s.insert(0, "[String:");
- s.append(close);
+ s.insert(0, "String:");
break;
case Formattable::kArray:
{
int32_t i, n;
const Formattable* array = f.getArray(n);
- s.insert(0, UnicodeString("[Array:"));
+ s.insert(0, UnicodeString("Array:"));
UnicodeString delim(", ");
for (i=0; i 0) {
s.append(delim);
}
- s = s + toString(array[i]);
+ s = s + _toString(array[i]);
}
- s.append(close);
}
break;
+ case Formattable::kObject:
+ if (f.getObject()->getDynamicClassID() ==
+ CurrencyAmount::getStaticClassID()) {
+ const CurrencyAmount& c = (const CurrencyAmount&) *f.getObject();
+ s = _toString(c.getNumber()) + " " + UnicodeString(c.getISOCurrency());
+ } else {
+ s = UnicodeString("Unknown UObject");
+ }
+ break;
+ default:
+ s = UnicodeString("Unknown Formattable type=") + (int32_t)f.getType();
+ break;
}
return s;
}
+/**
+ * Originally coded this as operator+, but that makes the expression
+ * + char* ambiguous. - liu
+ */
+UnicodeString toString(const Formattable& f) {
+ UnicodeString s((UChar)91/*[*/);
+ s.append(_toString(f));
+ s.append((UChar)0x5d/*]*/);
+ return s;
+}
+
#endif
// useful when operator+ won't cooperate
diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp
index cc1e054806d..629c4d123c6 100644
--- a/icu4c/source/test/intltest/numfmtst.cpp
+++ b/icu4c/source/test/intltest/numfmtst.cpp
@@ -18,6 +18,7 @@
#include "unicode/ucurr.h"
#include "unicode/ustring.h"
#include "unicode/measfmt.h"
+#include "unicode/curramt.h"
#include "digitlst.h"
#include "textfile.h"
#include "tokiter.h"
@@ -1569,8 +1570,9 @@ static void parseCurrencyAmount(const UnicodeString& str,
int32_t i = str.indexOf(delim);
str.extractBetween(0, i, num);
str.extractBetween(i+1, INT32_MAX, cur);
- fmt.parse(num, result, ec);
- result.setCurrency(cur.getTerminatedBuffer());
+ Formattable n;
+ fmt.parse(num, n, ec);
+ result.adoptObject(new CurrencyAmount(n, cur.getTerminatedBuffer(), ec));
}
void NumberFormatTest::TestCases() {