X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/51004dcb01e06fef634b61be77ed73dd61cb6db9..a01113dcd0f39d5da295ef82785beff9ed86fe38:/icuSources/i18n/unum.cpp diff --git a/icuSources/i18n/unum.cpp b/icuSources/i18n/unum.cpp index 61d8e46c..c2bd5488 100644 --- a/icuSources/i18n/unum.cpp +++ b/icuSources/i18n/unum.cpp @@ -1,6 +1,8 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /* ******************************************************************************* -* Copyright (C) 1996-2012, International Business Machines +* Copyright (C) 1996-2015, International Business Machines * Corporation and others. All Rights Reserved. ******************************************************************************* * Modification History: @@ -20,11 +22,13 @@ #include "unicode/numfmt.h" #include "unicode/decimfmt.h" #include "unicode/rbnf.h" +#include "unicode/compactdecimalformat.h" #include "unicode/ustring.h" #include "unicode/fmtable.h" #include "unicode/dcfmtsym.h" #include "unicode/curramt.h" #include "unicode/localpointer.h" +#include "unicode/udisplaycontext.h" #include "uassert.h" #include "cpputils.h" #include "cstring.h" @@ -51,6 +55,11 @@ unum_open( UNumberFormatStyle style, case UNUM_CURRENCY: case UNUM_PERCENT: case UNUM_SCIENTIFIC: + case UNUM_CURRENCY_ISO: + case UNUM_CURRENCY_PLURAL: + case UNUM_CURRENCY_ACCOUNTING: + case UNUM_CASH_CURRENCY: + case UNUM_CURRENCY_STANDARD: retVal = NumberFormat::createInstance(Locale(locale), style, *status); break; @@ -109,6 +118,14 @@ unum_open( UNumberFormatStyle style, break; #endif + case UNUM_DECIMAL_COMPACT_SHORT: + retVal = CompactDecimalFormat::createInstance(Locale(locale), UNUM_SHORT, *status); + break; + + case UNUM_DECIMAL_COMPACT_LONG: + retVal = CompactDecimalFormat::createInstance(Locale(locale), UNUM_LONG, *status); + break; + default: *status = U_UNSUPPORTED_ERROR; return NULL; @@ -187,7 +204,12 @@ unum_formatInt64(const UNumberFormat* fmt, if(pos != 0) fp.setField(pos->field); - ((const NumberFormat*)fmt)->format(number, res, fp, *status); + const CompactDecimalFormat* cdf = dynamic_cast((const NumberFormat*)fmt); + if (cdf != NULL) { + cdf->format(number, res, fp); // CompactDecimalFormat does not override the version with UErrorCode& !! + } else { + ((const NumberFormat*)fmt)->format(number, res, fp, *status); + } if(pos != 0) { pos->beginIndex = fp.getBeginIndex(); @@ -220,7 +242,12 @@ unum_formatDouble( const UNumberFormat* fmt, if(pos != 0) fp.setField(pos->field); - ((const NumberFormat*)fmt)->format(number, res, fp, *status); + const CompactDecimalFormat* cdf = dynamic_cast((const NumberFormat*)fmt); + if (cdf != NULL) { + cdf->format(number, res, fp); // CompactDecimalFormat does not override the version with UErrorCode& !! + } else { + ((const NumberFormat*)fmt)->format(number, res, fp, *status); + } if(pos != 0) { pos->beginIndex = fp.getBeginIndex(); @@ -230,6 +257,33 @@ unum_formatDouble( const UNumberFormat* fmt, return res.extract(result, resultLength, *status); } +U_CAPI int32_t U_EXPORT2 +unum_formatDoubleForFields(const UNumberFormat* format, + double number, + UChar* result, + int32_t resultLength, + UFieldPositionIterator* fpositer, + UErrorCode* status) +{ + if (U_FAILURE(*status)) + return -1; + + if (result == NULL ? resultLength != 0 : resultLength < 0) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return -1; + } + + UnicodeString res; + if (result != NULL) { + // NULL destination for pure preflighting: empty dummy string + // otherwise, alias the destination buffer + res.setTo(result, 0, resultLength); + } + + ((const NumberFormat*)format)->format(number, res, (FieldPositionIterator*)fpositer, *status); + + return res.extract(result, resultLength, *status); +} U_CAPI int32_t U_EXPORT2 unum_formatDecimal(const UNumberFormat* fmt, @@ -254,7 +308,7 @@ unum_formatDecimal(const UNumberFormat* fmt, } if (length < 0) { - length = uprv_strlen(number); + length = static_cast(uprv_strlen(number)); } StringPiece numSP(number, length); Formattable numFmtbl(numSP, *status); @@ -463,20 +517,43 @@ U_CAPI int32_t U_EXPORT2 unum_getAttribute(const UNumberFormat* fmt, UNumberFormatAttribute attr) { - const NumberFormat* nf = reinterpret_cast(fmt); - if ( attr == UNUM_LENIENT_PARSE ) { - // Supported for all subclasses - return nf->isLenient(); - } + const NumberFormat* nf = reinterpret_cast(fmt); + if (attr == UNUM_LENIENT_PARSE) { + // Supported for all subclasses + return nf->isLenient(); + } + else if (attr == UNUM_MAX_INTEGER_DIGITS) { + return nf->getMaximumIntegerDigits(); + } + else if (attr == UNUM_MIN_INTEGER_DIGITS) { + return nf->getMinimumIntegerDigits(); + } + else if (attr == UNUM_INTEGER_DIGITS) { + // TODO: what should this return? + return nf->getMinimumIntegerDigits(); + } + else if (attr == UNUM_MAX_FRACTION_DIGITS) { + return nf->getMaximumFractionDigits(); + } + else if (attr == UNUM_MIN_FRACTION_DIGITS) { + return nf->getMinimumFractionDigits(); + } + else if (attr == UNUM_FRACTION_DIGITS) { + // TODO: what should this return? + return nf->getMinimumFractionDigits(); + } + else if (attr == UNUM_ROUNDING_MODE) { + return nf->getRoundingMode(); + } - // The remaining attributea are only supported for DecimalFormat - const DecimalFormat* df = dynamic_cast(nf); - if (df != NULL) { - UErrorCode ignoredStatus = U_ZERO_ERROR; - return df->getAttribute( attr, ignoredStatus ); - } + // The remaining attributes are only supported for DecimalFormat + const DecimalFormat* df = dynamic_cast(nf); + if (df != NULL) { + UErrorCode ignoredStatus = U_ZERO_ERROR; + return df->getAttribute(attr, ignoredStatus); + } - return -1; + return -1; } U_CAPI void U_EXPORT2 @@ -484,18 +561,42 @@ unum_setAttribute( UNumberFormat* fmt, UNumberFormatAttribute attr, int32_t newValue) { - NumberFormat* nf = reinterpret_cast(fmt); - if ( attr == UNUM_LENIENT_PARSE ) { - // Supported for all subclasses - // keep this here as the class may not be a DecimalFormat - return nf->setLenient(newValue != 0); - } - // The remaining attributea are only supported for DecimalFormat - DecimalFormat* df = dynamic_cast(nf); - if (df != NULL) { - UErrorCode ignoredStatus = U_ZERO_ERROR; - df->setAttribute(attr, newValue, ignoredStatus); - } + NumberFormat* nf = reinterpret_cast(fmt); + if (attr == UNUM_LENIENT_PARSE) { + // Supported for all subclasses + // keep this here as the class may not be a DecimalFormat + return nf->setLenient(newValue != 0); + } + else if (attr == UNUM_MAX_INTEGER_DIGITS) { + return nf->setMaximumIntegerDigits(newValue); + } + else if (attr == UNUM_MIN_INTEGER_DIGITS) { + return nf->setMinimumIntegerDigits(newValue); + } + else if (attr == UNUM_INTEGER_DIGITS) { + nf->setMinimumIntegerDigits(newValue); + return nf->setMaximumIntegerDigits(newValue); + } + else if (attr == UNUM_MAX_FRACTION_DIGITS) { + return nf->setMaximumFractionDigits(newValue); + } + else if (attr == UNUM_MIN_FRACTION_DIGITS) { + return nf->setMinimumFractionDigits(newValue); + } + else if (attr == UNUM_FRACTION_DIGITS) { + nf->setMinimumFractionDigits(newValue); + return nf->setMaximumFractionDigits(newValue); + } + else if (attr == UNUM_ROUNDING_MODE) { + return nf->setRoundingMode((NumberFormat::ERoundingMode)newValue); + } + + // The remaining attributes are only supported for DecimalFormat + DecimalFormat* df = dynamic_cast(nf); + if (df != NULL) { + UErrorCode ignoredStatus = U_ZERO_ERROR; + df->setAttribute(attr, newValue, ignoredStatus); + } } U_CAPI double U_EXPORT2 @@ -783,4 +884,79 @@ unum_getLocaleByType(const UNumberFormat *fmt, return ((const Format*)fmt)->getLocaleID(type, *status); } +U_CAPI void U_EXPORT2 +unum_setContext(UNumberFormat* fmt, UDisplayContext value, UErrorCode* status) +{ + if (U_FAILURE(*status)) { + return; + } + ((NumberFormat*)fmt)->setContext(value, *status); + return; +} + +U_CAPI UDisplayContext U_EXPORT2 +unum_getContext(const UNumberFormat *fmt, UDisplayContextType type, UErrorCode* status) +{ + if (U_FAILURE(*status)) { + return (UDisplayContext)0; + } + return ((const NumberFormat*)fmt)->getContext(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) { + UFormattable *newFormattable = NULL; + if (U_FAILURE(*status)) return result; + if (fmt == NULL || (text==NULL && textLength!=0)) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return result; + } + if (result == NULL) { // allocate if not allocated. + newFormattable = result = ufmt_open(status); + } + parseRes(*(Formattable::fromUFormattable(result)), fmt, text, textLength, parsePos, status); + if (U_FAILURE(*status) && newFormattable != NULL) { + ufmt_close(newFormattable); + result = NULL; // deallocate if there was a parse error + } + return result; +} + +U_INTERNAL int32_t U_EXPORT2 +unum_formatUFormattable(const UNumberFormat* fmt, + const UFormattable *number, + UChar *result, + int32_t resultLength, + UFieldPosition *pos, /* ignored if 0 */ + UErrorCode *status) { + if (U_FAILURE(*status)) { + return 0; + } + if (fmt == NULL || number==NULL || + (result==NULL ? resultLength!=0 : resultLength<0)) { + *status = U_ILLEGAL_ARGUMENT_ERROR; + return 0; + } + UnicodeString res(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 */