ICU-7912 C wrapper for Formattable - UFormattable
X-SVN-Rev: 33849
This commit is contained in:
parent
20016a58db
commit
ae061ff78f
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2012, International Business Machines Corporation and *
|
||||
* Copyright (C) 1997-2013, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*
|
||||
@ -22,6 +22,7 @@
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/measure.h"
|
||||
#include "unicode/curramt.h"
|
||||
#include "unicode/uformattable.h"
|
||||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
@ -695,46 +696,56 @@ StringPiece Formattable::getDecimalNumber(UErrorCode &status) {
|
||||
return "";
|
||||
}
|
||||
if (fDecimalStr != NULL) {
|
||||
return fDecimalStr->toStringPiece();
|
||||
return fDecimalStr->toStringPiece();
|
||||
}
|
||||
|
||||
if (fDecimalNum == NULL) {
|
||||
CharString *decimalStr = internalGetCharString(status);
|
||||
if(decimalStr == NULL) {
|
||||
return ""; // getDecimalNumber returns "" for error cases
|
||||
} else {
|
||||
return decimalStr->toStringPiece();
|
||||
}
|
||||
}
|
||||
|
||||
CharString *Formattable::internalGetCharString(UErrorCode &status) {
|
||||
if(fDecimalStr == NULL) {
|
||||
if (fDecimalNum == NULL) {
|
||||
// No decimal number for the formattable yet. Which means the value was
|
||||
// set directly by the user as an int, int64 or double. If the value came
|
||||
// from parsing, or from the user setting a decimal number, fDecimalNum
|
||||
// would already be set.
|
||||
//
|
||||
fDecimalNum = new DigitList; // TODO: use internal digit list
|
||||
fDecimalNum = new DigitList; // TODO: use internal digit list
|
||||
if (fDecimalNum == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return "";
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (fType) {
|
||||
case kDouble:
|
||||
fDecimalNum->set(this->getDouble());
|
||||
break;
|
||||
fDecimalNum->set(this->getDouble());
|
||||
break;
|
||||
case kLong:
|
||||
fDecimalNum->set(this->getLong());
|
||||
break;
|
||||
fDecimalNum->set(this->getLong());
|
||||
break;
|
||||
case kInt64:
|
||||
fDecimalNum->set(this->getInt64());
|
||||
break;
|
||||
fDecimalNum->set(this->getInt64());
|
||||
break;
|
||||
default:
|
||||
// The formattable's value is not a numeric type.
|
||||
status = U_INVALID_STATE_ERROR;
|
||||
return "";
|
||||
// The formattable's value is not a numeric type.
|
||||
status = U_INVALID_STATE_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fDecimalStr = new CharString;
|
||||
if (fDecimalStr == NULL) {
|
||||
fDecimalStr = new CharString;
|
||||
if (fDecimalStr == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return "";
|
||||
return NULL;
|
||||
}
|
||||
fDecimalNum->getDecimal(*fDecimalStr, status);
|
||||
}
|
||||
fDecimalNum->getDecimal(*fDecimalStr, status);
|
||||
|
||||
return fDecimalStr->toStringPiece();
|
||||
return fDecimalStr;
|
||||
}
|
||||
|
||||
|
||||
@ -882,6 +893,197 @@ FormattableStreamer::streamOut(ostream& stream, const Formattable& obj)
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- UFormattable stuff ---- */
|
||||
|
||||
|
||||
U_DRAFT UFormattable* U_EXPORT2
|
||||
ufmt_open(UErrorCode *status) {
|
||||
if( U_FAILURE(*status) ) {
|
||||
return NULL;
|
||||
}
|
||||
UFormattable *fmt = (new Formattable())->toUFormattable();
|
||||
|
||||
if( fmt == NULL ) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
U_DRAFT void U_EXPORT2
|
||||
ufmt_close(UFormattable *fmt) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
delete obj;
|
||||
}
|
||||
|
||||
U_INTERNAL UFormattableType U_EXPORT2
|
||||
ufmt_getType(UFormattable *fmt, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) {
|
||||
return (UFormattableType)-1;
|
||||
}
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
switch( obj->getType() ) {
|
||||
case Formattable::kDate:
|
||||
return UFMT_DATE;
|
||||
break;
|
||||
case Formattable::kDouble:
|
||||
return UFMT_DOUBLE;
|
||||
break;
|
||||
case Formattable::kLong:
|
||||
return UFMT_LONG;
|
||||
break;
|
||||
case Formattable::kString:
|
||||
return UFMT_STRING;
|
||||
break;
|
||||
case Formattable::kArray:
|
||||
return UFMT_ARRAY;
|
||||
break;
|
||||
case Formattable::kInt64:
|
||||
return UFMT_INT64;
|
||||
break;
|
||||
case Formattable::kObject:
|
||||
return UFMT_OBJECT;
|
||||
break;
|
||||
default:
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return (UFormattableType)-1; // invalid
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U_INTERNAL UBool U_EXPORT2
|
||||
ufmt_isNumeric(UFormattable *fmt) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
return obj->isNumeric();
|
||||
}
|
||||
|
||||
U_DRAFT UDate U_EXPORT2
|
||||
ufmt_getDate(UFormattable *fmt, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
return obj->getDate(*status);
|
||||
}
|
||||
|
||||
U_DRAFT double U_EXPORT2
|
||||
ufmt_getDouble(UFormattable *fmt, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
return obj->getDouble(*status);
|
||||
}
|
||||
|
||||
U_DRAFT int32_t U_EXPORT2
|
||||
ufmt_getLong(UFormattable *fmt, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
return obj->getLong(*status);
|
||||
}
|
||||
|
||||
|
||||
U_DRAFT const void *U_EXPORT2
|
||||
ufmt_getObject(UFormattable *fmt, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
const void *ret = obj->getObject();
|
||||
if( ret==NULL &&
|
||||
(obj->getType() != Formattable::kObject) &&
|
||||
U_SUCCESS( *status )) {
|
||||
*status = U_INVALID_FORMAT_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
U_DRAFT const UChar* U_EXPORT2
|
||||
ufmt_getUChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
// avoid bogosity by checking the type first.
|
||||
if( obj->getType() != Formattable::kString ) {
|
||||
if( U_SUCCESS(*status) ){
|
||||
*status = U_INVALID_FORMAT_ERROR;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// This should return a valid string
|
||||
UnicodeString &str = obj->getString(*status);
|
||||
if( U_SUCCESS(*status) && len != NULL ) {
|
||||
*len = str.length();
|
||||
}
|
||||
return str.getTerminatedBuffer();
|
||||
}
|
||||
|
||||
U_DRAFT int32_t U_EXPORT2
|
||||
ufmt_getArrayLength(UFormattable* fmt, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
|
||||
int32_t count;
|
||||
(void)obj->getArray(count, *status);
|
||||
return count;
|
||||
}
|
||||
|
||||
U_DRAFT UFormattable * U_EXPORT2
|
||||
ufmt_getArrayItemByIndex(UFormattable* fmt, int32_t n, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
int32_t count;
|
||||
(void)obj->getArray(count, *status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return NULL;
|
||||
} else if(n<0 || n>=count) {
|
||||
setError(*status, U_INDEX_OUTOFBOUNDS_ERROR);
|
||||
return NULL;
|
||||
} else {
|
||||
return (*obj)[n].toUFormattable(); // returns non-const Formattable
|
||||
}
|
||||
}
|
||||
|
||||
U_DRAFT const char * U_EXPORT2
|
||||
ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status) {
|
||||
if(U_FAILURE(*status)) {
|
||||
return "";
|
||||
}
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
CharString *charString = obj->internalGetCharString(*status);
|
||||
if(U_FAILURE(*status)) {
|
||||
return "";
|
||||
}
|
||||
if(charString == NULL) {
|
||||
*status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return "";
|
||||
} else {
|
||||
if(len!=NULL) {
|
||||
*len = charString->length();
|
||||
}
|
||||
return charString->data();
|
||||
}
|
||||
}
|
||||
|
||||
// make-a-copy version
|
||||
// U_DRAFT int32_t U_EXPORT2
|
||||
// ufmt_getDecNumChars(UFormattable *fmt, char *buf, int32_t len, UErrorCode *status) {
|
||||
// if(U_FAILURE(*status)) {
|
||||
// return 0;
|
||||
// }
|
||||
// Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
// CharString *charString = obj->internalGetCharString(*status);
|
||||
// if(U_FAILURE(*status)) {
|
||||
// return 0;
|
||||
// }
|
||||
// if(charString == NULL) {
|
||||
// *status = U_MEMORY_ALLOCATION_ERROR;
|
||||
// return 0;
|
||||
// } else {
|
||||
// return charString->extract(buf, len, *status);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
U_DRAFT int64_t U_EXPORT2
|
||||
ufmt_getInt64(UFormattable *fmt, UErrorCode *status) {
|
||||
Formattable *obj = Formattable::fromUFormattable(fmt);
|
||||
return obj->getInt64(*status);
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
@ -879,6 +879,20 @@
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="unicode\uformattable.h">
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">copy "%(FullPath)" ..\..\include\unicode
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy "%(FullPath)" ..\..\include\unicode
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">copy "%(FullPath)" ..\..\include\unicode
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
|
@ -16,16 +16,18 @@
|
||||
#define FMTABLE_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/stringpiece.h"
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C++ API: Formattable is a thin wrapper for primitive numeric types.
|
||||
* \file
|
||||
* \brief C++ API: Formattable is a thin wrapper for primitive types used for formatting and parsing
|
||||
*/
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/stringpiece.h"
|
||||
#include "unicode/uformattable.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
class CharString;
|
||||
@ -84,7 +86,7 @@ public:
|
||||
* Creates a Formattable object with a UDate instance.
|
||||
* @param d the UDate instance.
|
||||
* @param flag the flag to indicate this is a date. Always set it to kIsDate
|
||||
* @stable ICU 2.0
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
Formattable(UDate d, ISDATE flag);
|
||||
|
||||
@ -183,8 +185,8 @@ public:
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
UBool operator==(const Formattable &other) const;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Equality operator.
|
||||
* @param other the object to be compared with.
|
||||
* @return TRUE if other are unequal to this, FALSE otherwise.
|
||||
@ -193,7 +195,7 @@ public:
|
||||
UBool operator!=(const Formattable& other) const
|
||||
{ return !operator==(other); }
|
||||
|
||||
/**
|
||||
/**
|
||||
* Destructor.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
@ -212,7 +214,7 @@ public:
|
||||
*/
|
||||
Formattable *clone() const;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Selector for flavor of data type contained within a
|
||||
* Formattable object. Formattable is a union of several
|
||||
* different types, and at any time contains exactly one type.
|
||||
@ -275,7 +277,7 @@ public:
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
Type getType(void) const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns TRUE if the data type of this Formattable object
|
||||
* is kDouble, kLong, kInt64 or kDecimalNumber.
|
||||
@ -283,13 +285,13 @@ public:
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
UBool isNumeric() const;
|
||||
|
||||
|
||||
/**
|
||||
* Gets the double value of this object. If this object is not of type
|
||||
* kDouble then the result is undefined.
|
||||
* @return the double value of this object.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
double getDouble(void) const { return fValue.fDouble; }
|
||||
|
||||
/**
|
||||
@ -303,7 +305,7 @@ public:
|
||||
* @param status the error code
|
||||
* @return the double value of this object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
double getDouble(UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
@ -311,7 +313,7 @@ public:
|
||||
* kLong then the result is undefined.
|
||||
* @return the long value of this object.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
int32_t getLong(void) const { return (int32_t)fValue.fInt64; }
|
||||
|
||||
/**
|
||||
@ -329,7 +331,7 @@ public:
|
||||
* @param status the error code
|
||||
* @return the long value of this object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
int32_t getLong(UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
@ -337,7 +339,7 @@ public:
|
||||
* kInt64 then the result is undefined.
|
||||
* @return the int64 value of this object.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
*/
|
||||
int64_t getInt64(void) const { return fValue.fInt64; }
|
||||
|
||||
/**
|
||||
@ -354,7 +356,7 @@ public:
|
||||
* @param status the error code
|
||||
* @return the int64 value of this object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
int64_t getInt64(UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
@ -362,7 +364,7 @@ public:
|
||||
* kDate then the result is undefined.
|
||||
* @return the Date value of this object.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
UDate getDate() const { return fValue.fDate; }
|
||||
|
||||
/**
|
||||
@ -372,7 +374,7 @@ public:
|
||||
* @param status the error code.
|
||||
* @return the Date value of this object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
UDate getDate(UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
@ -381,7 +383,7 @@ public:
|
||||
* @param result Output param to receive the Date value of this object.
|
||||
* @return A reference to 'result'.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
UnicodeString& getString(UnicodeString& result) const
|
||||
{ result=*fValue.fString; return result; }
|
||||
|
||||
@ -390,10 +392,10 @@ public:
|
||||
* string, status is set to U_INVALID_FORMAT_ERROR and a bogus
|
||||
* string is returned.
|
||||
* @param result Output param to receive the Date value of this object.
|
||||
* @param status the error code.
|
||||
* @param status the error code.
|
||||
* @return A reference to 'result'.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
UnicodeString& getString(UnicodeString& result, UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
@ -427,7 +429,7 @@ public:
|
||||
* Gets a reference to the string value of this object. If the
|
||||
* type is not a string, status is set to U_INVALID_FORMAT_ERROR
|
||||
* and the result is a bogus string.
|
||||
* @param status the error code.
|
||||
* @param status the error code.
|
||||
* @return a reference to the string value of this object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
@ -439,7 +441,7 @@ public:
|
||||
* @param count fill-in with the count of this object.
|
||||
* @return the array value of this object.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
const Formattable* getArray(int32_t& count) const
|
||||
{ count=fValue.fArrayAndCount.fCount; return fValue.fArrayAndCount.fArray; }
|
||||
|
||||
@ -448,10 +450,10 @@ public:
|
||||
* not an array, status is set to U_INVALID_FORMAT_ERROR, count is
|
||||
* set to 0, and the result is NULL.
|
||||
* @param count fill-in with the count of this object.
|
||||
* @param status the error code.
|
||||
* @param status the error code.
|
||||
* @return the array value of this object.
|
||||
* @stable ICU 3.0
|
||||
*/
|
||||
*/
|
||||
const Formattable* getArray(int32_t& count, UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
@ -463,7 +465,7 @@ public:
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
Formattable& operator[](int32_t index) { return fValue.fArrayAndCount.fArray[index]; }
|
||||
|
||||
|
||||
/**
|
||||
* Returns a pointer to the UObject contained within this
|
||||
* formattable, or NULL if this object does not contain a UObject.
|
||||
@ -478,7 +480,7 @@ public:
|
||||
* For values obtained by parsing, the returned decimal number retains
|
||||
* the full precision and range of the original input, unconstrained by
|
||||
* the limits of a double floating point or a 64 bit int.
|
||||
*
|
||||
*
|
||||
* This function is not thread safe, and therfore is not declared const,
|
||||
* even though it is logically const.
|
||||
*
|
||||
@ -497,7 +499,7 @@ public:
|
||||
* kDouble.
|
||||
* @param d the new double value to be set.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void setDouble(double d);
|
||||
|
||||
/**
|
||||
@ -505,7 +507,7 @@ public:
|
||||
* kLong.
|
||||
* @param l the new long value to be set.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void setLong(int32_t l);
|
||||
|
||||
/**
|
||||
@ -513,7 +515,7 @@ public:
|
||||
* kInt64.
|
||||
* @param ll the new int64 value to be set.
|
||||
* @stable ICU 2.8
|
||||
*/
|
||||
*/
|
||||
void setInt64(int64_t ll);
|
||||
|
||||
/**
|
||||
@ -521,7 +523,7 @@ public:
|
||||
* kDate.
|
||||
* @param d the new Date value to be set.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void setDate(UDate d);
|
||||
|
||||
/**
|
||||
@ -529,7 +531,7 @@ public:
|
||||
* kString.
|
||||
* @param stringToCopy the new string value to be set.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void setString(const UnicodeString& stringToCopy);
|
||||
|
||||
/**
|
||||
@ -538,7 +540,7 @@ public:
|
||||
* @param array the array value.
|
||||
* @param count the number of array elements to be copied.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void setArray(const Formattable* array, int32_t count);
|
||||
|
||||
/**
|
||||
@ -546,16 +548,16 @@ public:
|
||||
* changes the type to kArray.
|
||||
* @param stringToAdopt the new string value to be adopted.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void adoptString(UnicodeString* stringToAdopt);
|
||||
|
||||
/**
|
||||
* Sets and adopts the array value and count of this object and
|
||||
* changes the type to kArray.
|
||||
* @stable ICU 2.0
|
||||
*/
|
||||
*/
|
||||
void adoptArray(Formattable* array, int32_t count);
|
||||
|
||||
|
||||
/**
|
||||
* Sets and adopts the UObject value of this object and changes
|
||||
* the type to kObject. After this call, the caller must not
|
||||
@ -567,7 +569,7 @@ public:
|
||||
|
||||
/**
|
||||
* Sets the the numeric value from a decimal number string, and changes
|
||||
* the type to to a numeric type appropriate for the number.
|
||||
* the type to to a numeric type appropriate for the number.
|
||||
* The syntax of the number is a "numeric string"
|
||||
* as defined in the Decimal Arithmetic Specification, available at
|
||||
* http://speleotrove.com/decimal
|
||||
@ -596,13 +598,29 @@ public:
|
||||
*/
|
||||
static UClassID U_EXPORT2 getStaticClassID();
|
||||
|
||||
/**
|
||||
* Convert the UFormattable to a Formattable. Internally, this is a reinterpret_cast.
|
||||
* @param fmt a valid UFormattable
|
||||
* @return the UFormattable as a Formattable object pointer. This is an alias to the original
|
||||
* UFormattable, and so is only valid while the original argument remains in scope.
|
||||
* @draft ICU 52
|
||||
*/
|
||||
static inline Formattable *fromUFormattable(UFormattable *fmt);
|
||||
|
||||
/**
|
||||
* Convert this object pointer to a UFormattable.
|
||||
* @return this object as a UFormattable pointer. This is an alias to the original UFormattable,
|
||||
* and so is only valid while the original argument remains in scope.
|
||||
*/
|
||||
inline UFormattable *toUFormattable();
|
||||
|
||||
#ifndef U_HIDE_DEPRECATED_API
|
||||
/**
|
||||
* Deprecated variant of getLong(UErrorCode&).
|
||||
* @param status the error code
|
||||
* @return the long value of this object.
|
||||
* @deprecated ICU 3.0 use getLong(UErrorCode&) instead
|
||||
*/
|
||||
*/
|
||||
inline int32_t getLong(UErrorCode* status) const;
|
||||
#endif /* U_HIDE_DEPRECATED_API */
|
||||
|
||||
@ -629,6 +647,14 @@ public:
|
||||
* @internal
|
||||
*/
|
||||
void adoptDigitList(DigitList *dl);
|
||||
|
||||
/**
|
||||
* Internal function to return the CharString pointer.
|
||||
* @param status error code
|
||||
* @return pointer to the CharString - may become invalid if the object is modified
|
||||
*/
|
||||
CharString *internalGetCharString(UErrorCode &status);
|
||||
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
private:
|
||||
@ -689,6 +715,14 @@ inline int32_t Formattable::getLong(UErrorCode* status) const {
|
||||
return getLong(*status);
|
||||
}
|
||||
|
||||
inline UFormattable* Formattable::toUFormattable() {
|
||||
return (UFormattable*)(this);
|
||||
}
|
||||
|
||||
inline Formattable* Formattable::fromUFormattable(UFormattable *fmt) {
|
||||
return reinterpret_cast<Formattable *>(fmt);
|
||||
}
|
||||
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
224
icu4c/source/i18n/unicode/uformattable.h
Normal file
224
icu4c/source/i18n/unicode/uformattable.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
TODO
|
||||
* copy C++ apidoc concerning error codes to appropriate wrapper functions
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
********************************************************************************
|
||||
* Copyright (C) 2013, International Business Machines Corporation and others.
|
||||
* All Rights Reserved.
|
||||
********************************************************************************
|
||||
*
|
||||
* File UFORMATTABLE.H
|
||||
*
|
||||
* Modification History:
|
||||
*
|
||||
* Date Name Description
|
||||
* 2013 Jul 7 srl New
|
||||
********************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief C API: UFormattable is a thin wrapper for primitive types used for formatting and parsing.
|
||||
*
|
||||
* This is a C interface to the icu::Formattable class. Static functions on this class convert
|
||||
* to and from this interface (via reinterpret_cast). Note that Formattables (and thus UFormattables)
|
||||
* are mutable, and many operations (even getters) may actually modify the internal state. For this
|
||||
* reason, UFormattables are not thread safe, and should not be shared between threads.
|
||||
*/
|
||||
|
||||
#ifndef FORMATTABLE_H
|
||||
#define FORMATTABLE_H
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/localpointer.h"
|
||||
|
||||
/**
|
||||
* Enum designating the type of a UFormattable instance.
|
||||
* Practically, this indicates which of the getters would return without conversion
|
||||
* or error.
|
||||
* @see icu::Formattable::Type
|
||||
* @draft ICU 52
|
||||
*/
|
||||
typedef enum UFormattableType {
|
||||
UFMT_DATE = 0, /**< ufmt_getDate() will return without conversion. */
|
||||
UFMT_DOUBLE, /**< ufmt_getDouble() will return without conversion. */
|
||||
UFMT_LONG, /**< ufmt_getLong() will return without conversion. */
|
||||
UFMT_INT64, /**< ufmt_getInt64() will return without conversion. */
|
||||
UFMT_OBJECT, /**< ufmt_getObject() will return without conversion. */
|
||||
UFMT_STRING, /**< ufmt_getUChars() will return without conversion. */
|
||||
UFMT_ARRAY, /**< ufmt_countArray() and ufmt_getArray() will return the value. */
|
||||
UFMT_COUNT /**< Count of defined UFormattableType values */
|
||||
} UFormattableType;
|
||||
|
||||
|
||||
/**
|
||||
* Opaque type representing various types of data which may be used for formatting
|
||||
* and parsing operations.
|
||||
* @see icu::Formattable
|
||||
* @draft ICU 52
|
||||
*/
|
||||
typedef void *UFormattable;
|
||||
|
||||
/**
|
||||
* Initialize a UFormattable, to type UNUM_LONG, value 0
|
||||
* may return error if memory allocation failed.
|
||||
* parameter status error code.
|
||||
* @draft ICU 52
|
||||
* @return the new UFormattable
|
||||
*/
|
||||
U_DRAFT UFormattable* U_EXPORT2
|
||||
ufmt_open(UErrorCode* status);
|
||||
|
||||
/**
|
||||
* Cleanup any additional memory allocated by this UFormattable.
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT void U_EXPORT2
|
||||
ufmt_close(UFormattable* fmt);
|
||||
|
||||
#if U_SHOW_CPLUSPLUS_API
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* \class LocalUFormattablePointer
|
||||
* "Smart pointer" class, closes a UFormattable via ufmt_close().
|
||||
* For most methods see the LocalPointerBase base class.
|
||||
*
|
||||
* @see LocalPointerBase
|
||||
* @see LocalPointer
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattablePointer, UFormattable, ufmt_close);
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return the type of this object
|
||||
* @param fmt the UFormattable object
|
||||
* @status status code - U_ILLEGAL_ARGUMENT_ERROR is returned if the UFormattable contains data not supported by
|
||||
* the API
|
||||
* @return the value as a UFormattableType
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UFormattableType U_EXPORT2
|
||||
ufmt_getType(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Return the type of this object
|
||||
* @param fmt the UFormattable object
|
||||
* @return true if the object is a double, long, or int64 value.
|
||||
* @internal
|
||||
*/
|
||||
U_INTERNAL UBool U_EXPORT2
|
||||
ufmt_isNumeric(UFormattable* fmt);
|
||||
|
||||
|
||||
/**
|
||||
* Get the value as a date, converting if need be.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors
|
||||
* @return the value
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT UDate U_EXPORT2
|
||||
ufmt_getDate(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the value as a double, converting if need be.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors
|
||||
* @return the value
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT double U_EXPORT2
|
||||
ufmt_getDouble(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the value as a int32_t, converting if need be.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors
|
||||
* @return the value
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT int32_t U_EXPORT2
|
||||
ufmt_getLong(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
|
||||
/**
|
||||
* Get the value as a int64_t, converting if need be.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors
|
||||
* @return the value
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT int64_t U_EXPORT2
|
||||
ufmt_getInt64(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the value as an object.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors
|
||||
* @return the value as a const void*. It is a polymorphic C++ object.
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT const void *U_EXPORT2
|
||||
ufmt_getObject(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the value as UChar string, converting if need be.
|
||||
* This function is not thread safe and may modify the UFormattable if need be to terminate the buffer.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors
|
||||
* @param len if non null, contains the string length on return
|
||||
* @return the null terminated string value - must not be referenced after any other functions are called on this UFormattable.
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT const UChar* U_EXPORT2
|
||||
ufmt_getUChars(UFormattable* fmt, int32_t *len, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the number of array objects contained. Invalid if the object is not an array type.
|
||||
* @param fmt the UFormattable object
|
||||
* @param status the error code - any conversion or format errors. U_ILLEGAL_ARGUMENT_ERROR if not an array type.
|
||||
* @return the number of array objects
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT int32_t U_EXPORT2
|
||||
ufmt_getArrayLength(UFormattable* fmt, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the specified value from the array of UFormattables. Invalid if the object is not an array type.
|
||||
* @param fmt the UFormattable object
|
||||
* #param n the number of the array to return (0 based).
|
||||
* @param status the error code - any conversion or format errors. Returns an error if n is out of bounds.
|
||||
* @return the nth array value, only valid while the containing UFormattable is valid
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT UFormattable * U_EXPORT2
|
||||
ufmt_getArrayItemByIndex(UFormattable* fmt, int32_t n, UErrorCode *status);
|
||||
|
||||
/**
|
||||
* Get the value as a C String, if it is a numeric type (isNumeric is true), or if is an Object
|
||||
* with a numeric value. The returned string is not valid if any other function calls are made on this
|
||||
* object, or if it is destroyed.
|
||||
* @param fmt the UFormattable object
|
||||
* @param len if non-null, on exit contains the string length (not including the terminating null)
|
||||
* @param status the error code
|
||||
* @return the character buffer, which is owned by the object and must not be accessed if any other functions are called on this object.
|
||||
* @draft ICU 52
|
||||
*/
|
||||
U_DRAFT const char * U_EXPORT2
|
||||
ufmt_getDecNumChars(UFormattable *fmt, int32_t *len, UErrorCode *status);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -120,6 +120,12 @@ operator+(const UnicodeString& left,
|
||||
return left + buffer;
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
operator+(const UnicodeString& left,
|
||||
int64_t num) {
|
||||
return left + Int64ToUnicodeString(num);
|
||||
}
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
/**
|
||||
@ -204,6 +210,12 @@ UnicodeString toString(int32_t n) {
|
||||
return UnicodeString() + (long)n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
UnicodeString toString(UBool b) {
|
||||
return b ? UnicodeString("TRUE"):UnicodeString("false");
|
||||
}
|
||||
|
||||
// stephen - cleaned up 05/05/99
|
||||
UnicodeString operator+(const UnicodeString& left, char num)
|
||||
{ return left + (long)num; }
|
||||
@ -1768,6 +1780,40 @@ UBool IntlTest::assertEquals(const char* message,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UBool IntlTest::assertEquals(const char* message,
|
||||
int64_t expected,
|
||||
int64_t actual) {
|
||||
if (expected != actual) {
|
||||
errln((UnicodeString)"FAIL: " + message + "; got " +
|
||||
actual +
|
||||
"; expected " + expected );
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef VERBOSE_ASSERTIONS
|
||||
else {
|
||||
logln((UnicodeString)"Ok: " + message + "; got " + actual);
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UBool IntlTest::assertEquals(const char* message,
|
||||
UBool expected,
|
||||
UBool actual) {
|
||||
if (expected != actual) {
|
||||
errln((UnicodeString)"FAIL: " + message + "; got " +
|
||||
toString(actual) +
|
||||
"; expected " + toString(expected));
|
||||
return FALSE;
|
||||
}
|
||||
#ifdef VERBOSE_ASSERTIONS
|
||||
else {
|
||||
logln((UnicodeString)"Ok: " + message + "; got " + toString(actual));
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
UBool IntlTest::assertEquals(const char* message,
|
||||
const Formattable& expected,
|
||||
@ -1820,6 +1866,21 @@ UBool IntlTest::assertEquals(const UnicodeString& message,
|
||||
const char* actual) {
|
||||
return assertEquals(extractToAssertBuf(message), expected, actual);
|
||||
}
|
||||
UBool IntlTest::assertEquals(const UnicodeString& message,
|
||||
UBool expected,
|
||||
UBool actual) {
|
||||
return assertEquals(extractToAssertBuf(message), expected, actual);
|
||||
}
|
||||
UBool IntlTest::assertEquals(const UnicodeString& message,
|
||||
int32_t expected,
|
||||
int32_t actual) {
|
||||
return assertEquals(extractToAssertBuf(message), expected, actual);
|
||||
}
|
||||
UBool IntlTest::assertEquals(const UnicodeString& message,
|
||||
int64_t expected,
|
||||
int64_t actual) {
|
||||
return assertEquals(extractToAssertBuf(message), expected, actual);
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
// Time bomb - allows temporary behavior that expires at a given
|
||||
// release
|
||||
|
@ -51,21 +51,23 @@ U_NAMESPACE_USE
|
||||
//string-concatenation operator (moved from findword test by rtg)
|
||||
UnicodeString UCharToUnicodeString(UChar c);
|
||||
UnicodeString Int64ToUnicodeString(int64_t num);
|
||||
//UnicodeString operator+(const UnicodeString& left, int64_t num); // Some compilers don't allow this because of the long type.
|
||||
UnicodeString operator+(const UnicodeString& left, int64_t num);
|
||||
UnicodeString operator+(const UnicodeString& left, long num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned long num);
|
||||
UnicodeString operator+(const UnicodeString& left, double num);
|
||||
UnicodeString operator+(const UnicodeString& left, char num);
|
||||
UnicodeString operator+(const UnicodeString& left, short num);
|
||||
UnicodeString operator+(const UnicodeString& left, int num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned char num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned short num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned int num);
|
||||
UnicodeString operator+(const UnicodeString& left, char num);
|
||||
UnicodeString operator+(const UnicodeString& left, short num);
|
||||
UnicodeString operator+(const UnicodeString& left, int num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned char num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned short num);
|
||||
UnicodeString operator+(const UnicodeString& left, unsigned int num);
|
||||
UnicodeString operator+(const UnicodeString& left, float num);
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
UnicodeString toString(const Formattable& f); // liu
|
||||
UnicodeString toString(int32_t n);
|
||||
#endif
|
||||
UnicodeString toString(UBool b);
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Use the TESTCASE macro in subclasses of IntlTest. Define the
|
||||
@ -178,6 +180,13 @@ public:
|
||||
void errln(const char *fmt, ...);
|
||||
void dataerr(const char *fmt, ...);
|
||||
void dataerrln(const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* logs an error (even if status==U_ZERO_ERROR), but
|
||||
* calls dataerrln() or errln() depending on the type of error.
|
||||
* Does not report the status code.
|
||||
* @param status parameter for selecting whether errln or dataerrln is called.
|
||||
*/
|
||||
void errcheckln(UErrorCode status, const char *fmt, ...);
|
||||
|
||||
// Print ALL named errors encountered so far
|
||||
@ -236,12 +245,19 @@ protected:
|
||||
/* JUnit-like assertions. Each returns TRUE if it succeeds. */
|
||||
UBool assertTrue(const char* message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE, const char *file=NULL, int line=0);
|
||||
UBool assertFalse(const char* message, UBool condition, UBool quiet=FALSE);
|
||||
/**
|
||||
* @param possibleDataError - if TRUE, use dataerrln instead of errcheckln on failure
|
||||
* @return TRUE on success, FALSE on failure.
|
||||
*/
|
||||
UBool assertSuccess(const char* message, UErrorCode ec, UBool possibleDataError=FALSE);
|
||||
UBool assertEquals(const char* message, const UnicodeString& expected,
|
||||
const UnicodeString& actual, UBool possibleDataError=FALSE);
|
||||
UBool assertEquals(const char* message, const char* expected,
|
||||
const char* actual);
|
||||
UBool assertEquals(const char* message, UBool expected,
|
||||
UBool actual);
|
||||
UBool assertEquals(const char* message, int32_t expected, int32_t actual);
|
||||
UBool assertEquals(const char* message, int64_t expected, int64_t actual);
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
UBool assertEquals(const char* message, const Formattable& expected,
|
||||
const Formattable& actual);
|
||||
@ -255,6 +271,9 @@ protected:
|
||||
const UnicodeString& actual);
|
||||
UBool assertEquals(const UnicodeString& message, const char* expected,
|
||||
const char* actual);
|
||||
UBool assertEquals(const UnicodeString& message, UBool expected, UBool actual);
|
||||
UBool assertEquals(const UnicodeString& message, int32_t expected, int32_t actual);
|
||||
UBool assertEquals(const UnicodeString& message, int64_t expected, int64_t actual);
|
||||
|
||||
virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !
|
||||
|
||||
|
@ -121,6 +121,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
|
||||
TESTCASE_AUTO(Test9087);
|
||||
TESTCASE_AUTO(TestFormatFastpaths);
|
||||
TESTCASE_AUTO(TestFormattableSize);
|
||||
TESTCASE_AUTO(TestUFormattable);
|
||||
TESTCASE_AUTO(TestSignificantDigits);
|
||||
TESTCASE_AUTO(TestShowZero);
|
||||
TESTCASE_AUTO(TestCompatibleCurrencies);
|
||||
@ -6789,6 +6790,226 @@ void NumberFormatTest::TestFormattableSize(void) {
|
||||
}
|
||||
}
|
||||
|
||||
UBool NumberFormatTest::testFormattableAsUFormattable(const char *file, int line, Formattable &f) {
|
||||
UnicodeString fileLine = UnicodeString(file)+UnicodeString(":")+line+UnicodeString(": ");
|
||||
|
||||
UFormattable *u = f.toUFormattable();
|
||||
logln();
|
||||
if (u == NULL) {
|
||||
errln("%s:%d: Error: f.toUFormattable() retuned NULL.");
|
||||
return FALSE;
|
||||
}
|
||||
logln("%s:%d: comparing Formattable with UFormattable", file, line);
|
||||
logln(fileLine + toString(f));
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UErrorCode valueStatus = U_ZERO_ERROR;
|
||||
UFormattableType expectUType = UFMT_COUNT; // invalid
|
||||
|
||||
UBool triedExact = FALSE; // did we attempt an exact comparison?
|
||||
UBool exactMatch = FALSE; // was the exact comparison true?
|
||||
|
||||
switch( f.getType() ) {
|
||||
case Formattable::kDate:
|
||||
expectUType = UFMT_DATE;
|
||||
exactMatch = (f.getDate()==ufmt_getDate(u, &valueStatus));
|
||||
triedExact = TRUE;
|
||||
break;
|
||||
case Formattable::kDouble:
|
||||
expectUType = UFMT_DOUBLE;
|
||||
exactMatch = (f.getDouble()==ufmt_getDouble(u, &valueStatus));
|
||||
triedExact = TRUE;
|
||||
break;
|
||||
case Formattable::kLong:
|
||||
expectUType = UFMT_LONG;
|
||||
exactMatch = (f.getLong()==ufmt_getLong(u, &valueStatus));
|
||||
triedExact = TRUE;
|
||||
break;
|
||||
case Formattable::kString:
|
||||
expectUType = UFMT_STRING;
|
||||
{
|
||||
UnicodeString str;
|
||||
f.getString(str);
|
||||
int32_t len;
|
||||
const UChar* uch = ufmt_getUChars(u, &len, &valueStatus);
|
||||
if(U_SUCCESS(valueStatus)) {
|
||||
UnicodeString str2(uch, len);
|
||||
exactMatch = (str == str2);
|
||||
}
|
||||
triedExact = TRUE;
|
||||
}
|
||||
break;
|
||||
case Formattable::kArray:
|
||||
expectUType = UFMT_ARRAY;
|
||||
triedExact = TRUE;
|
||||
{
|
||||
int32_t count = ufmt_getArrayLength(u, &valueStatus);
|
||||
int32_t count2;
|
||||
const Formattable *array2 = f.getArray(count2);
|
||||
exactMatch = assertEquals(fileLine + " array count", count, count2);
|
||||
|
||||
if(exactMatch) {
|
||||
for(int i=0;U_SUCCESS(valueStatus) && i<count;i++) {
|
||||
UFormattable *uu = ufmt_getArrayItemByIndex(u, i, &valueStatus);
|
||||
if(*Formattable::fromUFormattable(uu) != (array2[i])) {
|
||||
errln("%s:%d: operator== did not match at index[%d] - %p vs %p", file, line, i,
|
||||
(const void*)Formattable::fromUFormattable(uu), (const void*)&(array2[i]));
|
||||
exactMatch = FALSE;
|
||||
} else {
|
||||
if(!testFormattableAsUFormattable("(sub item)",i,*Formattable::fromUFormattable(uu))) {
|
||||
exactMatch = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Formattable::kInt64:
|
||||
expectUType = UFMT_INT64;
|
||||
exactMatch = (f.getInt64()==ufmt_getInt64(u, &valueStatus));
|
||||
triedExact = TRUE;
|
||||
break;
|
||||
case Formattable::kObject:
|
||||
expectUType = UFMT_OBJECT;
|
||||
exactMatch = (f.getObject()==ufmt_getObject(u, &valueStatus));
|
||||
triedExact = TRUE;
|
||||
break;
|
||||
}
|
||||
UFormattableType uType = ufmt_getType(u, &status);
|
||||
|
||||
if(U_FAILURE(status)) {
|
||||
errln("%s:%d: Error calling ufmt_getType - %s", file, line, u_errorName(status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(uType != expectUType) {
|
||||
errln("%s:%d: got type (%d) expected (%d) from ufmt_getType", file, line, (int) uType, (int) expectUType);
|
||||
}
|
||||
|
||||
if(triedExact) {
|
||||
if(U_FAILURE(valueStatus)) {
|
||||
errln("%s:%d: got err %s trying to ufmt_get...() for exact match check", file, line, u_errorName(valueStatus));
|
||||
} else if(!exactMatch) {
|
||||
errln("%s:%d: failed exact match for the Formattable type", file, line);
|
||||
} else {
|
||||
logln("%s:%d: exact match OK", file, line);
|
||||
}
|
||||
} else {
|
||||
logln("%s:%d: note, did not attempt exact match for this formattable type", file, line);
|
||||
}
|
||||
|
||||
if( assertEquals(fileLine + " isNumeric()", f.isNumeric(), ufmt_isNumeric(u))
|
||||
&& f.isNumeric()) {
|
||||
UErrorCode convStatus = U_ZERO_ERROR;
|
||||
assertTrue(fileLine + " as doubles ==", f.getDouble(convStatus)==ufmt_getDouble(u, &convStatus));
|
||||
|
||||
if( assertSuccess(fileLine + " (numeric conversion status)", convStatus) ) {
|
||||
StringPiece fDecNum = f.getDecimalNumber(convStatus);
|
||||
#if 1
|
||||
int32_t len;
|
||||
const char *decNumChars = ufmt_getDecNumChars(u, &len, &convStatus);
|
||||
#else
|
||||
// copy version
|
||||
char decNumChars[200];
|
||||
int32_t len = ufmt_getDecNumChars(u, decNumChars, 200, &convStatus);
|
||||
#endif
|
||||
|
||||
if( assertSuccess(fileLine + " (decNumbers conversion)", convStatus) ) {
|
||||
logln(fileLine + decNumChars);
|
||||
assertEquals(fileLine + " decNumChars length==", len, fDecNum.length());
|
||||
assertEquals(fileLine + " decNumChars digits", decNumChars, fDecNum.data());
|
||||
}
|
||||
|
||||
UErrorCode int64ConversionF = U_ZERO_ERROR;
|
||||
int64_t l = f.getInt64(int64ConversionF);
|
||||
UErrorCode int64ConversionU = U_ZERO_ERROR;
|
||||
int64_t r = ufmt_getInt64(u, &int64ConversionU);
|
||||
|
||||
if( (l==r)
|
||||
&& ( uType != UFMT_INT64 ) // int64 better not overflow
|
||||
&& (U_INVALID_FORMAT_ERROR==int64ConversionU)
|
||||
&& (U_INVALID_FORMAT_ERROR==int64ConversionF) ) {
|
||||
logln("%s:%d: OK: 64 bit overflow", file, line);
|
||||
} else {
|
||||
assertEquals(fileLine + " as int64 ==", l, r);
|
||||
assertSuccess(fileLine + " Formattable.getnt64()", int64ConversionF);
|
||||
assertSuccess(fileLine + " ufmt_getInt64()", int64ConversionU);
|
||||
}
|
||||
}
|
||||
}
|
||||
return exactMatch || !triedExact;
|
||||
}
|
||||
|
||||
void NumberFormatTest::TestUFormattable(void) {
|
||||
{
|
||||
// test that a default formattable is equal to Formattable()
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
LocalUFormattablePointer defaultUFormattable(ufmt_open(&status));
|
||||
assertSuccess("calling umt_open", status);
|
||||
Formattable defaultFormattable;
|
||||
assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
|
||||
(defaultFormattable
|
||||
== *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
|
||||
assertTrue((UnicodeString)"comparing ufmt_open() with Formattable()",
|
||||
(defaultFormattable
|
||||
== *(Formattable::fromUFormattable(defaultUFormattable.getAlias()))));
|
||||
assertTrue((UnicodeString)"comparing Formattable() round tripped through UFormattable",
|
||||
(defaultFormattable
|
||||
== *(Formattable::fromUFormattable(defaultFormattable.toUFormattable()))));
|
||||
assertTrue((UnicodeString)"comparing &Formattable() round tripped through UFormattable",
|
||||
((&defaultFormattable)
|
||||
== Formattable::fromUFormattable(defaultFormattable.toUFormattable())));
|
||||
assertFalse((UnicodeString)"comparing &Formattable() with ufmt_open()",
|
||||
((&defaultFormattable)
|
||||
== Formattable::fromUFormattable(defaultUFormattable.getAlias())));
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, defaultFormattable);
|
||||
}
|
||||
// test some random Formattables
|
||||
{
|
||||
Formattable f(ucal_getNow(), Formattable::kIsDate);
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
Formattable f((double)1.61803398874989484820); // golden ratio
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
Formattable f((int64_t)80994231587905127LL); // weight of the moon, in kilotons http://solarsystem.nasa.gov/planets/profile.cfm?Display=Facts&Object=Moon
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
Formattable f((int32_t)4); // random number, source: http://www.xkcd.com/221/
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
Formattable f("Hello world."); // should be invariant?
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
UErrorCode status2 = U_ZERO_ERROR;
|
||||
Formattable f(StringPiece("73476730924573500000000.0"), status2); // weight of the moon, kg
|
||||
assertSuccess("Constructing a StringPiece", status2);
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
UErrorCode status2 = U_ZERO_ERROR;
|
||||
UObject *obj = new Locale();
|
||||
Formattable f(obj);
|
||||
assertSuccess("Constructing a Formattable from a default constructed Locale()", status2);
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, f);
|
||||
}
|
||||
{
|
||||
const Formattable array[] = {
|
||||
Formattable(ucal_getNow(), Formattable::kIsDate),
|
||||
Formattable((int32_t)4),
|
||||
Formattable((double)1.234),
|
||||
};
|
||||
|
||||
Formattable fa(array, 3);
|
||||
testFormattableAsUFormattable(__FILE__, __LINE__, fa);
|
||||
}
|
||||
}
|
||||
|
||||
void NumberFormatTest::TestSignificantDigits(void) {
|
||||
double input[] = {
|
||||
0, 0,
|
||||
|
@ -160,6 +160,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
||||
|
||||
void TestFormattableSize();
|
||||
|
||||
void TestUFormattable();
|
||||
|
||||
void TestEnumSet();
|
||||
|
||||
void TestSignificantDigits();
|
||||
@ -169,6 +171,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
||||
void TestBug9936();
|
||||
|
||||
private:
|
||||
UBool testFormattableAsUFormattable(const char *file, int line, Formattable &f);
|
||||
|
||||
void expectParseCurrency(const NumberFormat &fmt, const UChar* currency, double amount, const char *text);
|
||||
|
||||
static UBool equalValue(const Formattable& a, const Formattable& b);
|
||||
|
Loading…
Reference in New Issue
Block a user