ICU-7912 add unum_parse and unum_format taking UFormattable (@internal, API proposal to follow)

X-SVN-Rev: 33862
This commit is contained in:
Steven R. Loomis 2013-06-27 19:49:55 +00:00
parent f4d12ea183
commit 2fa49ba635
4 changed files with 172 additions and 2 deletions

View File

@ -101,6 +101,7 @@ U_NAMESPACE_END
#endif
#ifndef U_HIDE_INTERNAL_API
/**
* Return the type of this object
* @param fmt the UFormattable object
@ -120,7 +121,7 @@ ufmt_getType(UFormattable* fmt, UErrorCode *status);
*/
U_INTERNAL UBool U_EXPORT2
ufmt_isNumeric(UFormattable* fmt);
#endif
/**
* Get the value as a date, converting if need be.

View File

@ -20,6 +20,8 @@
#include "unicode/uloc.h"
#include "unicode/umisc.h"
#include "unicode/parseerr.h"
#include "unicode/uformattable.h"
/**
* \file
* \brief C API: NumberFormat
@ -559,6 +561,20 @@ unum_formatDoubleCurrency(const UNumberFormat* fmt,
UFieldPosition* pos, /* ignored if 0 */
UErrorCode* status);
#ifndef U_HIDE_INTERNAL_API
/**
* Format a UFormattable into a string
* @internal
*/
U_INTERNAL int32_t U_EXPORT2
unum_formatUFormattable(const UNumberFormat* fmt,
UFormattable *number,
UChar *result,
int32_t resultLength,
UFieldPosition *pos, /* ignored if 0 */
UErrorCode *status);
#endif
/**
* Parse a string into an integer using a UNumberFormat.
* The string will be parsed according to the UNumberFormat's locale.
@ -693,6 +709,21 @@ unum_parseDoubleCurrency(const UNumberFormat* fmt,
UChar* currency,
UErrorCode* status);
#ifndef U_HIDE_INTERNAL_API
/**
* Parse into a UFormattable.
* @param result - result formattable. Will be allocated with ufmt_open() first if NULL is passed in.
* @internal
*/
U_INTERNAL UFormattable* U_EXPORT2
unum_parseToUFormattable(const UNumberFormat* fmt,
UFormattable *result,
const UChar* text,
int32_t textLength,
int32_t* parsePos, /* 0 = start */
UErrorCode* status);
#endif
/**
* Set the pattern used by a UNumberFormat. This can only be used
* on a DecimalFormat, other formats return U_UNSUPPORTED_ERROR

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2012, International Business Machines
* Copyright (C) 1996-2013, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* Modification History:
@ -783,4 +783,54 @@ unum_getLocaleByType(const UNumberFormat *fmt,
return ((const Format*)fmt)->getLocaleID(type, *status);
}
U_INTERNAL UFormattable * U_EXPORT2
unum_parseToUFormattable(const UNumberFormat* fmt,
UFormattable *result,
const UChar* text,
int32_t textLength,
int32_t* parsePos, /* 0 = start */
UErrorCode* status) {
if(result == NULL) { // allocate if not allocated.
result = ufmt_open(status); // does an error check
}
if(U_FAILURE(*status)) return result;
parseRes(*(Formattable::fromUFormattable(result)), fmt, text, textLength, parsePos, status);
return result;
}
U_INTERNAL int32_t U_EXPORT2
unum_formatUFormattable(const UNumberFormat* fmt,
UFormattable *number,
UChar *result,
int32_t resultLength,
UFieldPosition *pos, /* ignored if 0 */
UErrorCode *status) {
// cribbed from unum_formatInt64
if(U_FAILURE(*status))
return -1;
UnicodeString res;
if(!(result==NULL && resultLength==0)) {
// NULL destination for pure preflighting: empty dummy string
// otherwise, alias the destination buffer
res.setTo(result, 0, resultLength);
}
FieldPosition fp;
if(pos != 0)
fp.setField(pos->field);
((const NumberFormat*)fmt)->format(*(Formattable::fromUFormattable(number)), res, fp, *status);
if(pos != 0) {
pos->beginIndex = fp.getBeginIndex();
pos->endIndex = fp.getEndIndex();
}
return res.extract(result, resultLength, *status);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -51,6 +51,7 @@ static void TestInt64Parse(void);
static void TestParseCurrency(void);
static void TestMaxInt(void);
static void TestNoExponent(void);
static void TestUFormattable(void);
#define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x)
@ -73,6 +74,7 @@ void addNumForTest(TestNode** root)
TESTCASE(TestCloneWithRBNF);
TESTCASE(TestMaxInt);
TESTCASE(TestNoExponent);
TESTCASE(TestUFormattable);
}
/* test Parse int 64 */
@ -2173,4 +2175,90 @@ static void TestMaxInt(void) {
unum_close(fmt);
}
static void TestUFormattable(void) {
UChar buf2k[2048];
UChar out2k[2048];
// test with explicitly created ufmt_open
{
UErrorCode status = U_ZERO_ERROR;
UFormattable *f;
UNumberFormat *unum;
const char *pattern = "";
f = ufmt_open(&status);
unum = unum_open(UNUM_DEFAULT, NULL, -1, "en_US_POSIX", NULL, &status);
if(assertSuccess("calling ufmt_open()", &status)) {
pattern = "31337";
log_verbose("-- pattern: %s\n", pattern);
u_uastrcpy(buf2k, pattern);
unum_parseToUFormattable(unum, f, buf2k, -1, NULL, &status);
if(assertSuccess("unum_parseToUFormattable[31337]", &status)) {
assertTrue("ufmt_getLong()=31337", ufmt_getLong(f, &status) == 31337);
assertTrue("ufmt_getType()=UFMT_LONG", ufmt_getType(f, &status) == UFMT_LONG);
log_verbose("long = %d\n", ufmt_getLong(f, &status));
assertSuccess("ufmt_getLong()", &status);
}
unum_formatUFormattable(unum, f, out2k, 2048, NULL, &status);
if(assertSuccess("unum_formatUFormattable(31337)", &status)) {
assertEquals("unum_formatUFormattable r/t", austrdup(buf2k), austrdup(out2k));
}
pattern = "3.14159";
log_verbose("-- pattern: %s\n", pattern);
u_uastrcpy(buf2k, pattern);
unum_parseToUFormattable(unum, f, buf2k, -1, NULL, &status);
if(assertSuccess("unum_parseToUFormattable[3.14159]", &status)) {
assertTrue("ufmt_getDouble()=3.14159", ufmt_getDouble(f, &status) == 3.14159);
assertTrue("ufmt_getType()=UFMT_DOUBLE", ufmt_getType(f, &status) == UFMT_DOUBLE);
log_verbose("double = %g\n", ufmt_getDouble(f, &status));
assertSuccess("ufmt_getDouble()", &status);
}
unum_formatUFormattable(unum, f, out2k, 2048, NULL, &status);
if(assertSuccess("unum_formatUFormattable(3.14159)", &status)) {
assertEquals("unum_formatUFormattable r/t", austrdup(buf2k), austrdup(out2k));
}
}
ufmt_close(f);
unum_close(unum);
}
// test with auto-generated ufmt
{
UErrorCode status = U_ZERO_ERROR;
UFormattable *f = NULL;
UNumberFormat *unum;
const char *pattern = "73476730924573500000000"; // weight of the moon, kg
log_verbose("-- pattern: %s (testing auto-opened UFormattable)\n", pattern);
u_uastrcpy(buf2k, pattern);
unum = unum_open(UNUM_DEFAULT, NULL, -1, "en_US_POSIX", NULL, &status);
if(assertSuccess("calling ufmt_open()", &status)) {
f = unum_parseToUFormattable(unum, NULL, /* will be unum_open()'ed for us */
buf2k, -1, NULL, &status);
if(assertSuccess("unum_parseToUFormattable(weight of the moon", &status)) {
log_verbose("new formattable allocated at %p\n", (void*)f);
assertTrue("ufmt_isNumeric() TRUE", ufmt_isNumeric(f));
unum_formatUFormattable(unum, f, out2k, 2048, NULL, &status);
if(assertSuccess("unum_formatUFormattable(3.14159)", &status)) {
assertEquals("unum_formatUFormattable r/t", austrdup(buf2k), austrdup(out2k));
}
log_verbose("double: %g\n", ufmt_getDouble(f, &status));
assertSuccess("ufmt_getDouble()", &status);
log_verbose("long: %ld\n", ufmt_getLong(f, &status));
assertTrue("failure on ufmt_getLong() for huge number:", U_FAILURE(status));
// status is now a failure due to ufmt_getLong() above.
// the intltest does extensive r/t testing of Formattable vs. UFormattable.
}
}
unum_close(unum);
ufmt_close(f); // was implicitly opened for us by the first unum_parseToUFormattable()
}
}
#endif /* #if !UCONFIG_NO_FORMATTING */