ICU-2825 add Measure, MeasureUnit, CurrencyUnit, and CurrencyAmount classes, and operate through them
X-SVN-Rev: 15059
This commit is contained in:
parent
540823fffa
commit
1db13e2b86
@ -23,7 +23,7 @@
|
||||
|
||||
/* Uncomment the following line to disable renaming on platforms
|
||||
that do not use Autoconf. */
|
||||
/* #define U_DISABLE_RENAMING 1 */
|
||||
#define U_DISABLE_RENAMING 1
|
||||
|
||||
#if !U_DISABLE_RENAMING
|
||||
|
||||
|
@ -72,7 +72,7 @@ cpdtrans.o rbt.o rbt_data.o rbt_pars.o rbt_rule.o rbt_set.o \
|
||||
nultrans.o remtrans.o titletrn.o tolowtrn.o toupptrn.o anytrans.o \
|
||||
name2uni.o uni2name.o nortrans.o quant.o transreg.o \
|
||||
regexcmp.o rematch.o repattrn.o regexst.o uregex.o ulocdata.o \
|
||||
measfmt.o currfmt.o
|
||||
measfmt.o currfmt.o curramt.o currunit.o measure.o
|
||||
|
||||
|
||||
STATIC_OBJECTS = $(OBJECTS:.o=.$(STATIC_O))
|
||||
|
50
icu4c/source/i18n/curramt.cpp
Normal file
50
icu4c/source/i18n/curramt.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
* Created: April 26, 2004
|
||||
* Since: ICU 3.0
|
||||
**********************************************************************
|
||||
*/
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/curramt.h"
|
||||
#include "unicode/currunit.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
CurrencyAmount::CurrencyAmount(const Formattable& amount, const UChar* isoCode,
|
||||
UErrorCode& ec) :
|
||||
Measure(amount, new CurrencyUnit(isoCode, ec), ec) {
|
||||
}
|
||||
|
||||
CurrencyAmount::CurrencyAmount(double amount, const UChar* isoCode,
|
||||
UErrorCode& ec) :
|
||||
Measure(Formattable(amount), new CurrencyUnit(isoCode, ec), ec) {
|
||||
}
|
||||
|
||||
CurrencyAmount::CurrencyAmount(const CurrencyAmount& other) :
|
||||
Measure(other) {
|
||||
}
|
||||
|
||||
CurrencyAmount& CurrencyAmount::operator=(const CurrencyAmount& other) {
|
||||
Measure::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
UObject* CurrencyAmount::clone() const {
|
||||
return new CurrencyAmount(*this);
|
||||
}
|
||||
|
||||
CurrencyAmount::~CurrencyAmount() {
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CurrencyAmount)
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif // !UCONFIG_NO_FORMATTING
|
59
icu4c/source/i18n/currunit.cpp
Normal file
59
icu4c/source/i18n/currunit.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
* Created: April 26, 2004
|
||||
* Since: ICU 3.0
|
||||
**********************************************************************
|
||||
*/
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/currunit.h"
|
||||
#include "unicode/ustring.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
CurrencyUnit::CurrencyUnit(const UChar* _isoCode, UErrorCode& ec) {
|
||||
*isoCode = 0;
|
||||
if (U_SUCCESS(ec)) {
|
||||
if (_isoCode && u_strlen(_isoCode)==3) {
|
||||
u_strcpy(isoCode, _isoCode);
|
||||
} else {
|
||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CurrencyUnit::CurrencyUnit(const CurrencyUnit& other) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
CurrencyUnit& CurrencyUnit::operator=(const CurrencyUnit& other) {
|
||||
if (this != &other) {
|
||||
u_strcpy(isoCode, other.isoCode);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
UObject* CurrencyUnit::clone() const {
|
||||
return new CurrencyUnit(*this);
|
||||
}
|
||||
|
||||
CurrencyUnit::~CurrencyUnit() {
|
||||
}
|
||||
|
||||
UBool CurrencyUnit::operator==(const UObject& other) const {
|
||||
const CurrencyUnit& c = (const CurrencyUnit&) other;
|
||||
return other.getDynamicClassID() == CurrencyUnit::getStaticClassID() &&
|
||||
u_strcmp(isoCode, c.isoCode) == 0;
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CurrencyUnit)
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif // !UCONFIG_NO_FORMATTING
|
@ -48,6 +48,7 @@
|
||||
#include "unicode/dcfmtsym.h"
|
||||
#include "unicode/resbund.h"
|
||||
#include "unicode/uchar.h"
|
||||
#include "unicode/curramt.h"
|
||||
#include "ucurrimp.h"
|
||||
#include "uprops.h"
|
||||
#include "digitlst.h"
|
||||
@ -1253,59 +1254,58 @@ void DecimalFormat::parse(const UnicodeString& text,
|
||||
return;
|
||||
}
|
||||
|
||||
if (parseCurrency) {
|
||||
result.setCurrency(curbuf);
|
||||
}
|
||||
|
||||
// Handle infinity
|
||||
if (status[fgStatusInfinite]) {
|
||||
double inf = uprv_getInfinity();
|
||||
result.setDouble(digits.fIsPositive ? inf : -inf);
|
||||
return;
|
||||
}
|
||||
|
||||
// Do as much of the multiplier conversion as possible without
|
||||
// losing accuracy.
|
||||
int32_t mult = fMultiplier; // Don't modify this.multiplier
|
||||
while (mult % 10 == 0) {
|
||||
mult /= 10;
|
||||
--digits.fDecimalAt;
|
||||
}
|
||||
|
||||
// Handle integral values. We want to return the most
|
||||
// parsimonious type that will accommodate all of the result's
|
||||
// precision. We therefore only return a long if the result fits
|
||||
// entirely within a long (taking into account the multiplier) --
|
||||
// otherwise we fall through and return a double. When more
|
||||
// numeric types are supported by Formattable (e.g., 64-bit
|
||||
// integers, bignums) we will extend this logic to include them.
|
||||
if (digits.fitsIntoLong(isParseIntegerOnly())) {
|
||||
int32_t n = digits.getLong();
|
||||
if (n % mult == 0) {
|
||||
result.setLong(n / mult);
|
||||
return;
|
||||
}
|
||||
else { // else handle the remainder
|
||||
result.setDouble(((double)n) / mult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (digits.fitsIntoInt64(isParseIntegerOnly())) {
|
||||
int64_t n = digits.getInt64();
|
||||
if (n % mult == 0) {
|
||||
result.setInt64(n / mult);
|
||||
return;
|
||||
}
|
||||
else { // else handle the remainder
|
||||
result.setDouble(((double)n) / mult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Handle non-integral or very large values
|
||||
// Dividing by one is okay and not that costly.
|
||||
result.setDouble(digits.getDouble() / mult);
|
||||
return;
|
||||
// Do as much of the multiplier conversion as possible without
|
||||
// losing accuracy.
|
||||
int32_t mult = fMultiplier; // Don't modify this.multiplier
|
||||
while (mult % 10 == 0) {
|
||||
mult /= 10;
|
||||
--digits.fDecimalAt;
|
||||
}
|
||||
|
||||
// Handle integral values. We want to return the most
|
||||
// parsimonious type that will accommodate all of the result's
|
||||
// precision. We therefore only return a long if the result fits
|
||||
// entirely within a long (taking into account the multiplier) --
|
||||
// otherwise we fall through and return a double. When more
|
||||
// numeric types are supported by Formattable (e.g., 64-bit
|
||||
// integers, bignums) we will extend this logic to include them.
|
||||
if (digits.fitsIntoLong(isParseIntegerOnly())) {
|
||||
int32_t n = digits.getLong();
|
||||
if (n % mult == 0) {
|
||||
result.setLong(n / mult);
|
||||
}
|
||||
else { // else handle the remainder
|
||||
result.setDouble(((double)n) / mult);
|
||||
}
|
||||
}
|
||||
else if (digits.fitsIntoInt64(isParseIntegerOnly())) {
|
||||
int64_t n = digits.getInt64();
|
||||
if (n % mult == 0) {
|
||||
result.setInt64(n / mult);
|
||||
}
|
||||
else { // else handle the remainder
|
||||
result.setDouble(((double)n) / mult);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Handle non-integral or very large values
|
||||
// Dividing by one is okay and not that costly.
|
||||
result.setDouble(digits.getDouble() / mult);
|
||||
}
|
||||
}
|
||||
|
||||
if (parseCurrency) {
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
Formattable n(result);
|
||||
result.adoptObject(new CurrencyAmount(n, curbuf, ec));
|
||||
U_ASSERT(U_SUCCESS(ec)); // should always succeed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "unicode/fmtable.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/measure.h"
|
||||
#include "unicode/curramt.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
// *****************************************************************************
|
||||
@ -29,6 +31,38 @@ U_NAMESPACE_BEGIN
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable)
|
||||
|
||||
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
|
||||
|
||||
// NOTE: As of 3.0, there are limitations to the UObject API. It does
|
||||
// not (yet) support cloning, operator=, nor operator==. RTTI is also
|
||||
// restricted in that subtype testing is not (yet) implemented. To
|
||||
// work around this, I implement some simple inlines here. Later
|
||||
// these can be modified or removed. [alan]
|
||||
|
||||
// NOTE: These inlines assume that all fObjects are in fact instances
|
||||
// of the Measure class, which is true as of 3.0. [alan]
|
||||
|
||||
// Return TRUE if *a == *b.
|
||||
inline UBool objectEquals(const UObject* a, const UObject* b) {
|
||||
// LATER: return *a == *b;
|
||||
return *((const Measure*) a) == *((const Measure*) b);
|
||||
}
|
||||
|
||||
// Return a clone of *a.
|
||||
inline UObject* objectClone(const UObject* a) {
|
||||
// LATER: return a->clone();
|
||||
return ((const Measure*) a)->clone();
|
||||
}
|
||||
|
||||
// Return TRUE if *a is an instance of Measure.
|
||||
inline UBool instanceOfMeasure(const UObject* a) {
|
||||
// LATER: return a->instanceof(Measure::getStaticClassID());
|
||||
return a->getDynamicClassID() ==
|
||||
CurrencyAmount::getStaticClassID();
|
||||
}
|
||||
|
||||
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
|
||||
|
||||
/**
|
||||
* Set 'ec' to 'err' only if 'ec' is not already set to a failing UErrorCode.
|
||||
*/
|
||||
@ -47,7 +81,6 @@ Formattable::Formattable()
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fInt64 = 0;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -58,7 +91,6 @@ Formattable::Formattable(UDate date, ISDATE /*isDate*/)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fDate = date;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -69,7 +101,6 @@ Formattable::Formattable(double value)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fDouble = value;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -80,7 +111,6 @@ Formattable::Formattable(int32_t value)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fInt64 = value;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -91,25 +121,6 @@ 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);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -120,7 +131,6 @@ Formattable::Formattable(const char* stringToCopy)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fString = new UnicodeString(stringToCopy);
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -131,7 +141,6 @@ Formattable::Formattable(const UnicodeString& stringToCopy)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fString = new UnicodeString(stringToCopy);
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -143,7 +152,13 @@ Formattable::Formattable(UnicodeString* stringToAdopt)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fString = stringToAdopt;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
Formattable::Formattable(UObject* objectToAdopt)
|
||||
: UObject(), fType(kObject)
|
||||
{
|
||||
fBogus.setToBogus();
|
||||
fValue.fObject = objectToAdopt;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -154,7 +169,6 @@ Formattable::Formattable(const Formattable* arrayToCopy, int32_t count)
|
||||
fBogus.setToBogus();
|
||||
fValue.fArrayAndCount.fArray = createArrayCopy(arrayToCopy, count);
|
||||
fValue.fArrayAndCount.fCount = count;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -205,9 +219,10 @@ Formattable::operator=(const Formattable& source)
|
||||
// Sets the Date value.
|
||||
fValue.fDate = source.fValue.fDate;
|
||||
break;
|
||||
case kObject:
|
||||
fValue.fObject = objectClone(source.fValue.fObject);
|
||||
break;
|
||||
}
|
||||
|
||||
u_strcpy(fCurrency, source.fCurrency);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -251,10 +266,9 @@ Formattable::operator==(const Formattable& that) const
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (equal) {
|
||||
equal = (u_strcmp(fCurrency, that.fCurrency) == 0);
|
||||
case kObject:
|
||||
equal = objectEquals(fValue.fObject, that.fValue.fObject);
|
||||
break;
|
||||
}
|
||||
|
||||
return equal;
|
||||
@ -279,6 +293,9 @@ void Formattable::dispose()
|
||||
case kArray:
|
||||
delete[] fValue.fArrayAndCount.fArray;
|
||||
break;
|
||||
case kObject:
|
||||
delete fValue.fObject;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -297,6 +314,18 @@ Formattable::getType() const
|
||||
return fType;
|
||||
}
|
||||
|
||||
UBool
|
||||
Formattable::isNumeric() const {
|
||||
switch (fType) {
|
||||
case kDouble:
|
||||
case kLong:
|
||||
case kInt64:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
int32_t
|
||||
//Formattable::getLong(UErrorCode* status) const
|
||||
@ -329,6 +358,12 @@ Formattable::getLong(UErrorCode& status) const
|
||||
} else {
|
||||
return (int32_t)fValue.fDouble; // loses fraction
|
||||
}
|
||||
case Formattable::kObject:
|
||||
// TODO Later replace this with instanceof call
|
||||
if (instanceOfMeasure(fValue.fObject)) {
|
||||
return ((const Measure*) fValue.fObject)->
|
||||
getNumber().getLong(status);
|
||||
}
|
||||
default:
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
return 0;
|
||||
@ -357,6 +392,12 @@ Formattable::getInt64(UErrorCode& status) const
|
||||
} else {
|
||||
return (int64_t)fValue.fDouble;
|
||||
}
|
||||
case Formattable::kObject:
|
||||
// TODO Later replace this with instanceof call
|
||||
if (instanceOfMeasure(fValue.fObject)) {
|
||||
return ((const Measure*) fValue.fObject)->
|
||||
getNumber().getInt64(status);
|
||||
}
|
||||
default:
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
return 0;
|
||||
@ -377,15 +418,21 @@ Formattable::getDouble(UErrorCode& status) const
|
||||
return (double)fValue.fInt64;
|
||||
case Formattable::kDouble:
|
||||
return fValue.fDouble;
|
||||
case Formattable::kObject:
|
||||
// TODO Later replace this with instanceof call
|
||||
if (instanceOfMeasure(fValue.fObject)) {
|
||||
return ((const Measure*) fValue.fObject)->
|
||||
getNumber().getDouble(status);
|
||||
}
|
||||
default:
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const UChar*
|
||||
Formattable::getCurrency() const {
|
||||
return (fCurrency[0] != 0) ? fCurrency : NULL;
|
||||
const UObject*
|
||||
Formattable::getObject() const {
|
||||
return (fType == kObject) ? fValue.fObject : NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -479,12 +526,10 @@ Formattable::adoptArray(Formattable* array, int32_t 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;
|
||||
}
|
||||
Formattable::adoptObject(UObject* objectToAdopt) {
|
||||
dispose();
|
||||
fType = kObject;
|
||||
fValue.fObject = objectToAdopt;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
@ -457,12 +457,38 @@
|
||||
Outputs="..\..\include\unicode\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\curramt.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unicode\curramt.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\unicode"
|
||||
Outputs="..\..\include\unicode\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\currfmt.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\currfmt.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\currunit.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unicode\currunit.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\unicode"
|
||||
Outputs="..\..\include\unicode\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\datefmt.cpp">
|
||||
</File>
|
||||
@ -673,11 +699,36 @@
|
||||
RelativePath=".\unicode\measfmt.h">
|
||||
<FileConfiguration
|
||||
Name="Release|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\unicode
|
||||
"
|
||||
Outputs="..\..\include\unicode\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\unicode
|
||||
"
|
||||
Outputs="..\..\include\unicode\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unicode\measunit.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
CommandLine="copy "$(InputPath)" ..\..\include\unicode"
|
||||
Outputs="..\..\include\unicode\$(InputFileName)"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\measure.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\unicode\measure.h">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32">
|
||||
<Tool
|
||||
|
63
icu4c/source/i18n/measure.cpp
Normal file
63
icu4c/source/i18n/measure.cpp
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
* Created: April 26, 2004
|
||||
* Since: ICU 3.0
|
||||
**********************************************************************
|
||||
*/
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/measure.h"
|
||||
#include "unicode/measunit.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
Measure::Measure(const Formattable& _number, MeasureUnit* adoptedUnit,
|
||||
UErrorCode& ec) :
|
||||
number(_number), unit(adoptedUnit) {
|
||||
if (U_SUCCESS(ec) &&
|
||||
(!number.isNumeric() || adoptedUnit == 0)) {
|
||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
Measure::Measure(const Measure& other) :
|
||||
unit(0) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Measure& Measure::operator=(const Measure& other) {
|
||||
if (this != &other) {
|
||||
delete unit;
|
||||
number = other.number;
|
||||
unit = (MeasureUnit*) other.unit->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
|
@ -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;
|
||||
|
124
icu4c/source/i18n/unicode/curramt.h
Normal file
124
icu4c/source/i18n/unicode/curramt.h
Normal file
@ -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__
|
112
icu4c/source/i18n/unicode/currunit.h
Normal file
112
icu4c/source/i18n/unicode/currunit.h
Normal file
@ -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__
|
@ -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.
|
||||
};
|
||||
|
||||
|
65
icu4c/source/i18n/unicode/measunit.h
Normal file
65
icu4c/source/i18n/unicode/measunit.h
Normal file
@ -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.
|
||||
*
|
||||
* <p>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__
|
125
icu4c/source/i18n/unicode/measure.h
Normal file
125
icu4c/source/i18n/unicode/measure.h
Normal file
@ -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.
|
||||
*
|
||||
* <p>Measure objects are parsed and formatted by subclasses of
|
||||
* MeasureFormat.
|
||||
*
|
||||
* <p>Measure objects are immutable.
|
||||
*
|
||||
* <p>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__
|
@ -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);
|
||||
}
|
||||
|
@ -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<n; ++i) {
|
||||
if (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
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user