ICU-2825 add currency attribute

X-SVN-Rev: 14977
This commit is contained in:
Alan Liu 2004-04-15 06:19:55 +00:00
parent 1b599b02f2
commit 894fb68198
2 changed files with 132 additions and 21 deletions

View file

@ -18,6 +18,7 @@
#if !UCONFIG_NO_FORMATTING
#include "unicode/fmtable.h"
#include "unicode/ustring.h"
#include "cmemory.h"
// *****************************************************************************
@ -44,7 +45,9 @@ inline void setError(UErrorCode& ec, UErrorCode err) {
Formattable::Formattable()
: UObject(), fType(kLong)
{
fBogus.setToBogus();
fValue.fInt64 = 0;
fCurrency[0] = 0;
}
// -------------------------------------
@ -55,6 +58,7 @@ Formattable::Formattable(UDate date, ISDATE /*isDate*/)
{
fBogus.setToBogus();
fValue.fDate = date;
fCurrency[0] = 0;
}
// -------------------------------------
@ -65,6 +69,7 @@ Formattable::Formattable(double value)
{
fBogus.setToBogus();
fValue.fDouble = value;
fCurrency[0] = 0;
}
// -------------------------------------
@ -75,6 +80,7 @@ Formattable::Formattable(int32_t value)
{
fBogus.setToBogus();
fValue.fInt64 = value;
fCurrency[0] = 0;
}
// -------------------------------------
@ -85,6 +91,25 @@ Formattable::Formattable(int64_t value)
{
fBogus.setToBogus();
fValue.fInt64 = value;
fCurrency[0] = 0;
}
Formattable::Formattable(double n, const UChar* currency) : UObject(), fType(kDouble) {
fBogus.setToBogus();
fValue.fDouble = n;
setCurrency(currency);
}
Formattable::Formattable(int32_t n, const UChar* currency) : UObject(), fType(kLong) {
fBogus.setToBogus();
fValue.fInt64 = n;
setCurrency(currency);
}
Formattable::Formattable(int64_t n, const UChar* currency) : UObject(), fType(kInt64) {
fBogus.setToBogus();
fValue.fInt64 = n;
setCurrency(currency);
}
// -------------------------------------
@ -95,6 +120,7 @@ Formattable::Formattable(const char* stringToCopy)
{
fBogus.setToBogus();
fValue.fString = new UnicodeString(stringToCopy);
fCurrency[0] = 0;
}
// -------------------------------------
@ -105,6 +131,7 @@ Formattable::Formattable(const UnicodeString& stringToCopy)
{
fBogus.setToBogus();
fValue.fString = new UnicodeString(stringToCopy);
fCurrency[0] = 0;
}
// -------------------------------------
@ -116,6 +143,7 @@ Formattable::Formattable(UnicodeString* stringToAdopt)
{
fBogus.setToBogus();
fValue.fString = stringToAdopt;
fCurrency[0] = 0;
}
// -------------------------------------
@ -126,6 +154,7 @@ Formattable::Formattable(const Formattable* arrayToCopy, int32_t count)
fBogus.setToBogus();
fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count);
fValue.fArrayAndCount.fCount = count;
fCurrency[0] = 0;
}
// -------------------------------------
@ -177,6 +206,8 @@ Formattable::operator=(const Formattable& source)
fValue.fDate = source.fValue.fDate;
break;
}
u_strcpy(fCurrency, source.fCurrency);
}
return *this;
}
@ -186,33 +217,47 @@ Formattable::operator=(const Formattable& source)
UBool
Formattable::operator==(const Formattable& that) const
{
// Checks class ID.
if (this == &that) return TRUE;
// Returns FALSE if the data types are different.
if (fType != that.fType) return FALSE;
// Compares the actual data values.
UBool equal = TRUE;
switch (fType) {
case kDate:
return fValue.fDate == that.fValue.fDate;
equal = (fValue.fDate == that.fValue.fDate);
break;
case kDouble:
return fValue.fDouble == that.fValue.fDouble;
equal = (fValue.fDouble == that.fValue.fDouble);
break;
case kLong:
case kInt64:
return fValue.fInt64 == that.fValue.fInt64;
case kInt64:
equal = (fValue.fInt64 == that.fValue.fInt64);
break;
case kString:
return *(fValue.fString) == *(that.fValue.fString);
equal = (*(fValue.fString) == *(that.fValue.fString));
break;
case kArray:
if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount)
return FALSE;
if (fValue.fArrayAndCount.fCount != that.fValue.fArrayAndCount.fCount) {
equal = FALSE;
break;
}
// Checks each element for equality.
for (int32_t i=0; i<fValue.fArrayAndCount.fCount; ++i)
if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i])
return FALSE;
for (int32_t i=0; i<fValue.fArrayAndCount.fCount; ++i) {
if (fValue.fArrayAndCount.fArray[i] != that.fValue.fArrayAndCount.fArray[i]) {
equal = FALSE;
break;
}
}
break;
}
return TRUE;
if (equal) {
equal = (u_strcmp(fCurrency, that.fCurrency) == 0);
}
return equal;
}
// -------------------------------------
@ -338,6 +383,11 @@ Formattable::getDouble(UErrorCode& status) const
}
}
const UChar*
Formattable::getCurrency() const {
return (fCurrency[0] != 0) ? fCurrency : NULL;
}
// -------------------------------------
// Sets the value to a double value d.
@ -428,6 +478,15 @@ Formattable::adoptArray(Formattable* array, int32_t count)
fValue.fArrayAndCount.fCount = count;
}
void
Formattable::setCurrency(const UChar* currency) {
fCurrency[0] = 0;
if (currency != NULL) {
uprv_memcpy(&fCurrency[0], currency, 3*sizeof(fCurrency[0]));
fCurrency[3] = 0;
}
}
// -------------------------------------
UnicodeString&
Formattable::getString(UnicodeString& result, UErrorCode& status) const

View file

@ -27,18 +27,28 @@ U_NAMESPACE_BEGIN
* its subclasses for formatting. Formattable is a thin wrapper
* class which interconverts between the primitive numeric types
* (double, long, etc.) as well as UDate and UnicodeString.
* <P>
* Note that this is fundamentally different from the Java behavior, since
*
* <p>Formattable objects may also contain a currency in the form of a
* 3-letter ISO 4217 code. Any Formattable object may have an
* associated currency, although this is intended for use with numeric
* objects. A numeric Formattable object with a currency is a
* "currency amount", and is handled specially by NumberFormat.
* During formatting, the currency of the object is used to determine
* the currency display name or symbol, the rounding, and the fraction
* digit counts. During parsing, if a valid currency is parsed, it is
* stored in the Formattable result.
*
* <p>Note that this is fundamentally different from the Java behavior, since
* in this case the various formattable objects do not occupy a hierarchy,
* but are all wrapped within this one class. Formattable encapsulates all
* the polymorphism in itself.
* <P>
* It would be easy to change this so that Formattable was an abstract base
*
* <p>It would be easy to change this so that Formattable was an abstract base
* class of a genuine hierarchy, and that would clean up the code that
* currently must explicitly check for type, but that seems like overkill at
* this point.
*
* The Formattable class is not suitable for subclassing.
* <p>The Formattable class is not suitable for subclassing.
*/
class U_I18N_API Formattable : public UObject {
public:
@ -88,6 +98,30 @@ 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.
@ -365,6 +399,15 @@ public:
* @stable ICU 2.0
*/
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
* @draft ICU 3.0
*/
const UChar* getCurrency() const;
/**
* Sets the double value of this object and changes the type to
@ -429,7 +472,18 @@ public:
* @stable ICU 2.0
*/
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.
* @draft ICU 3.0
*/
void setCurrency(const UChar* currency);
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
@ -470,9 +524,6 @@ private:
UnicodeString* getBogus() const;
// Note: For now, we do not handle unsigned long and unsigned
// double types. Smaller unsigned types, such as unsigned
// short, can fit within a long.
union {
UnicodeString* fString;
double fDouble;
@ -486,6 +537,7 @@ private:
} fValue;
Type fType;
UChar fCurrency[4];
UnicodeString fBogus; // Bogus string when it's needed.
};