mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-7892 add missing implementation for unum_parseDecimal() and unum_formatDecimal().
X-SVN-Rev: 28789
This commit is contained in:
parent
a788c4e44c
commit
801abaa192
2 changed files with 180 additions and 3 deletions
|
@ -26,6 +26,7 @@
|
|||
#include "unicode/curramt.h"
|
||||
#include "uassert.h"
|
||||
#include "cpputils.h"
|
||||
#include "cstring.h"
|
||||
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
@ -261,6 +262,51 @@ unum_formatDouble( const UNumberFormat* fmt,
|
|||
return res.extract(result, resultLength, *status);
|
||||
}
|
||||
|
||||
|
||||
U_DRAFT int32_t U_EXPORT2
|
||||
unum_formatDecimal(const UNumberFormat* fmt,
|
||||
const char * number,
|
||||
int32_t length,
|
||||
UChar* result,
|
||||
int32_t resultLength,
|
||||
UFieldPosition *pos, /* 0 if ignore */
|
||||
UErrorCode* status) {
|
||||
|
||||
if(U_FAILURE(*status)) {
|
||||
return -1;
|
||||
}
|
||||
if ((result == NULL && resultLength != 0) || resultLength < 0) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FieldPosition fp;
|
||||
if(pos != 0) {
|
||||
fp.setField(pos->field);
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
length = uprv_strlen(number);
|
||||
}
|
||||
StringPiece numSP(number, length);
|
||||
Formattable numFmtbl(numSP, *status);
|
||||
|
||||
UnicodeString resultStr;
|
||||
if (resultLength > 0) {
|
||||
// Alias the destination buffer.
|
||||
resultStr.setTo(result, 0, resultLength);
|
||||
}
|
||||
((const NumberFormat*)fmt)->format(numFmtbl, resultStr, fp, *status);
|
||||
if(pos != 0) {
|
||||
pos->beginIndex = fp.getBeginIndex();
|
||||
pos->endIndex = fp.getEndIndex();
|
||||
}
|
||||
return resultStr.extract(result, resultLength, *status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
unum_formatDoubleCurrency(const UNumberFormat* fmt,
|
||||
double number,
|
||||
|
@ -370,6 +416,38 @@ unum_parseDouble( const UNumberFormat* fmt,
|
|||
return res.getDouble(*status);
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
unum_parseDecimal(const UNumberFormat* fmt,
|
||||
const UChar* text,
|
||||
int32_t textLength,
|
||||
int32_t *parsePos /* 0 = start */,
|
||||
char *outBuf,
|
||||
int32_t outBufLength,
|
||||
UErrorCode *status)
|
||||
{
|
||||
if (U_FAILURE(*status)) {
|
||||
return -1;
|
||||
}
|
||||
if ((outBuf == NULL && outBufLength != 0) || outBufLength < 0) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return -1;
|
||||
}
|
||||
Formattable res;
|
||||
parseRes(res, fmt, text, textLength, parsePos, FALSE, status);
|
||||
StringPiece sp = res.getDecimalNumber(*status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return -1;
|
||||
} else if (sp.size() > outBufLength) {
|
||||
*status = U_BUFFER_OVERFLOW_ERROR;
|
||||
} else if (sp.size() == outBufLength) {
|
||||
uprv_strncpy(outBuf, sp.data(), sp.size());
|
||||
*status = U_STRING_NOT_TERMINATED_WARNING;
|
||||
} else {
|
||||
uprv_strcpy(outBuf, sp.data());
|
||||
}
|
||||
return sp.size();
|
||||
}
|
||||
|
||||
U_CAPI double U_EXPORT2
|
||||
unum_parseDoubleCurrency(const UNumberFormat* fmt,
|
||||
const UChar* text,
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/uloc.h"
|
||||
#include "unicode/umisc.h"
|
||||
#include "unicode/unum.h"
|
||||
#include "unicode/ustring.h"
|
||||
|
||||
#include "cintltst.h"
|
||||
#include "cnumtst.h"
|
||||
#include "cmemory.h"
|
||||
|
@ -98,9 +100,8 @@ static void TestInt64Parse()
|
|||
UErrorCode st = U_ZERO_ERROR;
|
||||
UErrorCode* status = &st;
|
||||
|
||||
char* st1 = "009223372036854775808";
|
||||
const char* st1 = "009223372036854775808";
|
||||
const int size = 21;
|
||||
/*const int textLength = size;*/
|
||||
UChar text[21];
|
||||
|
||||
|
||||
|
@ -407,7 +408,8 @@ free(result);
|
|||
}
|
||||
|
||||
/*
|
||||
* Note: "for strict standard conformance all operations and constants are now supposed to be evaluated in precision of long double". So, we assign a1 before comparing to a double. Bug #7932.
|
||||
* Note: "for strict standard conformance all operations and constants are now supposed to be
|
||||
evaluated in precision of long double". So, we assign a1 before comparing to a double. Bug #7932.
|
||||
*/
|
||||
a1 = 462.12345;
|
||||
|
||||
|
@ -823,6 +825,103 @@ free(result);
|
|||
}
|
||||
unum_close(dec_en);
|
||||
}
|
||||
|
||||
{ /* Test parse & format of big decimals. Use a number with too many digits to fit in a double,
|
||||
to verify that it is taking the pure decimal path. */
|
||||
UNumberFormat *fmt;
|
||||
const char *bdpattern = "#,##0.#########";
|
||||
const char *numInitial = "12345678900987654321.1234567896";
|
||||
const char *numFormatted = "12,345,678,900,987,654,321.12345679";
|
||||
const char *parseExpected = "12345678900987654321.12345679";
|
||||
int32_t resultSize = 0;
|
||||
int32_t parsePos = 0; /* Output parameter for Parse operations. */
|
||||
#define DESTCAPACITY 100
|
||||
UChar dest[DESTCAPACITY];
|
||||
char desta[DESTCAPACITY];
|
||||
UFieldPosition fieldPos = {0};
|
||||
|
||||
/* Format */
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
u_uastrcpy(dest, bdpattern);
|
||||
fmt = unum_open(UNUM_PATTERN_DECIMAL, dest, -1, "en", NULL /*parseError*/, &status);
|
||||
if (U_FAILURE(status)) log_err("File %s, Line %d, status = %s\n", __FILE__, __LINE__, u_errorName(status));
|
||||
|
||||
resultSize = unum_formatDecimal(fmt, numInitial, -1, dest, DESTCAPACITY, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("File %s, Line %d, status = %s\n", __FILE__, __LINE__, u_errorName(status));
|
||||
}
|
||||
u_austrncpy(desta, dest, DESTCAPACITY);
|
||||
if (strcmp(numFormatted, desta) != 0) {
|
||||
log_err("File %s, Line %d, (expected, acutal) = (\"%s\", \"%s\")\n",
|
||||
__FILE__, __LINE__, numFormatted, desta);
|
||||
}
|
||||
if (strlen(numFormatted) != resultSize) {
|
||||
log_err("File %s, Line %d, (expected, actual) = (%d, %d)\n",
|
||||
__FILE__, __LINE__, strlen(numFormatted), resultSize);
|
||||
}
|
||||
|
||||
/* Format with a FieldPosition parameter */
|
||||
|
||||
fieldPos.field = 2; /* Ticket 8034 - need enum constants for the field values. */
|
||||
/* 2 = kDecimalSeparatorField */
|
||||
resultSize = unum_formatDecimal(fmt, numInitial, -1, dest, DESTCAPACITY, &fieldPos, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("File %s, Line %d, status = %s\n", __FILE__, __LINE__, u_errorName(status));
|
||||
}
|
||||
u_austrncpy(desta, dest, DESTCAPACITY);
|
||||
if (strcmp(numFormatted, desta) != 0) {
|
||||
log_err("File %s, Line %d, (expected, acutal) = (\"%s\", \"%s\")\n",
|
||||
__FILE__, __LINE__, numFormatted, desta);
|
||||
}
|
||||
if (fieldPos.beginIndex != 26) { /* index of "." in formatted number */
|
||||
log_err("File %s, Line %d, (expected, acutal) = (%d, %d)\n",
|
||||
__FILE__, __LINE__, 0, fieldPos.beginIndex);
|
||||
}
|
||||
if (fieldPos.endIndex != 27) {
|
||||
log_err("File %s, Line %d, (expected, acutal) = (%d, %d)\n",
|
||||
__FILE__, __LINE__, 0, fieldPos.endIndex);
|
||||
}
|
||||
|
||||
/* Parse */
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
u_uastrcpy(dest, numFormatted); /* Parse the expected output of the formatting test */
|
||||
resultSize = unum_parseDecimal(fmt, dest, -1, NULL, desta, DESTCAPACITY, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("File %s, Line %d, status = %s\n", __FILE__, __LINE__, u_errorName(status));
|
||||
}
|
||||
if (strcmp(parseExpected, desta) != 0) {
|
||||
log_err("File %s, Line %d, (expected, actual) = (\"%s\", \"%s\")\n",
|
||||
__FILE__, __LINE__, parseExpected, desta);
|
||||
}
|
||||
if (strlen(parseExpected) != resultSize) {
|
||||
log_err("File %s, Line %d, (expected, actual) = (%d, %d)\n",
|
||||
__FILE__, __LINE__, strlen(parseExpected), resultSize);
|
||||
}
|
||||
|
||||
/* Parse with a parsePos parameter */
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
u_uastrcpy(dest, numFormatted); /* Parse the expected output of the formatting test */
|
||||
parsePos = 3; /* 12,345,678,900,987,654,321.12345679 */
|
||||
/* start parsing at the the third char */
|
||||
resultSize = unum_parseDecimal(fmt, dest, -1, &parsePos, desta, DESTCAPACITY, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("File %s, Line %d, status = %s\n", __FILE__, __LINE__, u_errorName(status));
|
||||
}
|
||||
if (strcmp(parseExpected+2, desta) != 0) { /* "345678900987654321.12345679" */
|
||||
log_err("File %s, Line %d, (expected, actual) = (\"%s\", \"%s\")\n",
|
||||
__FILE__, __LINE__, parseExpected+2, desta);
|
||||
}
|
||||
if (strlen(numFormatted) != parsePos) {
|
||||
log_err("File %s, Line %d, parsePos (expected, actual) = (\"%d\", \"%d\")\n",
|
||||
__FILE__, __LINE__, strlen(parseExpected), parsePos);
|
||||
}
|
||||
|
||||
unum_close(fmt);
|
||||
}
|
||||
|
||||
|
||||
/*closing the NumberFormat() using unum_close(UNumberFormat*)")*/
|
||||
unum_close(def);
|
||||
|
|
Loading…
Add table
Reference in a new issue