ICU-10640 Add C++ MeasureFormat API.
X-SVN-Rev: 35069
This commit is contained in:
parent
d8b2004576
commit
0a42d4959f
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -77,6 +77,7 @@ icu4c/source/extra/uconv/uconv.vcxproj -text
|
||||
icu4c/source/extra/uconv/uconv.vcxproj.filters -text
|
||||
icu4c/source/i18n/i18n.vcxproj -text
|
||||
icu4c/source/i18n/i18n.vcxproj.filters -text
|
||||
icu4c/source/i18n/measunit.cpp -text
|
||||
icu4c/source/i18n/quantityformatter.cpp -text
|
||||
icu4c/source/i18n/quantityformatter.h -text
|
||||
icu4c/source/io/io.vcxproj -text
|
||||
@ -146,6 +147,7 @@ icu4c/source/test/cintltst/cintltst.vcxproj -text
|
||||
icu4c/source/test/cintltst/cintltst.vcxproj.filters -text
|
||||
icu4c/source/test/intltest/intltest.vcxproj -text
|
||||
icu4c/source/test/intltest/intltest.vcxproj.filters -text
|
||||
icu4c/source/test/intltest/measfmttest.cpp -text
|
||||
icu4c/source/test/intltest/simplepatternformattertest.cpp -text
|
||||
icu4c/source/test/iotest/iotest.vcxproj -text
|
||||
icu4c/source/test/iotest/iotest.vcxproj.filters -text
|
||||
|
@ -253,6 +253,10 @@ ListFormatter::~ListFormatter() {
|
||||
|
||||
/**
|
||||
* Joins first and second using the pattern pat.
|
||||
* On entry offset is an offset into first or -1 if offset unspecified.
|
||||
* On exit offset is offset of second in result if recordOffset was set
|
||||
* Otherwise if it was >=0 it is set to point into result where it used
|
||||
* to point into first.
|
||||
*/
|
||||
static void joinStrings(
|
||||
const SimplePatternFormatter& pat,
|
||||
@ -260,7 +264,7 @@ static void joinStrings(
|
||||
const UnicodeString& second,
|
||||
UnicodeString &result,
|
||||
UBool recordOffset,
|
||||
int32_t offset,
|
||||
int32_t &offset,
|
||||
UErrorCode& errorCode) {
|
||||
if (U_FAILURE(errorCode)) {
|
||||
return;
|
||||
@ -375,7 +379,9 @@ UnicodeString& ListFormatter::format(
|
||||
offset,
|
||||
errorCode);
|
||||
if (U_SUCCESS(errorCode)) {
|
||||
offset += appendTo.length();
|
||||
if (offset >= 0) {
|
||||
offset += appendTo.length();
|
||||
}
|
||||
appendTo += temp[npos];
|
||||
}
|
||||
return appendTo;
|
||||
|
@ -87,7 +87,7 @@ uspoof.o uspoof_impl.o uspoof_build.o uspoof_conf.o uspoof_wsconf.o decfmtst.o s
|
||||
ztrans.o zrule.o vzone.o fphdlimp.o fpositer.o locdspnm.o \
|
||||
decNumber.o decContext.o alphaindex.o tznames.o tznames_impl.o tzgnames.o \
|
||||
tzfmt.o compactdecimalformat.o gender.o region.o scriptset.o identifier_info.o \
|
||||
uregion.o reldatefmt.o quantityformatter.o
|
||||
uregion.o reldatefmt.o quantityformatter.o measunit.o
|
||||
|
||||
## Header files to install
|
||||
HEADERS = $(srcdir)/unicode/*.h
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2012 International Business Machines
|
||||
* Copyright (c) 2004-2014 International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -21,7 +21,7 @@
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
CurrencyFormat::CurrencyFormat(const Locale& locale, UErrorCode& ec) :
|
||||
fmt(NULL)
|
||||
MeasureFormat(locale, UMEASFMT_WIDTH_WIDE, ec), fmt(NULL)
|
||||
{
|
||||
fmt = NumberFormat::createCurrencyInstance(locale, ec);
|
||||
}
|
||||
@ -36,17 +36,6 @@ CurrencyFormat::~CurrencyFormat() {
|
||||
delete fmt;
|
||||
}
|
||||
|
||||
UBool CurrencyFormat::operator==(const Format& other) const {
|
||||
if (this == &other) {
|
||||
return TRUE;
|
||||
}
|
||||
if (typeid(*this) != typeid(other)) {
|
||||
return FALSE;
|
||||
}
|
||||
const CurrencyFormat* c = (const CurrencyFormat*) &other;
|
||||
return *fmt == *c->fmt;
|
||||
}
|
||||
|
||||
Format* CurrencyFormat::clone() const {
|
||||
return new CurrencyFormat(*this);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2010, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -52,11 +52,6 @@ class CurrencyFormat : public MeasureFormat {
|
||||
*/
|
||||
virtual ~CurrencyFormat();
|
||||
|
||||
/**
|
||||
* Override Format API.
|
||||
*/
|
||||
virtual UBool operator==(const Format& other) const;
|
||||
|
||||
/**
|
||||
* Override Format API.
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2012, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -24,6 +24,9 @@ CurrencyUnit::CurrencyUnit(const UChar* _isoCode, UErrorCode& ec) {
|
||||
if (U_SUCCESS(ec)) {
|
||||
if (_isoCode && u_strlen(_isoCode)==3) {
|
||||
u_strcpy(isoCode, _isoCode);
|
||||
char simpleIsoCode[4];
|
||||
u_UCharsToChars(isoCode, simpleIsoCode, 4);
|
||||
initCurrency(simpleIsoCode);
|
||||
} else {
|
||||
ec = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
}
|
||||
@ -32,13 +35,15 @@ CurrencyUnit::CurrencyUnit(const UChar* _isoCode, UErrorCode& ec) {
|
||||
|
||||
CurrencyUnit::CurrencyUnit(const CurrencyUnit& other) :
|
||||
MeasureUnit(other) {
|
||||
*this = other;
|
||||
u_strcpy(isoCode, other.isoCode);
|
||||
}
|
||||
|
||||
CurrencyUnit& CurrencyUnit::operator=(const CurrencyUnit& other) {
|
||||
if (this != &other) {
|
||||
u_strcpy(isoCode, other.isoCode);
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
MeasureUnit::operator=(other);
|
||||
u_strcpy(isoCode, other.isoCode);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -49,12 +54,6 @@ UObject* CurrencyUnit::clone() const {
|
||||
CurrencyUnit::~CurrencyUnit() {
|
||||
}
|
||||
|
||||
UBool CurrencyUnit::operator==(const UObject& other) const {
|
||||
const CurrencyUnit& c = (const CurrencyUnit&) other;
|
||||
return typeid(*this) == typeid(other) &&
|
||||
u_strcmp(isoCode, c.isoCode) == 0;
|
||||
}
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CurrencyUnit)
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2011, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -13,13 +13,772 @@
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/measfmt.h"
|
||||
#include "unicode/numfmt.h"
|
||||
#include "currfmt.h"
|
||||
#include "unicode/localpointer.h"
|
||||
#include "quantityformatter.h"
|
||||
#include "unicode/plurrule.h"
|
||||
#include "unicode/decimfmt.h"
|
||||
#include "lrucache.h"
|
||||
#include "uresimp.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "cstring.h"
|
||||
#include "mutex.h"
|
||||
#include "ucln_in.h"
|
||||
#include "unicode/listformatter.h"
|
||||
#include "charstr.h"
|
||||
#include "unicode/putil.h"
|
||||
#include "unicode/smpdtfmt.h"
|
||||
|
||||
#include "sharedptr.h"
|
||||
|
||||
#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
|
||||
#define MEAS_UNIT_COUNT 46
|
||||
|
||||
static icu::LRUCache *gCache = NULL;
|
||||
static UMutex gCacheMutex = U_MUTEX_INITIALIZER;
|
||||
static icu::UInitOnce gCacheInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV measfmt_cleanup() {
|
||||
gCacheInitOnce.reset();
|
||||
if (gCache) {
|
||||
delete gCache;
|
||||
gCache = NULL;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
MeasureFormat::MeasureFormat() {}
|
||||
class UnitFormatters : public UMemory {
|
||||
public:
|
||||
UnitFormatters() { }
|
||||
QuantityFormatter formatters[MEAS_UNIT_COUNT][UMEASFMT_WIDTH_NARROW + 1];
|
||||
private:
|
||||
UnitFormatters(const UnitFormatters &other);
|
||||
UnitFormatters &operator=(const UnitFormatters &other);
|
||||
};
|
||||
|
||||
MeasureFormat::~MeasureFormat() {}
|
||||
class NumericDateFormatters : public UMemory {
|
||||
public:
|
||||
SimpleDateFormat hourMinute;
|
||||
SimpleDateFormat minuteSecond;
|
||||
SimpleDateFormat hourMinuteSecond;
|
||||
NumericDateFormatters(
|
||||
const UnicodeString &hm,
|
||||
const UnicodeString &ms,
|
||||
const UnicodeString &hms,
|
||||
UErrorCode &status) :
|
||||
hourMinute(hm, status),
|
||||
minuteSecond(ms, status),
|
||||
hourMinuteSecond(hms, status) {
|
||||
const TimeZone *gmt = TimeZone::getGMT();
|
||||
hourMinute.setTimeZone(*gmt);
|
||||
minuteSecond.setTimeZone(*gmt);
|
||||
hourMinuteSecond.setTimeZone(*gmt);
|
||||
}
|
||||
private:
|
||||
NumericDateFormatters(const NumericDateFormatters &other);
|
||||
NumericDateFormatters &operator=(const NumericDateFormatters &other);
|
||||
};
|
||||
|
||||
class MeasureFormatData : public SharedObject {
|
||||
public:
|
||||
SharedPtr<UnitFormatters> unitFormatters;
|
||||
SharedPtr<PluralRules> pluralRules;
|
||||
SharedPtr<NumberFormat> numberFormat;
|
||||
SharedPtr<NumberFormat> currencyFormats[UMEASFMT_WIDTH_NARROW + 1];
|
||||
SharedPtr<NumericDateFormatters> numericDateFormatters;
|
||||
virtual ~MeasureFormatData();
|
||||
private:
|
||||
MeasureFormatData &operator=(const MeasureFormatData& other);
|
||||
};
|
||||
|
||||
MeasureFormatData::~MeasureFormatData() {
|
||||
}
|
||||
|
||||
static int32_t widthToIndex(UMeasureFormatWidth width) {
|
||||
if (width > UMEASFMT_WIDTH_NARROW) {
|
||||
return UMEASFMT_WIDTH_NARROW;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
static UBool isCurrency(const MeasureUnit &unit) {
|
||||
return (uprv_strcmp(unit.getType(), "currency") == 0);
|
||||
}
|
||||
|
||||
static UBool getString(
|
||||
const UResourceBundle *resource,
|
||||
UnicodeString &result,
|
||||
UErrorCode &status) {
|
||||
int32_t len = 0;
|
||||
const UChar *resStr = ures_getString(resource, &len, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return FALSE;
|
||||
}
|
||||
result.setTo(TRUE, resStr, len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static UBool load(
|
||||
const UResourceBundle *resource,
|
||||
UnitFormatters &unitFormatters,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return FALSE;
|
||||
}
|
||||
static const char *widthPath[] = {"units", "unitsShort", "unitsNarrow"};
|
||||
MeasureUnit *units = NULL;
|
||||
int32_t unitCount = MeasureUnit::getAvailable(units, 0, status);
|
||||
while (status == U_BUFFER_OVERFLOW_ERROR) {
|
||||
status = U_ZERO_ERROR;
|
||||
delete [] units;
|
||||
units = new MeasureUnit[unitCount];
|
||||
if (units == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
unitCount = MeasureUnit::getAvailable(units, unitCount, status);
|
||||
}
|
||||
for (int32_t currentWidth = 0; currentWidth <= UMEASFMT_WIDTH_NARROW; ++currentWidth) {
|
||||
// Be sure status is clear since next resource bundle lookup may fail.
|
||||
if (U_FAILURE(status)) {
|
||||
delete [] units;
|
||||
return FALSE;
|
||||
}
|
||||
LocalUResourceBundlePointer widthBundle(
|
||||
ures_getByKeyWithFallback(
|
||||
resource, widthPath[currentWidth], NULL, &status));
|
||||
// We may not have data for all widths in all locales.
|
||||
if (status == U_MISSING_RESOURCE_ERROR) {
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
for (int32_t currentUnit = 0; currentUnit < unitCount; ++currentUnit) {
|
||||
// Be sure status is clear next lookup may fail.
|
||||
if (U_FAILURE(status)) {
|
||||
delete [] units;
|
||||
return FALSE;
|
||||
}
|
||||
if (isCurrency(units[currentUnit])) {
|
||||
continue;
|
||||
}
|
||||
CharString pathBuffer;
|
||||
pathBuffer.append(units[currentUnit].getType(), status)
|
||||
.append("/", status)
|
||||
.append(units[currentUnit].getSubtype(), status);
|
||||
LocalUResourceBundlePointer unitBundle(
|
||||
ures_getByKeyWithFallback(
|
||||
widthBundle.getAlias(),
|
||||
pathBuffer.data(),
|
||||
NULL,
|
||||
&status));
|
||||
// We may not have data for all units in all widths
|
||||
if (status == U_MISSING_RESOURCE_ERROR) {
|
||||
status = U_ZERO_ERROR;
|
||||
continue;
|
||||
}
|
||||
// We must have the unit bundle to proceed
|
||||
if (U_FAILURE(status)) {
|
||||
delete [] units;
|
||||
return FALSE;
|
||||
}
|
||||
int32_t size = ures_getSize(unitBundle.getAlias());
|
||||
for (int32_t plIndex = 0; plIndex < size; ++plIndex) {
|
||||
LocalUResourceBundlePointer pluralBundle(
|
||||
ures_getByIndex(
|
||||
unitBundle.getAlias(), plIndex, NULL, &status));
|
||||
if (U_FAILURE(status)) {
|
||||
delete [] units;
|
||||
return FALSE;
|
||||
}
|
||||
UnicodeString rawPattern;
|
||||
getString(pluralBundle.getAlias(), rawPattern, status);
|
||||
unitFormatters.formatters[units[currentUnit].getIndex()][currentWidth].add(
|
||||
ures_getKey(pluralBundle.getAlias()),
|
||||
rawPattern,
|
||||
status);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] units;
|
||||
return U_SUCCESS(status);
|
||||
}
|
||||
|
||||
static UnicodeString loadNumericDateFormatterPattern(
|
||||
const UResourceBundle *resource,
|
||||
const char *pattern,
|
||||
UErrorCode &status) {
|
||||
UnicodeString result;
|
||||
if (U_FAILURE(status)) {
|
||||
return result;
|
||||
}
|
||||
CharString chs;
|
||||
chs.append("durationUnits", status)
|
||||
.append("/", status).append(pattern, status);
|
||||
LocalUResourceBundlePointer patternBundle(
|
||||
ures_getByKeyWithFallback(
|
||||
resource,
|
||||
chs.data(),
|
||||
NULL,
|
||||
&status));
|
||||
if (U_FAILURE(status)) {
|
||||
return result;
|
||||
}
|
||||
getString(patternBundle.getAlias(), result, status);
|
||||
// Replace 'h' with 'H'
|
||||
int32_t len = result.length();
|
||||
UChar *buffer = result.getBuffer(len);
|
||||
for (int32_t i = 0; i < len; ++i) {
|
||||
if (buffer[i] == 0x68) { // 'h'
|
||||
buffer[i] = 0x48; // 'H'
|
||||
}
|
||||
}
|
||||
result.releaseBuffer(len);
|
||||
return result;
|
||||
}
|
||||
|
||||
static NumericDateFormatters *loadNumericDateFormatters(
|
||||
const UResourceBundle *resource,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
NumericDateFormatters *result = new NumericDateFormatters(
|
||||
loadNumericDateFormatterPattern(resource, "hm", status),
|
||||
loadNumericDateFormatterPattern(resource, "ms", status),
|
||||
loadNumericDateFormatterPattern(resource, "hms", status),
|
||||
status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete result;
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static SharedObject *U_CALLCONV createData(
|
||||
const char *localeId, UErrorCode &status) {
|
||||
LocalUResourceBundlePointer topLevel(ures_open(NULL, localeId, &status));
|
||||
static UNumberFormatStyle currencyStyles[] = {
|
||||
UNUM_CURRENCY_PLURAL, UNUM_CURRENCY_ISO, UNUM_CURRENCY};
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
LocalPointer<MeasureFormatData> result(new MeasureFormatData());
|
||||
LocalPointer<UnitFormatters> unitFormatters(new UnitFormatters());
|
||||
if (result.getAlias() == NULL
|
||||
|| unitFormatters.getAlias() == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
if (!load(
|
||||
topLevel.getAlias(),
|
||||
*unitFormatters,
|
||||
status)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!result->unitFormatters.reset(unitFormatters.orphan())) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LocalPointer<NumericDateFormatters> ndf(
|
||||
loadNumericDateFormatters(topLevel.getAlias(), status));
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!result->numericDateFormatters.reset(ndf.orphan())) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LocalPointer<PluralRules> pr(PluralRules::forLocale(localeId, status));
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!result->pluralRules.reset(pr.orphan())) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LocalPointer<NumberFormat> nf(
|
||||
NumberFormat::createInstance(localeId, status));
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!result->numberFormat.reset(nf.orphan())) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i <= UMEASFMT_WIDTH_NARROW; ++i) {
|
||||
LocalPointer<NumberFormat> cf(
|
||||
NumberFormat::createInstance(
|
||||
localeId, currencyStyles[i], status));
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!result->currencyFormats[i].reset(cf.orphan())) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return result.orphan();
|
||||
}
|
||||
|
||||
static void U_CALLCONV cacheInit(UErrorCode &status) {
|
||||
U_ASSERT(gCache == NULL);
|
||||
U_ASSERT(MeasureUnit::getIndexCount() == MEAS_UNIT_COUNT);
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_MEASFMT, measfmt_cleanup);
|
||||
gCache = new SimpleLRUCache(100, &createData, status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete gCache;
|
||||
gCache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void getFromCache(
|
||||
const char *locale,
|
||||
const MeasureFormatData *&ptr,
|
||||
UErrorCode &status) {
|
||||
umtx_initOnce(gCacheInitOnce, &cacheInit, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
Mutex lock(&gCacheMutex);
|
||||
gCache->get(locale, ptr, status);
|
||||
}
|
||||
|
||||
static int32_t toHMS(
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
Formattable *hms,
|
||||
UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
int32_t result = 0;
|
||||
LocalPointer<MeasureUnit> hourUnit(MeasureUnit::createHour(status));
|
||||
LocalPointer<MeasureUnit> minuteUnit(MeasureUnit::createMinute(status));
|
||||
LocalPointer<MeasureUnit> secondUnit(MeasureUnit::createSecond(status));
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
int32_t count = 0;
|
||||
for (int32_t i = 0; i < measureCount; ++i) {
|
||||
if (measures[i].getUnit() == *hourUnit) {
|
||||
if ((result & 1) == 0) {
|
||||
++count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
hms[0] = measures[i].getNumber();
|
||||
result |= 1;
|
||||
} else if (measures[i].getUnit() == *minuteUnit) {
|
||||
if ((result & 2) == 0) {
|
||||
++count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
hms[1] = measures[i].getNumber();
|
||||
result |= 2;
|
||||
} else if (measures[i].getUnit() == *secondUnit) {
|
||||
if ((result & 4) == 0) {
|
||||
++count;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
hms[2] = measures[i].getNumber();
|
||||
result |= 4;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
MeasureFormat::MeasureFormat(
|
||||
const Locale &locale, UMeasureFormatWidth w, UErrorCode &status)
|
||||
: ptr(NULL), width(w) {
|
||||
initMeasureFormat(locale, w, status);
|
||||
}
|
||||
|
||||
MeasureFormat::MeasureFormat(
|
||||
const Locale &locale,
|
||||
UMeasureFormatWidth w,
|
||||
NumberFormat *nfToAdopt,
|
||||
UErrorCode &status)
|
||||
: ptr(NULL), width(w) {
|
||||
initMeasureFormat(locale, w, status);
|
||||
adoptNumberFormat(nfToAdopt, status);
|
||||
}
|
||||
|
||||
MeasureFormat::MeasureFormat(const MeasureFormat &other)
|
||||
: Format(other), ptr(other.ptr), width(other.width) {
|
||||
ptr->addRef();
|
||||
}
|
||||
|
||||
MeasureFormat &MeasureFormat::operator=(const MeasureFormat &other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
Format::operator=(other);
|
||||
SharedObject::copyPtr(other.ptr, ptr);
|
||||
width = other.width;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MeasureFormat::MeasureFormat() : ptr(NULL), width(UMEASFMT_WIDTH_WIDE) {
|
||||
}
|
||||
|
||||
MeasureFormat::~MeasureFormat() {
|
||||
if (ptr != NULL) {
|
||||
ptr->removeRef();
|
||||
}
|
||||
}
|
||||
|
||||
UBool MeasureFormat::operator==(const Format &other) const {
|
||||
const MeasureFormat *rhs = dynamic_cast<const MeasureFormat *>(&other);
|
||||
if (rhs == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
// Same objects are equivalent
|
||||
if (this == rhs) {
|
||||
return TRUE;
|
||||
}
|
||||
// differing widths aren't equivalent
|
||||
if (width != rhs->width) {
|
||||
return FALSE;
|
||||
}
|
||||
// Width the same, same shared data -> equivlanet
|
||||
if (ptr == rhs->ptr) {
|
||||
return TRUE;
|
||||
}
|
||||
// Width same, but differing shred data. Depends on locale
|
||||
// and number format objects being the same.
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const char *localeId = getLocaleID(status);
|
||||
const char *rhsLocaleId = rhs->getLocaleID(status);
|
||||
if (U_FAILURE(status)) {
|
||||
// On failure, assume not equal
|
||||
return FALSE;
|
||||
}
|
||||
return (uprv_strcmp(localeId, rhsLocaleId) == 0
|
||||
&& *ptr->numberFormat == *rhs->ptr->numberFormat);
|
||||
}
|
||||
|
||||
Format *MeasureFormat::clone() const {
|
||||
return new MeasureFormat(*this);
|
||||
}
|
||||
|
||||
UnicodeString &MeasureFormat::format(
|
||||
const Formattable &obj,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) return appendTo;
|
||||
if (obj.getType() == Formattable::kObject) {
|
||||
const UObject* formatObj = obj.getObject();
|
||||
const Measure* amount = dynamic_cast<const Measure*>(formatObj);
|
||||
if (amount != NULL) {
|
||||
return formatMeasure(*amount, appendTo, pos, status);
|
||||
}
|
||||
}
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
void MeasureFormat::parseObject(
|
||||
const UnicodeString & /*source*/,
|
||||
Formattable & /*result*/,
|
||||
ParsePosition& /*pos*/) const {
|
||||
return;
|
||||
}
|
||||
|
||||
UnicodeString &MeasureFormat::formatMeasures(
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const {
|
||||
static const char *listStyles[] = {"unit", "unit-short", "unit-narrow"};
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
if (measureCount == 0) {
|
||||
return appendTo;
|
||||
}
|
||||
if (measureCount == 1) {
|
||||
return formatMeasure(measures[0], appendTo, pos, status);
|
||||
}
|
||||
if (width == UMEASFMT_WIDTH_NUMERIC) {
|
||||
Formattable hms[3];
|
||||
int32_t bitMap = toHMS(measures, measureCount, hms, status);
|
||||
if (bitMap > 0) {
|
||||
return formatNumeric(hms, bitMap, appendTo, status);
|
||||
}
|
||||
}
|
||||
LocalPointer<ListFormatter> lf(
|
||||
ListFormatter::createInstance(
|
||||
getLocale(status),
|
||||
listStyles[widthToIndex(width)],
|
||||
status));
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
if (pos.getField() != FieldPosition::DONT_CARE) {
|
||||
return formatMeasuresSlowTrack(
|
||||
measures, measureCount, *lf, appendTo, pos, status);
|
||||
}
|
||||
UnicodeString *results = new UnicodeString[measureCount];
|
||||
if (results == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return appendTo;
|
||||
}
|
||||
for (int32_t i = 0; i < measureCount; ++i) {
|
||||
formatMeasure(measures[i], results[i], pos, status);
|
||||
}
|
||||
lf->format(results, measureCount, appendTo, status);
|
||||
delete [] results;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
void MeasureFormat::initMeasureFormat(
|
||||
const Locale &locale, UMeasureFormatWidth w, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
const char *name = locale.getName();
|
||||
setLocaleIDs(name, name);
|
||||
width = w;
|
||||
getFromCache(name, ptr, status);
|
||||
}
|
||||
|
||||
void MeasureFormat::adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
MeasureFormatData* wptr = SharedObject::copyOnWrite(ptr);
|
||||
if (wptr == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
if (!wptr->numberFormat.reset(nfToAdopt)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UBool MeasureFormat::setMeasureFormatLocale(const Locale &locale, UErrorCode &status) {
|
||||
if (U_FAILURE(status) || locale == getLocale(status)) {
|
||||
return FALSE;
|
||||
}
|
||||
initMeasureFormat(locale, width, status);
|
||||
return U_SUCCESS(status);
|
||||
}
|
||||
|
||||
const NumberFormat &MeasureFormat::getNumberFormat() const {
|
||||
return *ptr->numberFormat;
|
||||
}
|
||||
|
||||
const PluralRules &MeasureFormat::getPluralRules() const {
|
||||
return *ptr->pluralRules;
|
||||
}
|
||||
|
||||
Locale MeasureFormat::getLocale(UErrorCode &status) const {
|
||||
return Format::getLocale(ULOC_VALID_LOCALE, status);
|
||||
}
|
||||
|
||||
const char *MeasureFormat::getLocaleID(UErrorCode &status) const {
|
||||
return Format::getLocaleID(ULOC_VALID_LOCALE, status);
|
||||
}
|
||||
|
||||
UnicodeString &MeasureFormat::formatMeasure(
|
||||
const Measure &measure,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
const Formattable& amtNumber = measure.getNumber();
|
||||
const MeasureUnit& amtUnit = measure.getUnit();
|
||||
if (isCurrency(amtUnit)) {
|
||||
UChar isoCode[4];
|
||||
u_charsToUChars(amtUnit.getSubtype(), isoCode, 4);
|
||||
return ptr->currencyFormats[widthToIndex(width)]->format(
|
||||
new CurrencyAmount(amtNumber, isoCode, status),
|
||||
appendTo,
|
||||
pos,
|
||||
status);
|
||||
}
|
||||
const QuantityFormatter *quantityFormatter = getQuantityFormatter(
|
||||
amtUnit.getIndex(), widthToIndex(width), status);
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
return quantityFormatter->format(
|
||||
amtNumber,
|
||||
*ptr->numberFormat,
|
||||
*ptr->pluralRules, appendTo,
|
||||
pos,
|
||||
status);
|
||||
}
|
||||
|
||||
UnicodeString &MeasureFormat::formatNumeric(
|
||||
const Formattable *hms, // always length 3
|
||||
int32_t bitMap, // 1=hourset, 2=minuteset, 4=secondset
|
||||
UnicodeString &appendTo,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
UDate millis =
|
||||
(UDate) (((hms[0].getDouble(status) * 60.0
|
||||
+ hms[1].getDouble(status)) * 60.0
|
||||
+ hms[2].getDouble(status)) * 1000.0);
|
||||
switch (bitMap) {
|
||||
case 5: // hs
|
||||
case 7: // hms
|
||||
return formatNumeric(
|
||||
millis,
|
||||
ptr->numericDateFormatters->hourMinuteSecond,
|
||||
UDAT_SECOND_FIELD,
|
||||
hms[2],
|
||||
appendTo,
|
||||
status);
|
||||
break;
|
||||
case 6: // ms
|
||||
return formatNumeric(
|
||||
millis,
|
||||
ptr->numericDateFormatters->minuteSecond,
|
||||
UDAT_SECOND_FIELD,
|
||||
hms[2],
|
||||
appendTo,
|
||||
status);
|
||||
break;
|
||||
case 3: // hm
|
||||
return formatNumeric(
|
||||
millis,
|
||||
ptr->numericDateFormatters->hourMinute,
|
||||
UDAT_MINUTE_FIELD,
|
||||
hms[1],
|
||||
appendTo,
|
||||
status);
|
||||
break;
|
||||
default:
|
||||
status = U_INTERNAL_PROGRAM_ERROR;
|
||||
return appendTo;
|
||||
break;
|
||||
}
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
UnicodeString &MeasureFormat::formatNumeric(
|
||||
UDate date,
|
||||
const DateFormat &dateFmt,
|
||||
UDateFormatField smallestField,
|
||||
const Formattable &smallestAmount,
|
||||
UnicodeString &appendTo,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
UnicodeString smallestAmountFormatted;
|
||||
ptr->numberFormat->format(
|
||||
smallestAmount, smallestAmountFormatted, status);
|
||||
FieldPosition smallestFieldPosition(smallestField);
|
||||
UnicodeString draft;
|
||||
dateFmt.format(date, draft, smallestFieldPosition, status);
|
||||
if (smallestFieldPosition.getBeginIndex() != 0 ||
|
||||
smallestFieldPosition.getEndIndex() != 0) {
|
||||
appendTo.append(draft, 0, smallestFieldPosition.getBeginIndex());
|
||||
appendTo.append(smallestAmountFormatted);
|
||||
appendTo.append(
|
||||
draft,
|
||||
smallestFieldPosition.getEndIndex(),
|
||||
draft.length());
|
||||
} else {
|
||||
appendTo.append(draft);
|
||||
}
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
const QuantityFormatter *MeasureFormat::getQuantityFormatter(
|
||||
int32_t index,
|
||||
int32_t widthIndex,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
const QuantityFormatter *formatters =
|
||||
ptr->unitFormatters->formatters[index];
|
||||
if (formatters[widthIndex].isValid()) {
|
||||
return &formatters[widthIndex];
|
||||
}
|
||||
if (formatters[UMEASFMT_WIDTH_SHORT].isValid()) {
|
||||
return &formatters[UMEASFMT_WIDTH_SHORT];
|
||||
}
|
||||
if (formatters[UMEASFMT_WIDTH_WIDE].isValid()) {
|
||||
return &formatters[UMEASFMT_WIDTH_WIDE];
|
||||
}
|
||||
status = U_MISSING_RESOURCE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UnicodeString &MeasureFormat::formatMeasuresSlowTrack(
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
const ListFormatter& lf,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
}
|
||||
FieldPosition dontCare(FieldPosition::DONT_CARE);
|
||||
FieldPosition fpos(pos.getField());
|
||||
UnicodeString *results = new UnicodeString[measureCount];
|
||||
int32_t fieldPositionFoundIndex = -1;
|
||||
for (int32_t i = 0; i < measureCount; ++i) {
|
||||
if (fieldPositionFoundIndex == -1) {
|
||||
formatMeasure(measures[i], results[i], fpos, status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete [] results;
|
||||
return appendTo;
|
||||
}
|
||||
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
||||
fieldPositionFoundIndex = i;
|
||||
}
|
||||
} else {
|
||||
formatMeasure(measures[i], results[i], dontCare, status);
|
||||
}
|
||||
}
|
||||
int32_t offset;
|
||||
lf.format(
|
||||
results,
|
||||
measureCount,
|
||||
appendTo,
|
||||
fieldPositionFoundIndex,
|
||||
offset,
|
||||
status);
|
||||
if (U_FAILURE(status)) {
|
||||
delete [] results;
|
||||
return appendTo;
|
||||
}
|
||||
if (offset != -1) {
|
||||
pos.setBeginIndex(fpos.getBeginIndex() + offset);
|
||||
pos.setEndIndex(fpos.getEndIndex() + offset);
|
||||
}
|
||||
delete [] results;
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
MeasureFormat* U_EXPORT2 MeasureFormat::createCurrencyFormat(const Locale& locale,
|
||||
UErrorCode& ec) {
|
||||
|
734
icu4c/source/i18n/measunit.cpp
Normal file
734
icu4c/source/i18n/measunit.cpp
Normal file
@ -0,0 +1,734 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
* Created: April 26, 2004
|
||||
* Since: ICU 3.0
|
||||
**********************************************************************
|
||||
*/
|
||||
#include "unicode/measunit.h"
|
||||
#include "unicode/uenum.h"
|
||||
#include "ustrenum.h"
|
||||
#include "cstring.h"
|
||||
#include "uassert.h"
|
||||
|
||||
#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static const int32_t gOffsets[] = {
|
||||
0,
|
||||
1,
|
||||
4,
|
||||
10,
|
||||
270,
|
||||
278,
|
||||
288,
|
||||
292,
|
||||
295,
|
||||
298,
|
||||
301,
|
||||
303,
|
||||
306
|
||||
};
|
||||
|
||||
static const int32_t gIndexes[] = {
|
||||
0,
|
||||
1,
|
||||
4,
|
||||
10,
|
||||
10,
|
||||
18,
|
||||
28,
|
||||
32,
|
||||
35,
|
||||
38,
|
||||
41,
|
||||
43,
|
||||
46
|
||||
};
|
||||
|
||||
static const char * const gTypes[] = {
|
||||
"acceleration",
|
||||
"angle",
|
||||
"area",
|
||||
"currency",
|
||||
"duration",
|
||||
"length",
|
||||
"mass",
|
||||
"power",
|
||||
"pressure",
|
||||
"speed",
|
||||
"temperature",
|
||||
"volume"
|
||||
};
|
||||
|
||||
static const char * const gSubTypes[] = {
|
||||
"g-force",
|
||||
"arc-minute",
|
||||
"arc-second",
|
||||
"degree",
|
||||
"acre",
|
||||
"hectare",
|
||||
"square-foot",
|
||||
"square-kilometer",
|
||||
"square-meter",
|
||||
"square-mile",
|
||||
"ADP",
|
||||
"AED",
|
||||
"AFA",
|
||||
"AFN",
|
||||
"ALL",
|
||||
"AMD",
|
||||
"ANG",
|
||||
"AOA",
|
||||
"AON",
|
||||
"AOR",
|
||||
"ARA",
|
||||
"ARP",
|
||||
"ARS",
|
||||
"ATS",
|
||||
"AUD",
|
||||
"AWG",
|
||||
"AYM",
|
||||
"AZM",
|
||||
"AZN",
|
||||
"BAD",
|
||||
"BAM",
|
||||
"BBD",
|
||||
"BDT",
|
||||
"BEC",
|
||||
"BEF",
|
||||
"BEL",
|
||||
"BGL",
|
||||
"BGN",
|
||||
"BHD",
|
||||
"BIF",
|
||||
"BMD",
|
||||
"BND",
|
||||
"BOB",
|
||||
"BOV",
|
||||
"BRC",
|
||||
"BRE",
|
||||
"BRL",
|
||||
"BRN",
|
||||
"BRR",
|
||||
"BSD",
|
||||
"BTN",
|
||||
"BWP",
|
||||
"BYB",
|
||||
"BYR",
|
||||
"BZD",
|
||||
"CAD",
|
||||
"CDF",
|
||||
"CHC",
|
||||
"CHE",
|
||||
"CHF",
|
||||
"CHW",
|
||||
"CLF",
|
||||
"CLP",
|
||||
"CNY",
|
||||
"COP",
|
||||
"COU",
|
||||
"CRC",
|
||||
"CSD",
|
||||
"CSK",
|
||||
"CUC",
|
||||
"CUP",
|
||||
"CVE",
|
||||
"CYP",
|
||||
"CZK",
|
||||
"DDM",
|
||||
"DEM",
|
||||
"DJF",
|
||||
"DKK",
|
||||
"DOP",
|
||||
"DZD",
|
||||
"ECS",
|
||||
"ECV",
|
||||
"EEK",
|
||||
"EGP",
|
||||
"ERN",
|
||||
"ESA",
|
||||
"ESB",
|
||||
"ESP",
|
||||
"ETB",
|
||||
"EUR",
|
||||
"FIM",
|
||||
"FJD",
|
||||
"FKP",
|
||||
"FRF",
|
||||
"GBP",
|
||||
"GEK",
|
||||
"GEL",
|
||||
"GHC",
|
||||
"GHP",
|
||||
"GHS",
|
||||
"GIP",
|
||||
"GMD",
|
||||
"GNF",
|
||||
"GQE",
|
||||
"GRD",
|
||||
"GTQ",
|
||||
"GWP",
|
||||
"GYD",
|
||||
"HKD",
|
||||
"HNL",
|
||||
"HRD",
|
||||
"HRK",
|
||||
"HTG",
|
||||
"HUF",
|
||||
"IDR",
|
||||
"IEP",
|
||||
"ILS",
|
||||
"INR",
|
||||
"IQD",
|
||||
"IRR",
|
||||
"ISK",
|
||||
"ITL",
|
||||
"JMD",
|
||||
"JOD",
|
||||
"JPY",
|
||||
"KES",
|
||||
"KGS",
|
||||
"KHR",
|
||||
"KMF",
|
||||
"KPW",
|
||||
"KRW",
|
||||
"KWD",
|
||||
"KYD",
|
||||
"KZT",
|
||||
"LAK",
|
||||
"LBP",
|
||||
"LKR",
|
||||
"LRD",
|
||||
"LSL",
|
||||
"LTL",
|
||||
"LTT",
|
||||
"LUC",
|
||||
"LUF",
|
||||
"LUL",
|
||||
"LVL",
|
||||
"LVR",
|
||||
"LYD",
|
||||
"MAD",
|
||||
"MDL",
|
||||
"MGA",
|
||||
"MGF",
|
||||
"MKD",
|
||||
"MLF",
|
||||
"MMK",
|
||||
"MNT",
|
||||
"MOP",
|
||||
"MRO",
|
||||
"MTL",
|
||||
"MUR",
|
||||
"MVR",
|
||||
"MWK",
|
||||
"MXN",
|
||||
"MXV",
|
||||
"MYR",
|
||||
"MZM",
|
||||
"MZN",
|
||||
"NAD",
|
||||
"NGN",
|
||||
"NIO",
|
||||
"NLG",
|
||||
"NOK",
|
||||
"NPR",
|
||||
"NZD",
|
||||
"OMR",
|
||||
"PAB",
|
||||
"PEI",
|
||||
"PEN",
|
||||
"PES",
|
||||
"PGK",
|
||||
"PHP",
|
||||
"PKR",
|
||||
"PLN",
|
||||
"PLZ",
|
||||
"PTE",
|
||||
"PYG",
|
||||
"QAR",
|
||||
"ROL",
|
||||
"RON",
|
||||
"RSD",
|
||||
"RUB",
|
||||
"RUR",
|
||||
"RWF",
|
||||
"SAR",
|
||||
"SBD",
|
||||
"SCR",
|
||||
"SDD",
|
||||
"SDG",
|
||||
"SEK",
|
||||
"SGD",
|
||||
"SHP",
|
||||
"SIT",
|
||||
"SKK",
|
||||
"SLL",
|
||||
"SOS",
|
||||
"SRD",
|
||||
"SRG",
|
||||
"SSP",
|
||||
"STD",
|
||||
"SVC",
|
||||
"SYP",
|
||||
"SZL",
|
||||
"THB",
|
||||
"TJR",
|
||||
"TJS",
|
||||
"TMM",
|
||||
"TMT",
|
||||
"TND",
|
||||
"TOP",
|
||||
"TPE",
|
||||
"TRL",
|
||||
"TRY",
|
||||
"TTD",
|
||||
"TWD",
|
||||
"TZS",
|
||||
"UAH",
|
||||
"UAK",
|
||||
"UGX",
|
||||
"USD",
|
||||
"USN",
|
||||
"USS",
|
||||
"UYI",
|
||||
"UYU",
|
||||
"UZS",
|
||||
"VEB",
|
||||
"VEF",
|
||||
"VND",
|
||||
"VUV",
|
||||
"WST",
|
||||
"XAF",
|
||||
"XAG",
|
||||
"XAU",
|
||||
"XBA",
|
||||
"XBB",
|
||||
"XBC",
|
||||
"XBD",
|
||||
"XCD",
|
||||
"XDR",
|
||||
"XEU",
|
||||
"XOF",
|
||||
"XPD",
|
||||
"XPF",
|
||||
"XPT",
|
||||
"XSU",
|
||||
"XTS",
|
||||
"XUA",
|
||||
"XXX",
|
||||
"YDD",
|
||||
"YER",
|
||||
"YUM",
|
||||
"YUN",
|
||||
"ZAL",
|
||||
"ZAR",
|
||||
"ZMK",
|
||||
"ZMW",
|
||||
"ZRN",
|
||||
"ZRZ",
|
||||
"ZWD",
|
||||
"ZWL",
|
||||
"ZWN",
|
||||
"ZWR",
|
||||
"day",
|
||||
"hour",
|
||||
"millisecond",
|
||||
"minute",
|
||||
"month",
|
||||
"second",
|
||||
"week",
|
||||
"year",
|
||||
"centimeter",
|
||||
"foot",
|
||||
"inch",
|
||||
"kilometer",
|
||||
"light-year",
|
||||
"meter",
|
||||
"mile",
|
||||
"millimeter",
|
||||
"picometer",
|
||||
"yard",
|
||||
"gram",
|
||||
"kilogram",
|
||||
"ounce",
|
||||
"pound",
|
||||
"horsepower",
|
||||
"kilowatt",
|
||||
"watt",
|
||||
"hectopascal",
|
||||
"inch-hg",
|
||||
"millibar",
|
||||
"kilometer-per-hour",
|
||||
"meter-per-second",
|
||||
"mile-per-hour",
|
||||
"celsius",
|
||||
"fahrenheit",
|
||||
"cubic-kilometer",
|
||||
"cubic-mile",
|
||||
"liter"
|
||||
};
|
||||
|
||||
MeasureUnit *MeasureUnit::createGForce(UErrorCode &status) {
|
||||
return MeasureUnit::create(0, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createArcMinute(UErrorCode &status) {
|
||||
return MeasureUnit::create(1, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createArcSecond(UErrorCode &status) {
|
||||
return MeasureUnit::create(1, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createDegree(UErrorCode &status) {
|
||||
return MeasureUnit::create(1, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createAcre(UErrorCode &status) {
|
||||
return MeasureUnit::create(2, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createHectare(UErrorCode &status) {
|
||||
return MeasureUnit::create(2, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createSquareFoot(UErrorCode &status) {
|
||||
return MeasureUnit::create(2, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createSquareKilometer(UErrorCode &status) {
|
||||
return MeasureUnit::create(2, 3, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createSquareMeter(UErrorCode &status) {
|
||||
return MeasureUnit::create(2, 4, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createSquareMile(UErrorCode &status) {
|
||||
return MeasureUnit::create(2, 5, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createDay(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createHour(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMillisecond(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMinute(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 3, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMonth(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 4, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createSecond(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 5, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createWeek(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 6, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createYear(UErrorCode &status) {
|
||||
return MeasureUnit::create(4, 7, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createCentimeter(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createFoot(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createInch(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createKilometer(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 3, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createLightYear(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 4, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMeter(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 5, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMile(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 6, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMillimeter(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 7, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createPicometer(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 8, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createYard(UErrorCode &status) {
|
||||
return MeasureUnit::create(5, 9, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createGram(UErrorCode &status) {
|
||||
return MeasureUnit::create(6, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createKilogram(UErrorCode &status) {
|
||||
return MeasureUnit::create(6, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createOunce(UErrorCode &status) {
|
||||
return MeasureUnit::create(6, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createPound(UErrorCode &status) {
|
||||
return MeasureUnit::create(6, 3, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createHorsepower(UErrorCode &status) {
|
||||
return MeasureUnit::create(7, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createKilowatt(UErrorCode &status) {
|
||||
return MeasureUnit::create(7, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createWatt(UErrorCode &status) {
|
||||
return MeasureUnit::create(7, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createHectopascal(UErrorCode &status) {
|
||||
return MeasureUnit::create(8, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createInchHg(UErrorCode &status) {
|
||||
return MeasureUnit::create(8, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMillibar(UErrorCode &status) {
|
||||
return MeasureUnit::create(8, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createKilometerPerHour(UErrorCode &status) {
|
||||
return MeasureUnit::create(9, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMeterPerSecond(UErrorCode &status) {
|
||||
return MeasureUnit::create(9, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createMilePerHour(UErrorCode &status) {
|
||||
return MeasureUnit::create(9, 2, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createCelsius(UErrorCode &status) {
|
||||
return MeasureUnit::create(10, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createFahrenheit(UErrorCode &status) {
|
||||
return MeasureUnit::create(10, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createCubicKilometer(UErrorCode &status) {
|
||||
return MeasureUnit::create(11, 0, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createCubicMile(UErrorCode &status) {
|
||||
return MeasureUnit::create(11, 1, status);
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::createLiter(UErrorCode &status) {
|
||||
return MeasureUnit::create(11, 2, status);
|
||||
}
|
||||
|
||||
static int32_t binarySearch(
|
||||
const char * const * array, int32_t start, int32_t end, const char * key) {
|
||||
while (start < end) {
|
||||
int32_t mid = (start + end) / 2;
|
||||
int32_t cmp = uprv_strcmp(array[mid], key);
|
||||
if (cmp < 0) {
|
||||
start = mid + 1;
|
||||
continue;
|
||||
}
|
||||
if (cmp == 0) {
|
||||
return mid;
|
||||
}
|
||||
end = mid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
MeasureUnit::MeasureUnit(const MeasureUnit &other)
|
||||
: fTypeId(other.fTypeId), fSubTypeId(other.fSubTypeId) {
|
||||
uprv_strcpy(fCurrency, other.fCurrency);
|
||||
}
|
||||
|
||||
MeasureUnit &MeasureUnit::operator=(const MeasureUnit &other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
fTypeId = other.fTypeId;
|
||||
fSubTypeId = other.fSubTypeId;
|
||||
uprv_strcpy(fCurrency, other.fCurrency);
|
||||
return *this;
|
||||
}
|
||||
|
||||
UObject *MeasureUnit::clone() const {
|
||||
return new MeasureUnit(*this);
|
||||
}
|
||||
|
||||
MeasureUnit::~MeasureUnit() {
|
||||
}
|
||||
|
||||
const char *MeasureUnit::getType() const {
|
||||
return gTypes[fTypeId];
|
||||
}
|
||||
|
||||
const char *MeasureUnit::getSubtype() const {
|
||||
return fCurrency[0] == 0 ? gSubTypes[getOffset()] : fCurrency;
|
||||
}
|
||||
|
||||
UBool MeasureUnit::operator==(const UObject& other) const {
|
||||
const MeasureUnit *rhs = dynamic_cast<const MeasureUnit*>(&other);
|
||||
if (rhs == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
return (
|
||||
fTypeId == rhs->fTypeId
|
||||
&& fSubTypeId == rhs->fSubTypeId
|
||||
&& uprv_strcmp(fCurrency, rhs->fCurrency) == 0);
|
||||
}
|
||||
|
||||
int32_t MeasureUnit::getIndex() const {
|
||||
return gIndexes[fTypeId] + fSubTypeId;
|
||||
}
|
||||
|
||||
int32_t MeasureUnit::getAvailable(
|
||||
MeasureUnit *dest,
|
||||
int32_t destCapacity,
|
||||
UErrorCode &errorCode) {
|
||||
if (U_FAILURE(errorCode)) {
|
||||
return 0;
|
||||
}
|
||||
if (destCapacity < LENGTHOF(gSubTypes)) {
|
||||
errorCode = U_BUFFER_OVERFLOW_ERROR;
|
||||
return LENGTHOF(gSubTypes);
|
||||
}
|
||||
int32_t idx = 0;
|
||||
for (int32_t typeIdx = 0; typeIdx < LENGTHOF(gTypes); ++typeIdx) {
|
||||
int32_t len = gOffsets[typeIdx + 1] - gOffsets[typeIdx];
|
||||
for (int32_t subTypeIdx = 0; subTypeIdx < len; ++subTypeIdx) {
|
||||
dest[idx].setTo(typeIdx, subTypeIdx);
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
U_ASSERT(idx == LENGTHOF(gSubTypes));
|
||||
return LENGTHOF(gSubTypes);
|
||||
}
|
||||
|
||||
int32_t MeasureUnit::getAvailable(
|
||||
const char *type,
|
||||
MeasureUnit *dest,
|
||||
int32_t destCapacity,
|
||||
UErrorCode &errorCode) {
|
||||
if (U_FAILURE(errorCode)) {
|
||||
return 0;
|
||||
}
|
||||
int32_t typeIdx = binarySearch(gTypes, 0, LENGTHOF(gTypes), type);
|
||||
if (typeIdx == -1) {
|
||||
return 0;
|
||||
}
|
||||
int32_t len = gOffsets[typeIdx + 1] - gOffsets[typeIdx];
|
||||
if (destCapacity < len) {
|
||||
errorCode = U_BUFFER_OVERFLOW_ERROR;
|
||||
return len;
|
||||
}
|
||||
for (int subTypeIdx = 0; subTypeIdx < len; ++subTypeIdx) {
|
||||
dest[subTypeIdx].setTo(typeIdx, subTypeIdx);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
StringEnumeration* MeasureUnit::getAvailableTypes(UErrorCode &errorCode) {
|
||||
UEnumeration *uenum = uenum_openCharStringsEnumeration(
|
||||
gTypes, LENGTHOF(gTypes), &errorCode);
|
||||
if (U_FAILURE(errorCode)) {
|
||||
uenum_close(uenum);
|
||||
return NULL;
|
||||
}
|
||||
StringEnumeration *result = new UStringEnumeration(uenum);
|
||||
if (result == NULL) {
|
||||
errorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
uenum_close(uenum);
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t MeasureUnit::getIndexCount() {
|
||||
return gIndexes[LENGTHOF(gIndexes) - 1];
|
||||
}
|
||||
|
||||
MeasureUnit *MeasureUnit::create(int typeId, int subTypeId, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
MeasureUnit *result = new MeasureUnit(typeId, subTypeId);
|
||||
if (result == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MeasureUnit::initTime(const char *timeId) {
|
||||
int32_t result = binarySearch(gTypes, 0, LENGTHOF(gTypes), "duration");
|
||||
U_ASSERT(result != -1);
|
||||
fTypeId = result;
|
||||
result = binarySearch(gSubTypes, gOffsets[fTypeId], gOffsets[fTypeId + 1], timeId);
|
||||
U_ASSERT(result != -1);
|
||||
fSubTypeId = result - gOffsets[fTypeId];
|
||||
}
|
||||
|
||||
void MeasureUnit::initCurrency(const char *isoCurrency) {
|
||||
int32_t result = binarySearch(gTypes, 0, LENGTHOF(gTypes), "currency");
|
||||
U_ASSERT(result != -1);
|
||||
fTypeId = result;
|
||||
result = binarySearch(
|
||||
gSubTypes, gOffsets[fTypeId], gOffsets[fTypeId + 1], isoCurrency);
|
||||
if (result != -1) {
|
||||
fSubTypeId = result - gOffsets[fTypeId];
|
||||
} else {
|
||||
uprv_strncpy(fCurrency, isoCurrency, LENGTHOF(fCurrency));
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureUnit::setTo(int32_t typeId, int32_t subTypeId) {
|
||||
fTypeId = typeId;
|
||||
fSubTypeId = subTypeId;
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
int32_t MeasureUnit::getOffset() const {
|
||||
return gOffsets[fTypeId] + fSubTypeId;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2012, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -44,6 +44,10 @@ Measure& Measure::operator=(const Measure& other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
UObject *Measure::clone() const {
|
||||
return new Measure(*this);
|
||||
}
|
||||
|
||||
Measure::~Measure() {
|
||||
delete unit;
|
||||
}
|
||||
@ -55,13 +59,6 @@ UBool Measure::operator==(const UObject& other) const {
|
||||
(unit != NULL && *unit == m->getUnit());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// MeasureUnit implementation
|
||||
|
||||
MeasureUnit:: MeasureUnit() {}
|
||||
|
||||
MeasureUnit::~MeasureUnit() {}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif // !UCONFIG_NO_FORMATTING
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "unicode/plurrule.h"
|
||||
#include "charstr.h"
|
||||
#include "unicode/fmtable.h"
|
||||
#include "unicode/fieldpos.h"
|
||||
|
||||
#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
@ -107,11 +108,16 @@ UBool QuantityFormatter::add(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UBool QuantityFormatter::isValid() const {
|
||||
return formatters[0] != NULL;
|
||||
}
|
||||
|
||||
UnicodeString &QuantityFormatter::format(
|
||||
const Formattable& quantity,
|
||||
const NumberFormat &fmt,
|
||||
const PluralRules &rules,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return appendTo;
|
||||
@ -154,9 +160,18 @@ UnicodeString &QuantityFormatter::format(
|
||||
return appendTo;
|
||||
}
|
||||
UnicodeString formattedNumber;
|
||||
FieldPosition pos(0);
|
||||
fmt.format(quantity, formattedNumber, pos, status);
|
||||
return pattern->format(formattedNumber, appendTo, status);
|
||||
FieldPosition fpos(pos.getField());
|
||||
fmt.format(quantity, formattedNumber, fpos, status);
|
||||
const UnicodeString *params[1] = {&formattedNumber};
|
||||
int32_t offsets[1];
|
||||
pattern->format(params, LENGTHOF(params), appendTo, offsets, LENGTHOF(offsets), status);
|
||||
if (offsets[0] != -1) {
|
||||
if (fpos.getBeginIndex() != 0 || fpos.getEndIndex() != 0) {
|
||||
pos.setBeginIndex(fpos.getBeginIndex() + offsets[0]);
|
||||
pos.setEndIndex(fpos.getEndIndex() + offsets[0]);
|
||||
}
|
||||
}
|
||||
return appendTo;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -19,6 +19,7 @@ class UnicodeString;
|
||||
class PluralRules;
|
||||
class NumberFormat;
|
||||
class Formattable;
|
||||
class FieldPosition;
|
||||
|
||||
/**
|
||||
* A plural aware formatter that is good for expressing a single quantity and
|
||||
@ -74,6 +75,11 @@ public:
|
||||
const UnicodeString &rawPattern,
|
||||
UErrorCode &status);
|
||||
|
||||
/**
|
||||
* returns TRUE if this object has at least the "other" variant.
|
||||
*/
|
||||
UBool isValid() const;
|
||||
|
||||
/**
|
||||
* Formats a quantity with this object appending the result to appendTo.
|
||||
* At least the "other" variant must be added to this object for this
|
||||
@ -91,6 +97,7 @@ public:
|
||||
const NumberFormat &fmt,
|
||||
const PluralRules &rules,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
private:
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "uresimp.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "cstring.h"
|
||||
#include "plurrule_impl.h"
|
||||
#include "ucln_in.h"
|
||||
#include "mutex.h"
|
||||
#include "charstr.h"
|
||||
@ -648,11 +647,13 @@ UnicodeString& RelativeDateTimeFormatter::format(
|
||||
return appendTo;
|
||||
}
|
||||
int32_t bFuture = direction == UDAT_DIRECTION_NEXT ? 1 : 0;
|
||||
FieldPosition pos(FieldPosition::DONT_CARE);
|
||||
return ptr->quantitativeUnits->data[unit][bFuture].format(
|
||||
quantity,
|
||||
*ptr->numberFormat,
|
||||
*ptr->pluralRules,
|
||||
appendTo,
|
||||
pos,
|
||||
status);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2008-2012, Google, International Business Machines Corporation and
|
||||
* Copyright (C) 2008-2014, Google, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -8,6 +8,7 @@
|
||||
#include "utypeinfo.h" // for 'typeid' to work
|
||||
|
||||
#include "unicode/tmunit.h"
|
||||
#include "uassert.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
@ -70,44 +71,58 @@ TimeUnit::createInstance(TimeUnit::UTimeUnitFields timeUnitField,
|
||||
|
||||
TimeUnit::TimeUnit(TimeUnit::UTimeUnitFields timeUnitField) {
|
||||
fTimeUnitField = timeUnitField;
|
||||
switch (fTimeUnitField) {
|
||||
case UTIMEUNIT_YEAR:
|
||||
initTime("year");
|
||||
break;
|
||||
case UTIMEUNIT_MONTH:
|
||||
initTime("month");
|
||||
break;
|
||||
case UTIMEUNIT_DAY:
|
||||
initTime("day");
|
||||
break;
|
||||
case UTIMEUNIT_WEEK:
|
||||
initTime("week");
|
||||
break;
|
||||
case UTIMEUNIT_HOUR:
|
||||
initTime("hour");
|
||||
break;
|
||||
case UTIMEUNIT_MINUTE:
|
||||
initTime("minute");
|
||||
break;
|
||||
case UTIMEUNIT_SECOND:
|
||||
initTime("second");
|
||||
break;
|
||||
default:
|
||||
U_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TimeUnit::TimeUnit(const TimeUnit& other)
|
||||
: MeasureUnit(other) {
|
||||
*this = other;
|
||||
: MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
|
||||
}
|
||||
|
||||
|
||||
UObject*
|
||||
TimeUnit::clone() const {
|
||||
return new TimeUnit(*this);
|
||||
}
|
||||
|
||||
|
||||
TimeUnit&
|
||||
TimeUnit::operator=(const TimeUnit& other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
MeasureUnit::operator=(other);
|
||||
fTimeUnitField = other.fTimeUnitField;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
UBool
|
||||
TimeUnit::operator==(const UObject& other) const {
|
||||
return (typeid(*this) == typeid(other)
|
||||
&& fTimeUnitField == ((TimeUnit*)&other)->fTimeUnitField);
|
||||
}
|
||||
|
||||
|
||||
TimeUnit::UTimeUnitFields
|
||||
TimeUnit::getTimeUnitField() const {
|
||||
return fTimeUnitField;
|
||||
}
|
||||
|
||||
|
||||
TimeUnit::~TimeUnit() {
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2008-2013, Google, International Business Machines Corporation
|
||||
* Copyright (C) 2008-2014, Google, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -78,53 +78,59 @@ static const UChar PLURAL_COUNT_ZERO[] = {LOW_Z, LOW_E, LOW_R, LOW_O, 0};
|
||||
static const UChar PLURAL_COUNT_ONE[] = {LOW_O, LOW_N, LOW_E, 0};
|
||||
static const UChar PLURAL_COUNT_TWO[] = {LOW_T, LOW_W, LOW_O, 0};
|
||||
|
||||
TimeUnitFormat::TimeUnitFormat(UErrorCode& status)
|
||||
: fNumberFormat(NULL),
|
||||
fPluralRules(NULL) {
|
||||
create(Locale::getDefault(), UTMUTFMT_FULL_STYLE, status);
|
||||
TimeUnitFormat::TimeUnitFormat(UErrorCode& status) {
|
||||
initMeasureFormat(Locale::getDefault(), UMEASFMT_WIDTH_WIDE, status);
|
||||
create(UTMUTFMT_FULL_STYLE, status);
|
||||
}
|
||||
|
||||
|
||||
TimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status)
|
||||
: fNumberFormat(NULL),
|
||||
fPluralRules(NULL) {
|
||||
create(locale, UTMUTFMT_FULL_STYLE, status);
|
||||
TimeUnitFormat::TimeUnitFormat(const Locale& locale, UErrorCode& status) {
|
||||
initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, status);
|
||||
create(UTMUTFMT_FULL_STYLE, status);
|
||||
}
|
||||
|
||||
|
||||
TimeUnitFormat::TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status)
|
||||
: fNumberFormat(NULL),
|
||||
fPluralRules(NULL) {
|
||||
create(locale, style, status);
|
||||
TimeUnitFormat::TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status) {
|
||||
switch (style) {
|
||||
case UTMUTFMT_FULL_STYLE:
|
||||
initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, status);
|
||||
break;
|
||||
case UTMUTFMT_ABBREVIATED_STYLE:
|
||||
initMeasureFormat(locale, UMEASFMT_WIDTH_SHORT, status);
|
||||
break;
|
||||
default:
|
||||
initMeasureFormat(locale, UMEASFMT_WIDTH_WIDE, status);
|
||||
break;
|
||||
}
|
||||
create(style, status);
|
||||
}
|
||||
|
||||
|
||||
TimeUnitFormat::TimeUnitFormat(const TimeUnitFormat& other)
|
||||
: MeasureFormat(other),
|
||||
fNumberFormat(NULL),
|
||||
fPluralRules(NULL),
|
||||
fStyle(UTMUTFMT_FULL_STYLE)
|
||||
fStyle(other.fStyle)
|
||||
{
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
fTimeUnitToCountToPatterns[i] = NULL;
|
||||
}
|
||||
*this = other;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
fTimeUnitToCountToPatterns[i] = initHash(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
copyHash(other.fTimeUnitToCountToPatterns[i], fTimeUnitToCountToPatterns[i], status);
|
||||
} else {
|
||||
delete fTimeUnitToCountToPatterns[i];
|
||||
fTimeUnitToCountToPatterns[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TimeUnitFormat::~TimeUnitFormat() {
|
||||
delete fNumberFormat;
|
||||
fNumberFormat = NULL;
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
deleteHash(fTimeUnitToCountToPatterns[i]);
|
||||
fTimeUnitToCountToPatterns[i] = NULL;
|
||||
}
|
||||
delete fPluralRules;
|
||||
fPluralRules = NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -139,20 +145,13 @@ TimeUnitFormat::operator=(const TimeUnitFormat& other) {
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
delete fNumberFormat;
|
||||
MeasureFormat::operator=(other);
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
deleteHash(fTimeUnitToCountToPatterns[i]);
|
||||
fTimeUnitToCountToPatterns[i] = NULL;
|
||||
}
|
||||
delete fPluralRules;
|
||||
if (other.fNumberFormat) {
|
||||
fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
|
||||
} else {
|
||||
fNumberFormat = NULL;
|
||||
}
|
||||
fLocale = other.fLocale;
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
@ -165,92 +164,10 @@ TimeUnitFormat::operator=(const TimeUnitFormat& other) {
|
||||
fTimeUnitToCountToPatterns[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (other.fPluralRules) {
|
||||
fPluralRules = (PluralRules*)other.fPluralRules->clone();
|
||||
} else {
|
||||
fPluralRules = NULL;
|
||||
}
|
||||
fStyle = other.fStyle;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
UBool
|
||||
TimeUnitFormat::operator==(const Format& other) const {
|
||||
if (typeid(*this) == typeid(other)) {
|
||||
TimeUnitFormat* fmt = (TimeUnitFormat*)&other;
|
||||
UBool ret = ( ((fNumberFormat && fmt->fNumberFormat && *fNumberFormat == *fmt->fNumberFormat)
|
||||
|| fNumberFormat == fmt->fNumberFormat )
|
||||
&& fLocale == fmt->fLocale
|
||||
&& ((fPluralRules && fmt->fPluralRules && *fPluralRules == *fmt->fPluralRules)
|
||||
|| fPluralRules == fmt->fPluralRules)
|
||||
&& fStyle == fmt->fStyle);
|
||||
if (ret) {
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT && ret;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
ret = fTimeUnitToCountToPatterns[i]->equals(*(fmt->fTimeUnitToCountToPatterns[i]));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
UnicodeString&
|
||||
TimeUnitFormat::format(const Formattable& obj, UnicodeString& toAppendTo,
|
||||
FieldPosition& pos, UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return toAppendTo;
|
||||
}
|
||||
if (obj.getType() == Formattable::kObject) {
|
||||
const UObject* formatObj = obj.getObject();
|
||||
const TimeUnitAmount* amount = dynamic_cast<const TimeUnitAmount*>(formatObj);
|
||||
if (amount != NULL){
|
||||
Hashtable* countToPattern = fTimeUnitToCountToPatterns[amount->getTimeUnitField()];
|
||||
const Formattable& amtNumber = amount->getNumber();
|
||||
UnicodeString formattedNumber;
|
||||
fNumberFormat->format(amtNumber, formattedNumber, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return toAppendTo;
|
||||
}
|
||||
UnicodeString count;
|
||||
const DecimalFormat* decfmt = dynamic_cast<const DecimalFormat*>(fNumberFormat);
|
||||
if (decfmt != NULL) {
|
||||
FixedDecimal fd = decfmt->getFixedDecimal(amtNumber, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return toAppendTo;
|
||||
}
|
||||
count = fPluralRules->select(fd);
|
||||
} else {
|
||||
if (amtNumber.getType() == Formattable::kDouble) {
|
||||
count = fPluralRules->select(amtNumber.getDouble());
|
||||
} else if (amtNumber.getType() == Formattable::kLong) {
|
||||
count = fPluralRules->select(amtNumber.getLong());
|
||||
} else if (amtNumber.getType() == Formattable::kInt64) {
|
||||
count = fPluralRules->select((double) amtNumber.getInt64());
|
||||
} else {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return toAppendTo;
|
||||
}
|
||||
}
|
||||
#ifdef TMUTFMT_DEBUG
|
||||
char result[1000];
|
||||
count.extract(0, count.length(), result, "UTF-8");
|
||||
std::cout << "number: " << number << "; format plural count: " << result << "\n";
|
||||
#endif
|
||||
MessageFormat* pattern = ((MessageFormat**)countToPattern->get(count))[fStyle];
|
||||
Formattable formattable[1];
|
||||
formattable[0].setString(formattedNumber);
|
||||
return pattern->format(formattable, 1, toAppendTo, pos, status);
|
||||
}
|
||||
}
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return toAppendTo;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TimeUnitFormat::parseObject(const UnicodeString& source,
|
||||
Formattable& result,
|
||||
@ -305,7 +222,7 @@ TimeUnitFormat::parseObject(const UnicodeString& source,
|
||||
if (temp.getType() == Formattable::kString) {
|
||||
UnicodeString tmpString;
|
||||
UErrorCode pStatus = U_ZERO_ERROR;
|
||||
fNumberFormat->parse(temp.getString(tmpString), tmpNumber, pStatus);
|
||||
getNumberFormat().parse(temp.getString(tmpString), tmpNumber, pStatus);
|
||||
if (U_FAILURE(pStatus)) {
|
||||
continue;
|
||||
}
|
||||
@ -368,7 +285,7 @@ TimeUnitFormat::parseObject(const UnicodeString& source,
|
||||
}
|
||||
|
||||
void
|
||||
TimeUnitFormat::create(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status) {
|
||||
TimeUnitFormat::create(UTimeUnitFormatStyle style, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
@ -377,12 +294,12 @@ TimeUnitFormat::create(const Locale& locale, UTimeUnitFormatStyle style, UErrorC
|
||||
return;
|
||||
}
|
||||
fStyle = style;
|
||||
fLocale = locale;
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
fTimeUnitToCountToPatterns[i] = NULL;
|
||||
}
|
||||
|
||||
//TODO: format() and parseObj() are const member functions,
|
||||
//so, can not do lazy initialization in C++.
|
||||
//setup has to be done in constructors.
|
||||
@ -399,7 +316,7 @@ TimeUnitFormat::setup(UErrorCode& err) {
|
||||
initDataMembers(err);
|
||||
|
||||
UVector pluralCounts(0, uhash_compareUnicodeString, 6, err);
|
||||
StringEnumeration* keywords = fPluralRules->getKeywords(err);
|
||||
StringEnumeration* keywords = getPluralRules().getKeywords(err);
|
||||
if (U_FAILURE(err)) {
|
||||
return;
|
||||
}
|
||||
@ -420,11 +337,6 @@ TimeUnitFormat::initDataMembers(UErrorCode& err){
|
||||
if (U_FAILURE(err)) {
|
||||
return;
|
||||
}
|
||||
if (fNumberFormat == NULL) {
|
||||
fNumberFormat = NumberFormat::createInstance(fLocale, err);
|
||||
}
|
||||
delete fPluralRules;
|
||||
fPluralRules = PluralRules::forLocale(fLocale, err);
|
||||
for (TimeUnit::UTimeUnitFields i = TimeUnit::UTIMEUNIT_YEAR;
|
||||
i < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
i = (TimeUnit::UTimeUnitFields)(i+1)) {
|
||||
@ -445,7 +357,7 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke
|
||||
// status does not affect "err".
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UResourceBundle *rb, *unitsRes;
|
||||
rb = ures_open(NULL, fLocale.getName(), &status);
|
||||
rb = ures_open(NULL, getLocaleID(status), &status);
|
||||
unitsRes = ures_getByKey(rb, key, NULL, &status);
|
||||
unitsRes = ures_getByKey(unitsRes, "duration", unitsRes, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
@ -515,7 +427,7 @@ TimeUnitFormat::readFromCurrentLocale(UTimeUnitFormatStyle style, const char* ke
|
||||
if (!pluralCounts.contains(&pluralCountUniStr)) {
|
||||
continue;
|
||||
}
|
||||
MessageFormat* messageFormat = new MessageFormat(pattern, fLocale, err);
|
||||
MessageFormat* messageFormat = new MessageFormat(pattern, getLocale(err), err);
|
||||
if ( U_SUCCESS(err) ) {
|
||||
MessageFormat** formatters = (MessageFormat**)countToPatterns->get(pluralCountUniStr);
|
||||
if (formatters == NULL) {
|
||||
@ -577,7 +489,7 @@ TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UE
|
||||
// Following is consistency check to create pattern for each
|
||||
// plural rule in each time unit using above fall-back rule.
|
||||
//
|
||||
StringEnumeration* keywords = fPluralRules->getKeywords(err);
|
||||
StringEnumeration* keywords = getPluralRules().getKeywords(err);
|
||||
if (U_SUCCESS(err)) {
|
||||
const UnicodeString* pluralCount;
|
||||
while ((pluralCount = keywords->snext(err)) != NULL) {
|
||||
@ -597,7 +509,7 @@ TimeUnitFormat::checkConsistency(UTimeUnitFormatStyle style, const char* key, UE
|
||||
MessageFormat** formatters = (MessageFormat**)countToPatterns->get(*pluralCount);
|
||||
if( formatters == NULL || formatters[style] == NULL ) {
|
||||
// look through parents
|
||||
const char* localeName = fLocale.getName();
|
||||
const char* localeName = getLocaleID(err);
|
||||
CharString pluralCountChars;
|
||||
pluralCountChars.appendInvariantChars(*pluralCount, err);
|
||||
searchInLocaleChain(style, key, localeName,
|
||||
@ -650,7 +562,7 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key,
|
||||
pattern = ures_getStringByKeyWithFallback(countsToPatternRB, searchPluralCount, &ptLength, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
//found
|
||||
MessageFormat* messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, ptLength), fLocale, err);
|
||||
MessageFormat* messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, ptLength), getLocale(err), err);
|
||||
if (U_SUCCESS(err)) {
|
||||
MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
|
||||
if (formatters == NULL) {
|
||||
@ -725,7 +637,7 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key,
|
||||
pattern = DEFAULT_PATTERN_FOR_YEAR;
|
||||
}
|
||||
if (pattern != NULL) {
|
||||
messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), fLocale, err);
|
||||
messageFormat = new MessageFormat(UnicodeString(TRUE, pattern, -1), getLocale(err), err);
|
||||
}
|
||||
if (U_SUCCESS(err)) {
|
||||
MessageFormat** formatters = (MessageFormat**)countToPatterns->get(srcPluralCount);
|
||||
@ -755,8 +667,7 @@ TimeUnitFormat::searchInLocaleChain(UTimeUnitFormatStyle style, const char* key,
|
||||
|
||||
void
|
||||
TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
|
||||
if (U_SUCCESS(status) && fLocale != locale) {
|
||||
fLocale = locale;
|
||||
if (setMeasureFormatLocale(locale, status)) {
|
||||
setup(status);
|
||||
}
|
||||
}
|
||||
@ -764,11 +675,10 @@ TimeUnitFormat::setLocale(const Locale& locale, UErrorCode& status) {
|
||||
|
||||
void
|
||||
TimeUnitFormat::setNumberFormat(const NumberFormat& format, UErrorCode& status){
|
||||
if (U_FAILURE(status) || (fNumberFormat && format == *fNumberFormat)) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
delete fNumberFormat;
|
||||
fNumberFormat = (NumberFormat*)format.clone();
|
||||
adoptNumberFormat((NumberFormat *)format.clone(), status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* *
|
||||
* Copyright (C) 2001-2013, International Business Machines *
|
||||
* Copyright (C) 2001-2014, International Business Machines *
|
||||
* Corporation and others. All Rights Reserved. *
|
||||
* *
|
||||
******************************************************************************
|
||||
@ -26,7 +26,6 @@ as the functions are suppose to be called.
|
||||
It's usually best to have child dependencies called first. */
|
||||
typedef enum ECleanupI18NType {
|
||||
UCLN_I18N_START = -1,
|
||||
UCLN_I18N_RELDATEFMT,
|
||||
UCLN_I18N_IDENTIFIER_INFO,
|
||||
UCLN_I18N_SPOOF,
|
||||
UCLN_I18N_TRANSLITERATOR,
|
||||
@ -46,6 +45,8 @@ typedef enum ECleanupI18NType {
|
||||
UCLN_I18N_CURRENCY,
|
||||
UCLN_I18N_DECFMT,
|
||||
UCLN_I18N_NUMFMT,
|
||||
UCLN_I18N_RELDATEFMT,
|
||||
UCLN_I18N_MEASFMT,
|
||||
UCLN_I18N_SMPDTFMT,
|
||||
UCLN_I18N_USEARCH,
|
||||
UCLN_I18N_COLLATOR,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2006, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -69,13 +69,6 @@ class U_I18N_API CurrencyUnit: public MeasureUnit {
|
||||
*/
|
||||
virtual ~CurrencyUnit();
|
||||
|
||||
/**
|
||||
* Equality operator. Return true if this object is equal
|
||||
* to the given object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
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.
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2011, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -12,27 +12,74 @@
|
||||
#define MEASUREFORMAT_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/measure.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/format.h"
|
||||
#include "unicode/udat.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C++ API: Formatter for measure objects.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constants for various widths.
|
||||
* There are 3 widths: Wide, Short, Narrow.
|
||||
* For example, for English, when formatting "3 hours"
|
||||
* Wide is "3 hours"; short is "3 hrs"; narrow is "3h"
|
||||
* @draft ICU 53
|
||||
*/
|
||||
enum UMeasureFormatWidth {
|
||||
|
||||
// Wide, short, and narrow must be first and in this order.
|
||||
/**
|
||||
* Spell out measure units.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UMEASFMT_WIDTH_WIDE,
|
||||
|
||||
/**
|
||||
* Abbreviate measure units.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UMEASFMT_WIDTH_SHORT,
|
||||
|
||||
/**
|
||||
* Use symbols for measure units when possible.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UMEASFMT_WIDTH_NARROW,
|
||||
|
||||
/**
|
||||
* Completely omit measure units when possible. For example, format
|
||||
* '5 hours, 37 minutes' as '5:37'
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UMEASFMT_WIDTH_NUMERIC,
|
||||
|
||||
/**
|
||||
* Count of values in this enum.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UMEASFMT_WIDTH_COUNT
|
||||
};
|
||||
/** @draft ICU 53 */
|
||||
typedef enum UMeasureFormatWidth UMeasureFormatWidth;
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class NumberFormat;
|
||||
class PluralRules;
|
||||
class MeasureFormatData;
|
||||
class QuantityFormatter;
|
||||
class ListFormatter;
|
||||
class DateFormat;
|
||||
|
||||
/**
|
||||
*
|
||||
* A formatter for measure objects. This is an abstract base class.
|
||||
*
|
||||
* <p>To format or parse a measure object, first create a formatter
|
||||
* object using a MeasureFormat factory method. Then use that
|
||||
* object's format and parse methods.
|
||||
*
|
||||
* <p>This is an abstract class.
|
||||
* A formatter for measure objects.
|
||||
*
|
||||
* @see Format
|
||||
* @author Alan Liu
|
||||
@ -40,12 +87,96 @@ U_NAMESPACE_BEGIN
|
||||
*/
|
||||
class U_I18N_API MeasureFormat : public Format {
|
||||
public:
|
||||
using Format::parseObject;
|
||||
using Format::format;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @draft ICU 53.
|
||||
*/
|
||||
MeasureFormat(
|
||||
const Locale &locale, UMeasureFormatWidth width, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @draft ICU 53.
|
||||
*/
|
||||
MeasureFormat(
|
||||
const Locale &locale,
|
||||
UMeasureFormatWidth width,
|
||||
NumberFormat *nfToAdopt,
|
||||
UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* @draft ICU 53.
|
||||
*/
|
||||
MeasureFormat(const MeasureFormat &other);
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
* @draft ICU 53.
|
||||
*/
|
||||
MeasureFormat &operator=(const MeasureFormat &rhs);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
virtual ~MeasureFormat();
|
||||
|
||||
/**
|
||||
* Return true if given Format objects are semantically equal.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
virtual UBool operator==(const Format &other) const;
|
||||
|
||||
/**
|
||||
* Clones this object polymorphically.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
virtual Format *clone() const;
|
||||
|
||||
/**
|
||||
* Formats object to produce a string.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
virtual UnicodeString &format(
|
||||
const Formattable &obj,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
/**
|
||||
* Parse a string to produce an object. This implementation sets
|
||||
* status to U_UNSUPPORTED_ERROR.
|
||||
*
|
||||
* @draft ICU 53
|
||||
*/
|
||||
virtual void parseObject(
|
||||
const UnicodeString &source,
|
||||
Formattable &reslt,
|
||||
ParsePosition &pos) const;
|
||||
|
||||
/**
|
||||
* Formats measure objects to produce a string.
|
||||
* @param measures measure objects.
|
||||
* @param measureCount the number of measure objects.
|
||||
* @param appendTo formatted string appended here.
|
||||
* @param pos the field position.
|
||||
* @param status the error.
|
||||
* @return appendTo reference
|
||||
*
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UnicodeString &formatMeasures(
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
|
||||
/**
|
||||
* Return a formatter for CurrencyAmount objects in the given
|
||||
* locale.
|
||||
@ -67,12 +198,99 @@ class U_I18N_API MeasureFormat : public Format {
|
||||
static MeasureFormat* U_EXPORT2 createCurrencyFormat(UErrorCode& ec);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
MeasureFormat();
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* Initialize MeasureFormat class from base class.
|
||||
* @internal.
|
||||
*/
|
||||
void initMeasureFormat(const Locale &locale, UMeasureFormatWidth width, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* Allows subclass to change locale. Note that this method also changes
|
||||
* the NumberFormat object. Returns TRUE if locale changed; FALSE if no
|
||||
* change was made.
|
||||
* @internal.
|
||||
*/
|
||||
UBool setMeasureFormatLocale(const Locale &locale, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* Let subclass change NumberFormat.
|
||||
* @internal.
|
||||
*/
|
||||
void adoptNumberFormat(NumberFormat *nfToAdopt, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* @internal.
|
||||
*/
|
||||
const NumberFormat &getNumberFormat() const;
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* @internal.
|
||||
*/
|
||||
const PluralRules &getPluralRules() const;
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* @internal.
|
||||
*/
|
||||
Locale getLocale(UErrorCode &status) const;
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* @internal.
|
||||
*/
|
||||
const char *getLocaleID(UErrorCode &status) const;
|
||||
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
private:
|
||||
const MeasureFormatData *ptr;
|
||||
UMeasureFormatWidth width;
|
||||
|
||||
const QuantityFormatter *getQuantityFormatter(
|
||||
int32_t index,
|
||||
int32_t widthIndex,
|
||||
UErrorCode &status) const;
|
||||
|
||||
UnicodeString &formatMeasure(
|
||||
const Measure &measure,
|
||||
UnicodeString &appendTo,
|
||||
FieldPosition &pos,
|
||||
UErrorCode &status) const;
|
||||
|
||||
UnicodeString &formatMeasuresSlowTrack(
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
const ListFormatter& lf,
|
||||
UnicodeString& appendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const;
|
||||
|
||||
UnicodeString &formatNumeric(
|
||||
const Formattable *hms, // always length 3
|
||||
int32_t bitMap, // 1=hourset, 2=minuteset, 4=secondset
|
||||
UnicodeString &appendTo,
|
||||
UErrorCode &status) const;
|
||||
|
||||
UnicodeString &formatNumeric(
|
||||
UDate date,
|
||||
const DateFormat &dateFmt,
|
||||
UDateFormatField smallestField,
|
||||
const Formattable &smallestAmount,
|
||||
UnicodeString &appendTo,
|
||||
UErrorCode &status) const;
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2006, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -12,10 +12,7 @@
|
||||
#define __MEASUREUNIT_H__
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/fmtable.h"
|
||||
#include "unicode/unistr.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
@ -24,48 +21,312 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class StringEnumeration;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
class U_I18N_API MeasureUnit: public UObject {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return a polymorphic clone of this object. The result will
|
||||
* Default constructor.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
MeasureUnit() : fTypeId(0), fSubTypeId(0) {
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
MeasureUnit(const MeasureUnit &other);
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
* @draft ICU 53.
|
||||
*/
|
||||
MeasureUnit &operator=(const MeasureUnit &other);
|
||||
|
||||
/**
|
||||
* Returns a polymorphic clone of this object. The result will
|
||||
* have the same class as returned by getDynamicClassID().
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
virtual UObject* clone() const = 0;
|
||||
virtual UObject* clone() const;
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
virtual ~MeasureUnit();
|
||||
|
||||
|
||||
/**
|
||||
* Equality operator. Return true if this object is equal
|
||||
* to the given object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
virtual UBool operator==(const UObject& other) const = 0;
|
||||
virtual UBool operator==(const UObject& other) const;
|
||||
|
||||
/**
|
||||
* Inequality operator. Return true if this object is not equal
|
||||
* to the given object.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
UBool operator!=(const UObject& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
const char *getType() const;
|
||||
|
||||
/**
|
||||
* Get the sub type.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
const char *getSubtype() const;
|
||||
|
||||
/**
|
||||
* getAvailable gets all of the available units.
|
||||
* If there are too many units to fit into destCapacity then the
|
||||
* error code is set to U_BUFFER_OVERFLOW_ERROR.
|
||||
*
|
||||
* @param destArray destination buffer.
|
||||
* @param destCapacity number of MeasureUnit instances available at dest.
|
||||
* @param errorCode ICU error code.
|
||||
* @return number of available units.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
static int32_t getAvailable(
|
||||
MeasureUnit *destArray,
|
||||
int32_t destCapacity,
|
||||
UErrorCode &errorCode);
|
||||
|
||||
/**
|
||||
* getAvailable gets all of the available units for a specific type.
|
||||
* If there are too many units to fit into destCapacity then the
|
||||
* error code is set to U_BUFFER_OVERFLOW_ERROR.
|
||||
*
|
||||
* @param type the type
|
||||
* @param destArray destination buffer.
|
||||
* @param destCapacity number of MeasureUnit instances available at dest.
|
||||
* @param errorCode ICU error code.
|
||||
* @return number of available units for type.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
static int32_t getAvailable(
|
||||
const char *type,
|
||||
MeasureUnit *destArray,
|
||||
int32_t destCapacity,
|
||||
UErrorCode &errorCode);
|
||||
|
||||
/**
|
||||
* getAvailableTypes gets all of the available types. Caller owns the
|
||||
* returned StringEnumeration and must delete it when finished using it.
|
||||
*
|
||||
* @param errorCode ICU error code.
|
||||
* @return the types.
|
||||
* @draft ICU 53
|
||||
*/
|
||||
static StringEnumeration* getAvailableTypes(UErrorCode &errorCode);
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* Returns associated array index for this measure unit. Only valid for
|
||||
* non-currency measure units.
|
||||
* @internal
|
||||
*/
|
||||
int32_t getIndex() const;
|
||||
|
||||
/**
|
||||
* ICU use only.
|
||||
* Returns maximum value from getIndex plus 1.
|
||||
* @internal
|
||||
*/
|
||||
static int32_t getIndexCount();
|
||||
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
// Start generated createXXX methods
|
||||
|
||||
/** Constant for unit of acceleration: g-force */
|
||||
static MeasureUnit *createGForce(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of angle: arc-minute */
|
||||
static MeasureUnit *createArcMinute(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of angle: arc-second */
|
||||
static MeasureUnit *createArcSecond(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of angle: degree */
|
||||
static MeasureUnit *createDegree(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of area: acre */
|
||||
static MeasureUnit *createAcre(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of area: hectare */
|
||||
static MeasureUnit *createHectare(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of area: square-foot */
|
||||
static MeasureUnit *createSquareFoot(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of area: square-kilometer */
|
||||
static MeasureUnit *createSquareKilometer(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of area: square-meter */
|
||||
static MeasureUnit *createSquareMeter(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of area: square-mile */
|
||||
static MeasureUnit *createSquareMile(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: day */
|
||||
static MeasureUnit *createDay(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: hour */
|
||||
static MeasureUnit *createHour(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: millisecond */
|
||||
static MeasureUnit *createMillisecond(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: minute */
|
||||
static MeasureUnit *createMinute(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: month */
|
||||
static MeasureUnit *createMonth(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: second */
|
||||
static MeasureUnit *createSecond(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: week */
|
||||
static MeasureUnit *createWeek(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of duration: year */
|
||||
static MeasureUnit *createYear(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: centimeter */
|
||||
static MeasureUnit *createCentimeter(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: foot */
|
||||
static MeasureUnit *createFoot(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: inch */
|
||||
static MeasureUnit *createInch(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: kilometer */
|
||||
static MeasureUnit *createKilometer(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: light-year */
|
||||
static MeasureUnit *createLightYear(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: meter */
|
||||
static MeasureUnit *createMeter(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: mile */
|
||||
static MeasureUnit *createMile(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: millimeter */
|
||||
static MeasureUnit *createMillimeter(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: picometer */
|
||||
static MeasureUnit *createPicometer(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of length: yard */
|
||||
static MeasureUnit *createYard(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of mass: gram */
|
||||
static MeasureUnit *createGram(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of mass: kilogram */
|
||||
static MeasureUnit *createKilogram(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of mass: ounce */
|
||||
static MeasureUnit *createOunce(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of mass: pound */
|
||||
static MeasureUnit *createPound(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of power: horsepower */
|
||||
static MeasureUnit *createHorsepower(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of power: kilowatt */
|
||||
static MeasureUnit *createKilowatt(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of power: watt */
|
||||
static MeasureUnit *createWatt(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of pressure: hectopascal */
|
||||
static MeasureUnit *createHectopascal(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of pressure: inch-hg */
|
||||
static MeasureUnit *createInchHg(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of pressure: millibar */
|
||||
static MeasureUnit *createMillibar(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of speed: kilometer-per-hour */
|
||||
static MeasureUnit *createKilometerPerHour(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of speed: meter-per-second */
|
||||
static MeasureUnit *createMeterPerSecond(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of speed: mile-per-hour */
|
||||
static MeasureUnit *createMilePerHour(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of temperature: celsius */
|
||||
static MeasureUnit *createCelsius(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of temperature: fahrenheit */
|
||||
static MeasureUnit *createFahrenheit(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of volume: cubic-kilometer */
|
||||
static MeasureUnit *createCubicKilometer(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of volume: cubic-mile */
|
||||
static MeasureUnit *createCubicMile(UErrorCode &status);
|
||||
|
||||
/** Constant for unit of volume: liter */
|
||||
static MeasureUnit *createLiter(UErrorCode &status);
|
||||
|
||||
protected:
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* Default constructor.
|
||||
* @stable ICU 3.0
|
||||
* For ICU use only.
|
||||
* @internal
|
||||
*/
|
||||
MeasureUnit();
|
||||
void initTime(const char *timeId);
|
||||
|
||||
/**
|
||||
* For ICU use only.
|
||||
* @internal
|
||||
*/
|
||||
void initCurrency(const char *isoCurrency);
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
int32_t fTypeId;
|
||||
int32_t fSubTypeId;
|
||||
char fCurrency[4];
|
||||
|
||||
MeasureUnit(int32_t typeId, int32_t subTypeId) : fTypeId(typeId), fSubTypeId(subTypeId) {
|
||||
fCurrency[0] = 0;
|
||||
}
|
||||
void setTo(int32_t typeId, int32_t subTypeId);
|
||||
int32_t getOffset() const;
|
||||
static MeasureUnit *create(int typeId, int subTypeId, UErrorCode &status);
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
// NOTE: There is no measunit.cpp. For implementation, see measure.cpp. [alan]
|
||||
|
||||
#endif // !UCONFIG_NO_FORMATTING
|
||||
#endif // __MEASUREUNIT_H__
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2004-2006, International Business Machines
|
||||
* Copyright (c) 2004-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
@ -74,7 +74,7 @@ class U_I18N_API Measure: public UObject {
|
||||
* have the same class as returned by getDynamicClassID().
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
virtual UObject* clone() const = 0;
|
||||
virtual UObject* clone() const;
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2009-2010, Google, International Business Machines Corporation and *
|
||||
* Copyright (C) 2009-2014, Google, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -76,20 +76,6 @@ public:
|
||||
*/
|
||||
TimeUnit& operator=(const TimeUnit& other);
|
||||
|
||||
/**
|
||||
* Equality operator.
|
||||
* @return true if 2 objects are the same.
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
virtual UBool operator==(const UObject& other) const;
|
||||
|
||||
/**
|
||||
* Non-Equality operator.
|
||||
* @return true if 2 objects are not the same.
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
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.
|
||||
@ -134,12 +120,6 @@ private:
|
||||
};
|
||||
|
||||
|
||||
inline UBool
|
||||
TimeUnit::operator!=(const UObject& other) const {
|
||||
return !operator==(other);
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2008-2013, Google, International Business Machines Corporation
|
||||
* Copyright (C) 2008-2014, Google, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -125,16 +125,6 @@ public:
|
||||
*/
|
||||
TimeUnitFormat& operator=(const TimeUnitFormat& other);
|
||||
|
||||
|
||||
/**
|
||||
* Return true if the given Format objects are semantically equal. Objects
|
||||
* of different subclasses are considered unequal.
|
||||
* @param other the object to be compared with.
|
||||
* @return true if the given Format objects are semantically equal.
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
virtual UBool operator==(const Format& other) const;
|
||||
|
||||
/**
|
||||
* Return true if the given Format objects are not semantically equal.
|
||||
* Objects of different subclasses are considered unequal.
|
||||
@ -161,22 +151,6 @@ public:
|
||||
*/
|
||||
void setNumberFormat(const NumberFormat& format, UErrorCode& status);
|
||||
|
||||
|
||||
using MeasureFormat::format;
|
||||
|
||||
/**
|
||||
* Format a TimeUnitAmount.
|
||||
* If the formattable object is not a time unit amount object,
|
||||
* or the number in time unit amount is not a double type or long type
|
||||
* numeric, it returns a failing status: U_ILLEGAL_ARGUMENT_ERROR.
|
||||
* @see Format#format(const Formattable&, UnicodeString&, FieldPosition&, UErrorCode&) const
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
virtual UnicodeString& format(const Formattable& obj,
|
||||
UnicodeString& toAppendTo,
|
||||
FieldPosition& pos,
|
||||
UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Parse a TimeUnitAmount.
|
||||
* @see Format#parseObject(const UnicodeString&, Formattable&, ParsePosition&) const;
|
||||
@ -213,13 +187,10 @@ public:
|
||||
virtual UClassID getDynamicClassID(void) const;
|
||||
|
||||
private:
|
||||
NumberFormat* fNumberFormat;
|
||||
Locale fLocale;
|
||||
Hashtable* fTimeUnitToCountToPatterns[TimeUnit::UTIMEUNIT_FIELD_COUNT];
|
||||
PluralRules* fPluralRules;
|
||||
UTimeUnitFormatStyle fStyle;
|
||||
|
||||
void create(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status);
|
||||
void create(UTimeUnitFormatStyle style, UErrorCode& status);
|
||||
|
||||
// it might actually be simpler to make them Decimal Formats later.
|
||||
// initialize all private data members
|
||||
|
@ -56,7 +56,7 @@ uobjtest.o idnaref.o idnaconf.o nptrans.o punyref.o testidn.o testidna.o uts46te
|
||||
incaltst.o calcasts.o v32test.o uvectest.o textfile.o tokiter.o utxttest.o \
|
||||
windttst.o winnmtst.o winutil.o csdetest.o tzrulets.o tzoffloc.o tzfmttst.o ssearch.o dtifmtts.o \
|
||||
tufmtts.o itspoof.o simplethread.o bidiconf.o locnmtst.o dcfmtest.o alphaindextst.o listformattertest.o genderinfotest.o compactdecimalformattest.o regiontst.o \
|
||||
reldatefmttest.o lrucachetest.o simplepatternformattertest.o
|
||||
reldatefmttest.o lrucachetest.o simplepatternformattertest.o measfmttest.o
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d)
|
||||
|
||||
|
@ -308,6 +308,7 @@
|
||||
<ClCompile Include="lrucachetest.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="measfmttest.cpp" />
|
||||
<ClCompile Include="miscdtfm.cpp" />
|
||||
<ClCompile Include="msfmrgts.cpp" />
|
||||
<ClCompile Include="nmfmapts.cpp" />
|
||||
|
@ -241,6 +241,9 @@
|
||||
<ClCompile Include="locnmtst.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="measfmttest.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="miscdtfm.cpp">
|
||||
<Filter>formatting</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2013, International Business Machines
|
||||
* Copyright (c) 1997-2014, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
|
||||
@ -62,6 +62,7 @@
|
||||
extern IntlTest *createCompactDecimalFormatTest();
|
||||
extern IntlTest *createGenderInfoTest();
|
||||
extern IntlTest *createRelativeDateTimeFormatterTest();
|
||||
extern IntlTest *createMeasureFormatTest();
|
||||
|
||||
#define TESTCLASS(id, TestClass) \
|
||||
case id: \
|
||||
@ -167,6 +168,15 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam
|
||||
callTest(*test, par);
|
||||
}
|
||||
break;
|
||||
case 47:
|
||||
name = "MeasureFormatTest";
|
||||
if (exec) {
|
||||
logln("MeasureFormatTest test---");
|
||||
logln((UnicodeString)"");
|
||||
LocalPointer<IntlTest> test(createMeasureFormatTest());
|
||||
callTest(*test, par);
|
||||
}
|
||||
break;
|
||||
default: name = ""; break; //needed to end loop
|
||||
}
|
||||
if (exec) {
|
||||
|
901
icu4c/source/test/intltest/measfmttest.cpp
Normal file
901
icu4c/source/test/intltest/measfmttest.cpp
Normal file
@ -0,0 +1,901 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
* File MEASFMTTEST.CPP
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "intltest.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/decimfmt.h"
|
||||
#include "unicode/measfmt.h"
|
||||
#include "unicode/measure.h"
|
||||
#include "unicode/measunit.h"
|
||||
#include "unicode/tmutamt.h"
|
||||
#include "charstr.h"
|
||||
|
||||
#define LENGTHOF(array) (int32_t)(sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
struct ExpectedResult {
|
||||
const Measure *measures;
|
||||
int32_t count;
|
||||
const char *expected;
|
||||
};
|
||||
|
||||
class MeasureFormatTest : public IntlTest {
|
||||
public:
|
||||
MeasureFormatTest() {
|
||||
}
|
||||
|
||||
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par=0);
|
||||
private:
|
||||
void TestBasic();
|
||||
void TestGetAvailable();
|
||||
void TestExamplesInDocs();
|
||||
void TestFormatPeriodEn();
|
||||
void Test10219FractionalPlurals();
|
||||
void TestGreek();
|
||||
void TestFormatSingleArg();
|
||||
void TestFormatMeasuresZeroArg();
|
||||
void TestMultiples();
|
||||
void TestGram();
|
||||
void TestCurrencies();
|
||||
void TestFieldPosition();
|
||||
void TestFieldPositionMultiple();
|
||||
void TestBadArg();
|
||||
void TestEquality();
|
||||
void verifyFormat(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
const char *expected);
|
||||
void verifyFormatWithPrefix(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const UnicodeString &prefix,
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
const char *expected);
|
||||
void verifyFormat(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const ExpectedResult *expectedResults,
|
||||
int32_t count);
|
||||
void helperTestMultiples(
|
||||
const Locale &locale,
|
||||
UMeasureFormatWidth width,
|
||||
const char *expected);
|
||||
void verifyFieldPosition(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const UnicodeString &prefix,
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
NumberFormat::EAlignmentFields field,
|
||||
int32_t start,
|
||||
int32_t end);
|
||||
};
|
||||
|
||||
void MeasureFormatTest::runIndexedTest(
|
||||
int32_t index, UBool exec, const char *&name, char *) {
|
||||
if (exec) {
|
||||
logln("TestSuite MeasureFormatTest: ");
|
||||
}
|
||||
TESTCASE_AUTO_BEGIN;
|
||||
TESTCASE_AUTO(TestBasic);
|
||||
TESTCASE_AUTO(TestGetAvailable);
|
||||
TESTCASE_AUTO(TestExamplesInDocs);
|
||||
TESTCASE_AUTO(TestFormatPeriodEn);
|
||||
TESTCASE_AUTO(Test10219FractionalPlurals);
|
||||
TESTCASE_AUTO(TestGreek);
|
||||
TESTCASE_AUTO(TestFormatSingleArg);
|
||||
TESTCASE_AUTO(TestFormatMeasuresZeroArg);
|
||||
TESTCASE_AUTO(TestMultiples);
|
||||
TESTCASE_AUTO(TestGram);
|
||||
TESTCASE_AUTO(TestCurrencies);
|
||||
TESTCASE_AUTO(TestFieldPosition);
|
||||
TESTCASE_AUTO(TestFieldPositionMultiple);
|
||||
TESTCASE_AUTO(TestBadArg);
|
||||
TESTCASE_AUTO(TestEquality);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestBasic() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureUnit *ptr1 = MeasureUnit::createArcMinute(status);
|
||||
MeasureUnit *ptr2 = MeasureUnit::createArcMinute(status);
|
||||
if (!(*ptr1 == *ptr2)) {
|
||||
errln("Expect == to work.");
|
||||
}
|
||||
if (*ptr1 != *ptr2) {
|
||||
errln("Expect != to work.");
|
||||
}
|
||||
MeasureUnit *ptr3 = MeasureUnit::createMeter(status);
|
||||
if (*ptr1 == *ptr3) {
|
||||
errln("Expect == to work.");
|
||||
}
|
||||
if (!(*ptr1 != *ptr3)) {
|
||||
errln("Expect != to work.");
|
||||
}
|
||||
MeasureUnit *ptr4 = (MeasureUnit *) ptr1->clone();
|
||||
if (*ptr1 != *ptr4) {
|
||||
errln("Expect clone to work.");
|
||||
}
|
||||
MeasureUnit stack;
|
||||
stack = *ptr1;
|
||||
if (*ptr1 != stack) {
|
||||
errln("Expect assignment to work.");
|
||||
}
|
||||
|
||||
delete ptr1;
|
||||
delete ptr2;
|
||||
delete ptr3;
|
||||
delete ptr4;
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestGetAvailable() {
|
||||
MeasureUnit *units = NULL;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t totalCount = MeasureUnit::getAvailable(units, 0, status);
|
||||
while (status == U_BUFFER_OVERFLOW_ERROR) {
|
||||
status = U_ZERO_ERROR;
|
||||
delete [] units;
|
||||
units = new MeasureUnit[totalCount];
|
||||
totalCount = MeasureUnit::getAvailable(units, totalCount, status);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Failure creating format object - %s", u_errorName(status));
|
||||
delete [] units;
|
||||
return;
|
||||
}
|
||||
if (totalCount < 200) {
|
||||
errln("Expect at least 200 measure units including currencies.");
|
||||
}
|
||||
delete [] units;
|
||||
StringEnumeration *types = MeasureUnit::getAvailableTypes(status);
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Failure getting types - %s", u_errorName(status));
|
||||
delete types;
|
||||
return;
|
||||
}
|
||||
if (types->count(status) < 10) {
|
||||
errln("Expect at least 10 distinct unit types.");
|
||||
}
|
||||
units = NULL;
|
||||
int32_t unitCapacity = 0;
|
||||
int32_t unitCountSum = 0;
|
||||
for (
|
||||
const char* type = types->next(NULL, status);
|
||||
type != NULL;
|
||||
type = types->next(NULL, status)) {
|
||||
int32_t unitCount = MeasureUnit::getAvailable(type, units, unitCapacity, status);
|
||||
while (status == U_BUFFER_OVERFLOW_ERROR) {
|
||||
status = U_ZERO_ERROR;
|
||||
delete [] units;
|
||||
units = new MeasureUnit[unitCount];
|
||||
unitCapacity = unitCount;
|
||||
unitCount = MeasureUnit::getAvailable(type, units, unitCapacity, status);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Failure getting units - %s", u_errorName(status));
|
||||
delete [] units;
|
||||
delete types;
|
||||
return;
|
||||
}
|
||||
if (unitCount < 1) {
|
||||
errln("Expect at least one unit count per type.");
|
||||
}
|
||||
unitCountSum += unitCount;
|
||||
}
|
||||
if (unitCountSum != totalCount) {
|
||||
errln("Expected total unit count to equal sum of unit counts by type.");
|
||||
}
|
||||
delete [] units;
|
||||
delete types;
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestExamplesInDocs() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmtFr(Locale::getFrench(), UMEASFMT_WIDTH_SHORT, status);
|
||||
MeasureFormat fmtFrFull(
|
||||
Locale::getFrench(), UMEASFMT_WIDTH_WIDE, status);
|
||||
MeasureFormat fmtFrNarrow(
|
||||
Locale::getFrench(), UMEASFMT_WIDTH_NARROW, status);
|
||||
MeasureFormat fmtEn(Locale::getUS(), UMEASFMT_WIDTH_WIDE, status);
|
||||
if (!assertSuccess("Error creating formatters", status)) {
|
||||
return;
|
||||
}
|
||||
Measure measureC(23, MeasureUnit::createCelsius(status), status);
|
||||
Measure measureF(70, MeasureUnit::createFahrenheit(status), status);
|
||||
Measure feetAndInches[] = {
|
||||
Measure(70, MeasureUnit::createFoot(status), status),
|
||||
Measure(5.3, MeasureUnit::createInch(status), status)};
|
||||
Measure footAndInch[] = {
|
||||
Measure(1, MeasureUnit::createFoot(status), status),
|
||||
Measure(1, MeasureUnit::createInch(status), status)};
|
||||
Measure inchAndFeet[] = {
|
||||
Measure(1, MeasureUnit::createInch(status), status),
|
||||
Measure(2, MeasureUnit::createFoot(status), status)};
|
||||
if (!assertSuccess("Error creating measurements.", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat(
|
||||
"Celsius",
|
||||
fmtFr,
|
||||
&measureC,
|
||||
1,
|
||||
"23 \\u00B0C");
|
||||
verifyFormatWithPrefix(
|
||||
"Celsius",
|
||||
fmtFr,
|
||||
"Prefix: ",
|
||||
&measureC,
|
||||
1,
|
||||
"Prefix: 23 \\u00B0C");
|
||||
verifyFormat(
|
||||
"Fahrenheit",
|
||||
fmtFr,
|
||||
&measureF,
|
||||
1,
|
||||
"70 \\u00B0F");
|
||||
verifyFormat(
|
||||
"Feet and inches",
|
||||
fmtFrFull,
|
||||
feetAndInches,
|
||||
LENGTHOF(feetAndInches),
|
||||
"70 pieds et 5,3 pouces");
|
||||
verifyFormatWithPrefix(
|
||||
"Feet and inches",
|
||||
fmtFrFull,
|
||||
"Prefix: ",
|
||||
feetAndInches,
|
||||
LENGTHOF(feetAndInches),
|
||||
"Prefix: 70 pieds et 5,3 pouces");
|
||||
verifyFormat(
|
||||
"Foot and inch",
|
||||
fmtFrFull,
|
||||
footAndInch,
|
||||
LENGTHOF(footAndInch),
|
||||
"1 pied et 1 pouce");
|
||||
verifyFormat(
|
||||
"Foot and inch narrow",
|
||||
fmtFrNarrow,
|
||||
footAndInch,
|
||||
LENGTHOF(footAndInch),
|
||||
"1\\u2032 1\\u2033");
|
||||
verifyFormat(
|
||||
"Inch and feet",
|
||||
fmtEn,
|
||||
inchAndFeet,
|
||||
LENGTHOF(inchAndFeet),
|
||||
"1 inch, 2 feet");
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestFormatPeriodEn() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Measure t_19m[] = {Measure(19, MeasureUnit::createMinute(status), status)};
|
||||
Measure t_1h_23_5s[] = {
|
||||
Measure(1.0, MeasureUnit::createHour(status), status),
|
||||
Measure(23.5, MeasureUnit::createSecond(status), status)
|
||||
};
|
||||
Measure t_1h_23_5m[] = {
|
||||
Measure(1.0, MeasureUnit::createHour(status), status),
|
||||
Measure(23.5, MeasureUnit::createMinute(status), status)
|
||||
};
|
||||
Measure t_1h_0m_23s[] = {
|
||||
Measure(1.0, MeasureUnit::createHour(status), status),
|
||||
Measure(0.0, MeasureUnit::createMinute(status), status),
|
||||
Measure(23, MeasureUnit::createSecond(status), status)
|
||||
};
|
||||
Measure t_2y_5M_3w_4d[] = {
|
||||
Measure(2.0, MeasureUnit::createYear(status), status),
|
||||
Measure(5.0, MeasureUnit::createMonth(status), status),
|
||||
Measure(3.0, MeasureUnit::createWeek(status), status),
|
||||
Measure(4.0, MeasureUnit::createDay(status), status)
|
||||
};
|
||||
Measure t_1m_59_9996s[] = {
|
||||
Measure(1.0, MeasureUnit::createMinute(status), status),
|
||||
Measure(59.9996, MeasureUnit::createSecond(status), status)
|
||||
};
|
||||
Measure t_5h_17m[] = {
|
||||
Measure(5.0, MeasureUnit::createHour(status), status),
|
||||
Measure(17.0, MeasureUnit::createMinute(status), status)
|
||||
};
|
||||
Measure t_19m_28s[] = {
|
||||
Measure(19.0, MeasureUnit::createMinute(status), status),
|
||||
Measure(28.0, MeasureUnit::createSecond(status), status)
|
||||
};
|
||||
Measure t_0h_0m_17s[] = {
|
||||
Measure(0.0, MeasureUnit::createHour(status), status),
|
||||
Measure(0.0, MeasureUnit::createMinute(status), status),
|
||||
Measure(17.0, MeasureUnit::createSecond(status), status)
|
||||
};
|
||||
Measure t_6h_56_92m[] = {
|
||||
Measure(6.0, MeasureUnit::createHour(status), status),
|
||||
Measure(56.92, MeasureUnit::createMinute(status), status)
|
||||
};
|
||||
Measure t_3h_5h[] = {
|
||||
Measure(3.0, MeasureUnit::createHour(status), status),
|
||||
Measure(5.0, MeasureUnit::createHour(status), status)
|
||||
};
|
||||
|
||||
if (!assertSuccess("Error creating Measure objects", status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ExpectedResult fullData[] = {
|
||||
{t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1 minute, 59.9996 seconds"},
|
||||
{t_19m, LENGTHOF(t_19m), "19 minutes"},
|
||||
{t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1 hour, 23.5 seconds"},
|
||||
{t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1 hour, 23.5 minutes"},
|
||||
{t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1 hour, 0 minutes, 23 seconds"},
|
||||
{t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 years, 5 months, 3 weeks, 4 days"}};
|
||||
|
||||
ExpectedResult abbrevData[] = {
|
||||
{t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1 min, 59.9996 secs"},
|
||||
{t_19m, LENGTHOF(t_19m), "19 mins"},
|
||||
{t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1 hr, 23.5 secs"},
|
||||
{t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1 hr, 23.5 mins"},
|
||||
{t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1 hr, 0 mins, 23 secs"},
|
||||
{t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 yrs, 5 mths, 3 wks, 4 days"}};
|
||||
|
||||
ExpectedResult narrowData[] = {
|
||||
{t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1m 59.9996s"},
|
||||
{t_19m, LENGTHOF(t_19m), "19m"},
|
||||
{t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1h 23.5s"},
|
||||
{t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1h 23.5m"},
|
||||
{t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1h 0m 23s"},
|
||||
{t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2y 5m 3w 4d"}};
|
||||
|
||||
ExpectedResult numericData[] = {
|
||||
{t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1:59.9996"},
|
||||
{t_19m, LENGTHOF(t_19m), "19m"},
|
||||
{t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1:00:23.5"},
|
||||
{t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1:23.5"},
|
||||
{t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1:00:23"},
|
||||
{t_5h_17m, LENGTHOF(t_5h_17m), "5:17"},
|
||||
{t_19m_28s, LENGTHOF(t_19m_28s), "19:28"},
|
||||
{t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2y 5m 3w 4d"},
|
||||
{t_0h_0m_17s, LENGTHOF(t_0h_0m_17s), "0:00:17"},
|
||||
{t_6h_56_92m, LENGTHOF(t_6h_56_92m), "6:56.92"},
|
||||
{t_3h_5h, LENGTHOF(t_3h_5h), "3h 5h"}};
|
||||
|
||||
ExpectedResult fullDataDe[] = {
|
||||
{t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1 Minute und 59,9996 Sekunden"},
|
||||
{t_19m, LENGTHOF(t_19m), "19 Minuten"},
|
||||
{t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1 Stunde und 23,5 Sekunden"},
|
||||
{t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1 Stunde und 23,5 Minuten"},
|
||||
{t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1 Stunde, 0 Minuten und 23 Sekunden"},
|
||||
{t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 Jahre, 5 Monate, 3 Wochen und 4 Tage"}};
|
||||
|
||||
ExpectedResult numericDataDe[] = {
|
||||
{t_1m_59_9996s, LENGTHOF(t_1m_59_9996s), "1:59,9996"},
|
||||
{t_19m, LENGTHOF(t_19m), "19 Min."},
|
||||
{t_1h_23_5s, LENGTHOF(t_1h_23_5s), "1:00:23,5"},
|
||||
{t_1h_23_5m, LENGTHOF(t_1h_23_5m), "1:23,5"},
|
||||
{t_1h_0m_23s, LENGTHOF(t_1h_0m_23s), "1:00:23"},
|
||||
{t_5h_17m, LENGTHOF(t_5h_17m), "5:17"},
|
||||
{t_19m_28s, LENGTHOF(t_19m_28s), "19:28"},
|
||||
{t_2y_5M_3w_4d, LENGTHOF(t_2y_5M_3w_4d), "2 J, 5 M, 3 W und 4 T"},
|
||||
{t_0h_0m_17s, LENGTHOF(t_0h_0m_17s), "0:00:17"},
|
||||
{t_6h_56_92m, LENGTHOF(t_6h_56_92m), "6:56,92"},
|
||||
{t_3h_5h, LENGTHOF(t_3h_5h), "3 Std., 5 Std."}};
|
||||
|
||||
Locale en(Locale::getEnglish());
|
||||
LocalPointer<NumberFormat> nf(NumberFormat::createInstance(en, status));
|
||||
if (!assertSuccess("Error creating number format en object", status)) {
|
||||
return;
|
||||
}
|
||||
nf->setMaximumFractionDigits(4);
|
||||
MeasureFormat mf(en, UMEASFMT_WIDTH_WIDE, (NumberFormat *) nf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format en WIDE", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("en WIDE", mf, fullData, LENGTHOF(fullData));
|
||||
|
||||
// exercise copy constructor
|
||||
{
|
||||
MeasureFormat mf2(mf);
|
||||
verifyFormat("en WIDE copy", mf2, fullData, LENGTHOF(fullData));
|
||||
}
|
||||
// exercise clone
|
||||
{
|
||||
MeasureFormat *mf3 = (MeasureFormat *) mf.clone();
|
||||
verifyFormat("en WIDE copy", *mf3, fullData, LENGTHOF(fullData));
|
||||
delete mf3;
|
||||
}
|
||||
mf = MeasureFormat(en, UMEASFMT_WIDTH_SHORT, (NumberFormat *) nf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format en SHORT", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("en SHORT", mf, abbrevData, LENGTHOF(abbrevData));
|
||||
mf = MeasureFormat(en, UMEASFMT_WIDTH_NARROW, (NumberFormat *) nf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format en NARROW", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("en NARROW", mf, narrowData, LENGTHOF(narrowData));
|
||||
mf = MeasureFormat(en, UMEASFMT_WIDTH_NUMERIC, (NumberFormat *) nf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format en NUMERIC", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("en NUMERIC", mf, numericData, LENGTHOF(numericData));
|
||||
|
||||
Locale de(Locale::getGerman());
|
||||
nf.adoptInstead(NumberFormat::createInstance(de, status));
|
||||
if (!assertSuccess("Error creating number format de object", status)) {
|
||||
return;
|
||||
}
|
||||
nf->setMaximumFractionDigits(4);
|
||||
mf = MeasureFormat(de, UMEASFMT_WIDTH_WIDE, (NumberFormat *) nf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format de WIDE", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("de WIDE", mf, fullDataDe, LENGTHOF(fullDataDe));
|
||||
mf = MeasureFormat(de, UMEASFMT_WIDTH_NUMERIC, (NumberFormat *) nf->clone(), status);
|
||||
if (!assertSuccess("Error creating measure format de NUMERIC", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("de NUMERIC", mf, numericDataDe, LENGTHOF(numericDataDe));
|
||||
}
|
||||
|
||||
void MeasureFormatTest::Test10219FractionalPlurals() {
|
||||
Locale en(Locale::getEnglish());
|
||||
double values[] = {1.588, 1.011};
|
||||
const char *expected[2][3] = {
|
||||
{"1 minute", "1.5 minutes", "1.58 minutes"},
|
||||
{"1 minute", "1.0 minutes", "1.01 minutes"}
|
||||
};
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
for (int j = 0; j < LENGTHOF(values); j++) {
|
||||
for (int i = 0; i < LENGTHOF(expected[j]); i++) {
|
||||
DecimalFormat *df =
|
||||
(DecimalFormat *) NumberFormat::createInstance(en, status);
|
||||
if (!assertSuccess("Error creating Number format", status)) {
|
||||
return;
|
||||
}
|
||||
df->setRoundingMode(DecimalFormat::kRoundDown);
|
||||
df->setMinimumFractionDigits(i);
|
||||
df->setMaximumFractionDigits(i);
|
||||
MeasureFormat mf(en, UMEASFMT_WIDTH_WIDE, df, status);
|
||||
if (!assertSuccess("Error creating Measure format", status)) {
|
||||
return;
|
||||
}
|
||||
Measure measure(values[j], MeasureUnit::createMinute(status), status);
|
||||
if (!assertSuccess("Error creating Measure unit", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("Test10219", mf, &measure, 1, expected[j][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MeasureUnit toMeasureUnit(MeasureUnit *adopted) {
|
||||
MeasureUnit result(*adopted);
|
||||
delete adopted;
|
||||
return result;
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestGreek() {
|
||||
Locale locales[] = {Locale("el_GR"), Locale("el")};
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureUnit units[] = {
|
||||
toMeasureUnit(MeasureUnit::createSecond(status)),
|
||||
toMeasureUnit(MeasureUnit::createMinute(status)),
|
||||
toMeasureUnit(MeasureUnit::createHour(status)),
|
||||
toMeasureUnit(MeasureUnit::createDay(status)),
|
||||
toMeasureUnit(MeasureUnit::createWeek(status)),
|
||||
toMeasureUnit(MeasureUnit::createMonth(status)),
|
||||
toMeasureUnit(MeasureUnit::createYear(status))};
|
||||
if (!assertSuccess("Error creating Measure units", status)) {
|
||||
return;
|
||||
}
|
||||
UMeasureFormatWidth styles[] = {
|
||||
UMEASFMT_WIDTH_WIDE,
|
||||
UMEASFMT_WIDTH_SHORT};
|
||||
int32_t numbers[] = {1, 7};
|
||||
const char *expected[] = {
|
||||
"1 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03BF",
|
||||
"1 \\u03BB\\u03B5\\u03C0\\u03C4\\u03CC",
|
||||
"1 \\u03CE\\u03C1\\u03B1",
|
||||
"1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
|
||||
"1 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B1",
|
||||
"1 \\u03BC\\u03AE\\u03BD\\u03B1\\u03C2",
|
||||
"1 \\u03AD\\u03C4\\u03BF\\u03C2",
|
||||
"1 \\u03B4\\u03B5\\u03C5\\u03C4.",
|
||||
"1 \\u03BB\\u03B5\\u03C0.",
|
||||
"1 \\u03CE\\u03C1\\u03B1",
|
||||
"1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
|
||||
"1 \\u03B5\\u03B2\\u03B4.",
|
||||
"1 \\u03BC\\u03AE\\u03BD.",
|
||||
"1 \\u03AD\\u03C4\\u03BF\\u03C2",
|
||||
"7 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03B1",
|
||||
"7 \\u03BB\\u03B5\\u03C0\\u03C4\\u03AC",
|
||||
"7 \\u03CE\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B5\\u03C2",
|
||||
"7 \\u03BC\\u03AE\\u03BD\\u03B5\\u03C2",
|
||||
"7 \\u03AD\\u03C4\\u03B7",
|
||||
"7 \\u03B4\\u03B5\\u03C5\\u03C4.",
|
||||
"7 \\u03BB\\u03B5\\u03C0.",
|
||||
"7 \\u03CE\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B5\\u03B2\\u03B4.",
|
||||
"7 \\u03BC\\u03AE\\u03BD.",
|
||||
"7 \\u03AD\\u03C4\\u03B7",
|
||||
"1 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03BF",
|
||||
"1 \\u03BB\\u03B5\\u03C0\\u03C4\\u03CC",
|
||||
"1 \\u03CE\\u03C1\\u03B1",
|
||||
"1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
|
||||
"1 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B1",
|
||||
"1 \\u03BC\\u03AE\\u03BD\\u03B1\\u03C2",
|
||||
"1 \\u03AD\\u03C4\\u03BF\\u03C2",
|
||||
"1 \\u03B4\\u03B5\\u03C5\\u03C4.",
|
||||
"1 \\u03BB\\u03B5\\u03C0.",
|
||||
"1 \\u03CE\\u03C1\\u03B1",
|
||||
"1 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B1",
|
||||
"1 \\u03B5\\u03B2\\u03B4.",
|
||||
"1 \\u03BC\\u03AE\\u03BD.",
|
||||
"1 \\u03AD\\u03C4\\u03BF\\u03C2",
|
||||
"7 \\u03B4\\u03B5\\u03C5\\u03C4\\u03B5\\u03C1\\u03CC\\u03BB\\u03B5\\u03C0\\u03C4\\u03B1",
|
||||
"7 \\u03BB\\u03B5\\u03C0\\u03C4\\u03AC",
|
||||
"7 \\u03CE\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B5\\u03B2\\u03B4\\u03BF\\u03BC\\u03AC\\u03B4\\u03B5\\u03C2",
|
||||
"7 \\u03BC\\u03AE\\u03BD\\u03B5\\u03C2",
|
||||
"7 \\u03AD\\u03C4\\u03B7",
|
||||
"7 \\u03B4\\u03B5\\u03C5\\u03C4.",
|
||||
"7 \\u03BB\\u03B5\\u03C0.",
|
||||
"7 \\u03CE\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B7\\u03BC\\u03AD\\u03C1\\u03B5\\u03C2",
|
||||
"7 \\u03B5\\u03B2\\u03B4.",
|
||||
"7 \\u03BC\\u03AE\\u03BD.",
|
||||
"7 \\u03AD\\u03C4\\u03B7"};
|
||||
|
||||
int32_t counter = 0;
|
||||
for (int32_t locIndex = 0; locIndex < LENGTHOF(locales); ++locIndex ) {
|
||||
for( int32_t numIndex = 0; numIndex < LENGTHOF(numbers); ++numIndex ) {
|
||||
for ( int32_t styleIndex = 0; styleIndex < LENGTHOF(styles); ++styleIndex ) {
|
||||
for ( int32_t unitIndex = 0; unitIndex < LENGTHOF(units); ++unitIndex ) {
|
||||
Measure measure(numbers[numIndex], new MeasureUnit(units[unitIndex]), status);
|
||||
if (!assertSuccess("Error creating Measure", status)) {
|
||||
return;
|
||||
}
|
||||
MeasureFormat fmt(locales[locIndex], styles[styleIndex], status);
|
||||
if (!assertSuccess("Error creating Measure format", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("TestGreek", fmt, &measure, 1, expected[counter]);
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestFormatSingleArg() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, status);
|
||||
if (!assertSuccess("Error creating formatter", status)) {
|
||||
return;
|
||||
}
|
||||
UnicodeString buffer;
|
||||
FieldPosition pos(0);
|
||||
fmt.format(
|
||||
new Measure(3.5, MeasureUnit::createFoot(status), status),
|
||||
buffer,
|
||||
pos,
|
||||
status);
|
||||
if (!assertSuccess("Error formatting", status)) {
|
||||
return;
|
||||
}
|
||||
assertEquals(
|
||||
"TestFormatSingleArg",
|
||||
UnicodeString("3.5 feet"),
|
||||
buffer);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestFormatMeasuresZeroArg() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_WIDE, status);
|
||||
verifyFormat("TestFormatMeasuresZeroArg", fmt, NULL, 0, "");
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestMultiples() {
|
||||
Locale ru("ru");
|
||||
Locale en("en");
|
||||
helperTestMultiples(en, UMEASFMT_WIDTH_WIDE, "2 miles, 1 foot, 2.3 inches");
|
||||
helperTestMultiples(en, UMEASFMT_WIDTH_SHORT, "2 mi, 1 ft, 2.3 in");
|
||||
helperTestMultiples(en, UMEASFMT_WIDTH_NARROW, "2mi 1\\u2032 2.3\\u2033");
|
||||
helperTestMultiples(ru, UMEASFMT_WIDTH_WIDE, "2 \\u043C\\u0438\\u043B\\u0438, 1 \\u0444\\u0443\\u0442 \\u0438 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430");
|
||||
helperTestMultiples(ru, UMEASFMT_WIDTH_SHORT, "2 \\u043C\\u0438\\u043B\\u0438 1 \\u0444\\u0443\\u0442 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430");
|
||||
helperTestMultiples(ru, UMEASFMT_WIDTH_NARROW, "2 \\u043C\\u0438\\u043B\\u0438, 1 \\u0444\\u0443\\u0442, 2,3 \\u0434\\u044E\\u0439\\u043C\\u0430");
|
||||
}
|
||||
|
||||
void MeasureFormatTest::helperTestMultiples(
|
||||
const Locale &locale,
|
||||
UMeasureFormatWidth width,
|
||||
const char *expected) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
FieldPosition pos(0);
|
||||
MeasureFormat fmt(locale, width, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
Measure measures[] = {
|
||||
Measure(2, MeasureUnit::createMile(status), status),
|
||||
Measure(1, MeasureUnit::createFoot(status), status),
|
||||
Measure(2.3, MeasureUnit::createInch(status), status)};
|
||||
if (!assertSuccess("Error creating measures", status)) {
|
||||
return;
|
||||
}
|
||||
UnicodeString buffer;
|
||||
fmt.formatMeasures(measures, LENGTHOF(measures), buffer, pos, status);
|
||||
if (!assertSuccess("Error formatting measures", status)) {
|
||||
return;
|
||||
}
|
||||
assertEquals("TestMultiples", UnicodeString(expected).unescape(), buffer);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestGram() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
Measure gram(1, MeasureUnit::createGram(status), status);
|
||||
Measure gforce(1, MeasureUnit::createGForce(status), status);
|
||||
if (!assertSuccess("Error creating measures", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("TestGram", fmt, &gram, 1, "1 g");
|
||||
verifyFormat("TestGram", fmt, &gforce, 1, "1 G");
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestCurrencies() {
|
||||
UChar USD[] = {'U', 'S', 'D', 0};
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
CurrencyAmount USD_1(1.0, USD, status);
|
||||
CurrencyAmount USD_2(2.0, USD, status);
|
||||
CurrencyAmount USD_NEG_1(-1.0, USD, status);
|
||||
if (!assertSuccess("Error creating measures", status)) {
|
||||
return;
|
||||
}
|
||||
Locale en("en");
|
||||
MeasureFormat fmt(en, UMEASFMT_WIDTH_WIDE, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("TestCurrenciesWide", fmt, &USD_NEG_1, 1, "-1.00 US dollars");
|
||||
verifyFormat("TestCurrenciesWide", fmt, &USD_1, 1, "1.00 US dollars");
|
||||
verifyFormat("TestCurrenciesWide", fmt, &USD_2, 1, "2.00 US dollars");
|
||||
fmt = MeasureFormat(en, UMEASFMT_WIDTH_SHORT, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("TestCurrenciesShort", fmt, &USD_NEG_1, 1, "-USD1.00");
|
||||
verifyFormat("TestCurrenciesShort", fmt, &USD_1, 1, "USD1.00");
|
||||
verifyFormat("TestCurrenciesShort", fmt, &USD_2, 1, "USD2.00");
|
||||
fmt = MeasureFormat(en, UMEASFMT_WIDTH_NARROW, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("TestCurrenciesNarrow", fmt, &USD_NEG_1, 1, "-$1.00");
|
||||
verifyFormat("TestCurrenciesNarrow", fmt, &USD_1, 1, "$1.00");
|
||||
verifyFormat("TestCurrenciesNarrow", fmt, &USD_2, 1, "$2.00");
|
||||
fmt = MeasureFormat(en, UMEASFMT_WIDTH_NUMERIC, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFormat("TestCurrenciesNumeric", fmt, &USD_NEG_1, 1, "-$1.00");
|
||||
verifyFormat("TestCurrenciesNumeric", fmt, &USD_1, 1, "$1.00");
|
||||
verifyFormat("TestCurrenciesNumeric", fmt, &USD_2, 1, "$2.00");
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestFieldPosition() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
Measure measure(43.5, MeasureUnit::createFoot(status), status);
|
||||
if (!assertSuccess("Error creating measure object 1", status)) {
|
||||
return;
|
||||
}
|
||||
UnicodeString prefix("123456: ");
|
||||
verifyFieldPosition(
|
||||
"",
|
||||
fmt,
|
||||
prefix,
|
||||
&measure,
|
||||
1,
|
||||
NumberFormat::kDecimalSeparatorField,
|
||||
10,
|
||||
11);
|
||||
measure = Measure(43, MeasureUnit::createFoot(status), status);
|
||||
if (!assertSuccess("Error creating measure object 2", status)) {
|
||||
return;
|
||||
}
|
||||
verifyFieldPosition(
|
||||
"",
|
||||
fmt,
|
||||
prefix,
|
||||
&measure,
|
||||
1,
|
||||
NumberFormat::kDecimalSeparatorField,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestFieldPositionMultiple() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
Measure first[] = {
|
||||
Measure(354, MeasureUnit::createMeter(status), status),
|
||||
Measure(23, MeasureUnit::createCentimeter(status), status)};
|
||||
Measure second[] = {
|
||||
Measure(354, MeasureUnit::createMeter(status), status),
|
||||
Measure(23, MeasureUnit::createCentimeter(status), status),
|
||||
Measure(5.4, MeasureUnit::createMillimeter(status), status)};
|
||||
Measure third[] = {
|
||||
Measure(3, MeasureUnit::createMeter(status), status),
|
||||
Measure(23, MeasureUnit::createCentimeter(status), status),
|
||||
Measure(5, MeasureUnit::createMillimeter(status), status)};
|
||||
if (!assertSuccess("Error creating measure objects", status)) {
|
||||
return;
|
||||
}
|
||||
UnicodeString prefix("123456: ");
|
||||
verifyFieldPosition(
|
||||
"Integer",
|
||||
fmt,
|
||||
prefix,
|
||||
first,
|
||||
LENGTHOF(first),
|
||||
NumberFormat::kIntegerField,
|
||||
8,
|
||||
11);
|
||||
verifyFieldPosition(
|
||||
"Decimal separator",
|
||||
fmt,
|
||||
prefix,
|
||||
second,
|
||||
LENGTHOF(second),
|
||||
NumberFormat::kDecimalSeparatorField,
|
||||
23,
|
||||
24);
|
||||
verifyFieldPosition(
|
||||
"no decimal separator",
|
||||
fmt,
|
||||
prefix,
|
||||
third,
|
||||
LENGTHOF(third),
|
||||
NumberFormat::kDecimalSeparatorField,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestBadArg() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
|
||||
if (!assertSuccess("Error creating format object", status)) {
|
||||
return;
|
||||
}
|
||||
FieldPosition pos(0);
|
||||
UnicodeString buffer;
|
||||
fmt.format(
|
||||
9.3,
|
||||
buffer,
|
||||
pos,
|
||||
status);
|
||||
if (status != U_ILLEGAL_ARGUMENT_ERROR) {
|
||||
errln("Expected ILLEGAL_ARGUMENT_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureFormatTest::TestEquality() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
NumberFormat* nfeq = NumberFormat::createInstance("en", status);
|
||||
NumberFormat* nfne = NumberFormat::createInstance("fr", status);
|
||||
MeasureFormat fmt("en", UMEASFMT_WIDTH_SHORT, status);
|
||||
MeasureFormat fmtEq(fmt);
|
||||
MeasureFormat fmtEq2("en", UMEASFMT_WIDTH_SHORT, nfeq, status);
|
||||
MeasureFormat fmtne1("en", UMEASFMT_WIDTH_WIDE, status);
|
||||
MeasureFormat fmtne2("fr", UMEASFMT_WIDTH_SHORT, status);
|
||||
MeasureFormat fmtne3("en", UMEASFMT_WIDTH_SHORT, nfne, status);
|
||||
assertSuccess("Error creating MeasureFormats", status);
|
||||
assertTrue("Equal", fmt == fmtEq);
|
||||
assertTrue("Equal2", fmt == fmtEq2);
|
||||
assertFalse("Equal Neg", fmt != fmtEq);
|
||||
assertTrue("Not Equal 1", fmt != fmtne1);
|
||||
assertFalse("Not Equal Neg 1", fmt == fmtne1);
|
||||
assertTrue("Not Equal 2", fmt != fmtne2);
|
||||
assertTrue("Not Equal 3", fmt != fmtne3);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::verifyFieldPosition(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const UnicodeString &prefix,
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
NumberFormat::EAlignmentFields field,
|
||||
int32_t start,
|
||||
int32_t end) {
|
||||
// 8 char lead
|
||||
UnicodeString result(prefix);
|
||||
FieldPosition pos(field);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
CharString ch;
|
||||
const char *descPrefix = ch.append(description, status)
|
||||
.append(": ", status).data();
|
||||
CharString beginIndex;
|
||||
beginIndex.append(descPrefix, status).append("beginIndex", status);
|
||||
CharString endIndex;
|
||||
endIndex.append(descPrefix, status).append("endIndex", status);
|
||||
fmt.formatMeasures(measures, measureCount, result, pos, status);
|
||||
if (!assertSuccess("Error formatting", status)) {
|
||||
return;
|
||||
}
|
||||
assertEquals(beginIndex.data(), start, pos.getBeginIndex());
|
||||
assertEquals(endIndex.data(), end, pos.getEndIndex());
|
||||
}
|
||||
|
||||
void MeasureFormatTest::verifyFormat(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
const char *expected) {
|
||||
verifyFormatWithPrefix(
|
||||
description,
|
||||
fmt,
|
||||
"",
|
||||
measures,
|
||||
measureCount,
|
||||
expected);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::verifyFormatWithPrefix(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const UnicodeString &prefix,
|
||||
const Measure *measures,
|
||||
int32_t measureCount,
|
||||
const char *expected) {
|
||||
UnicodeString result(prefix);
|
||||
FieldPosition pos(0);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
fmt.formatMeasures(measures, measureCount, result, pos, status);
|
||||
if (!assertSuccess("Error formatting", status)) {
|
||||
return;
|
||||
}
|
||||
assertEquals(description, UnicodeString(expected).unescape(), result);
|
||||
}
|
||||
|
||||
void MeasureFormatTest::verifyFormat(
|
||||
const char *description,
|
||||
const MeasureFormat &fmt,
|
||||
const ExpectedResult *expectedResults,
|
||||
int32_t count) {
|
||||
for (int32_t i = 0; i < count; ++i) {
|
||||
verifyFormat(description, fmt, expectedResults[i].measures, expectedResults[i].count, expectedResults[i].expected);
|
||||
}
|
||||
}
|
||||
|
||||
extern IntlTest *createMeasureFormatTest() {
|
||||
return new MeasureFormatTest();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1896,6 +1896,8 @@ void NumberFormatTest::TestCurrencyNames(void) {
|
||||
void NumberFormatTest::TestCurrencyUnit(void){
|
||||
UErrorCode ec = U_ZERO_ERROR;
|
||||
static const UChar USD[] = {85, 83, 68, 0}; /*USD*/
|
||||
static const UChar BAD[] = {63, 63, 63, 0}; /*???*/
|
||||
static const UChar BAD2[] = {63, 63, 65, 0}; /*???*/
|
||||
CurrencyUnit cu(USD, ec);
|
||||
assertSuccess("CurrencyUnit", ec);
|
||||
|
||||
@ -1911,6 +1913,23 @@ void NumberFormatTest::TestCurrencyUnit(void){
|
||||
if (!(*cu3 == cu)){
|
||||
errln("CurrencyUnit cloned object should be same");
|
||||
}
|
||||
CurrencyUnit bad(BAD, ec);
|
||||
assertSuccess("CurrencyUnit", ec);
|
||||
if (cu.getIndex() == bad.getIndex()) {
|
||||
errln("Indexes of different currencies should differ.");
|
||||
}
|
||||
CurrencyUnit bad2(BAD2, ec);
|
||||
assertSuccess("CurrencyUnit", ec);
|
||||
if (bad2.getIndex() != bad.getIndex()) {
|
||||
errln("Indexes of unrecognized currencies should be the same.");
|
||||
}
|
||||
if (bad == bad2) {
|
||||
errln("Different unrecognized currencies should not be equal.");
|
||||
}
|
||||
bad = bad2;
|
||||
if (bad != bad2) {
|
||||
errln("Currency unit assignment should be the same.");
|
||||
}
|
||||
delete cu3;
|
||||
}
|
||||
|
||||
|
@ -138,10 +138,37 @@ void TimeUnitTest::testAPI() {
|
||||
|
||||
TimeUnit::UTimeUnitFields field = tmunit_m->getTimeUnitField();
|
||||
assertTrue("field of month time unit is month", (field == TimeUnit::UTIMEUNIT_MONTH));
|
||||
|
||||
|
||||
//===== Interropability with MeasureUnit ======
|
||||
MeasureUnit **ptrs = new MeasureUnit *[TimeUnit::UTIMEUNIT_FIELD_COUNT];
|
||||
|
||||
ptrs[TimeUnit::UTIMEUNIT_YEAR] = MeasureUnit::createYear(status);
|
||||
ptrs[TimeUnit::UTIMEUNIT_MONTH] = MeasureUnit::createMonth(status);
|
||||
ptrs[TimeUnit::UTIMEUNIT_DAY] = MeasureUnit::createDay(status);
|
||||
ptrs[TimeUnit::UTIMEUNIT_WEEK] = MeasureUnit::createWeek(status);
|
||||
ptrs[TimeUnit::UTIMEUNIT_HOUR] = MeasureUnit::createHour(status);
|
||||
ptrs[TimeUnit::UTIMEUNIT_MINUTE] = MeasureUnit::createMinute(status);
|
||||
ptrs[TimeUnit::UTIMEUNIT_SECOND] = MeasureUnit::createSecond(status);
|
||||
if (!assertSuccess("TimeUnit::createInstance", status)) return;
|
||||
|
||||
for (TimeUnit::UTimeUnitFields j = TimeUnit::UTIMEUNIT_YEAR;
|
||||
j < TimeUnit::UTIMEUNIT_FIELD_COUNT;
|
||||
j = (TimeUnit::UTimeUnitFields)(j+1)) {
|
||||
MeasureUnit *ptr = TimeUnit::createInstance(j, status);
|
||||
if (!assertSuccess("TimeUnit::createInstance", status)) return;
|
||||
assertTrue(
|
||||
"Time unit should be equal to corresponding MeasureUnit",
|
||||
*ptr == *ptrs[j]);
|
||||
delete ptr;
|
||||
}
|
||||
delete tmunit;
|
||||
delete another;
|
||||
delete tmunit_m;
|
||||
for (int i = 0; i < TimeUnit::UTIMEUNIT_FIELD_COUNT; ++i) {
|
||||
delete ptrs[i];
|
||||
}
|
||||
delete [] ptrs;
|
||||
|
||||
//
|
||||
//================= TimeUnitAmount =================
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user