LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - unum.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 406 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 32 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : *   Copyright (C) 1996-2015, International Business Machines
       6             : *   Corporation and others.  All Rights Reserved.
       7             : *******************************************************************************
       8             : * Modification History:
       9             : *
      10             : *   Date        Name        Description
      11             : *   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
      12             : *******************************************************************************
      13             : */
      14             : 
      15             : #include "unicode/utypes.h"
      16             : 
      17             : #if !UCONFIG_NO_FORMATTING
      18             : 
      19             : #include "unicode/unum.h"
      20             : 
      21             : #include "unicode/uloc.h"
      22             : #include "unicode/numfmt.h"
      23             : #include "unicode/decimfmt.h"
      24             : #include "unicode/rbnf.h"
      25             : #include "unicode/compactdecimalformat.h"
      26             : #include "unicode/ustring.h"
      27             : #include "unicode/fmtable.h"
      28             : #include "unicode/dcfmtsym.h"
      29             : #include "unicode/curramt.h"
      30             : #include "unicode/localpointer.h"
      31             : #include "unicode/udisplaycontext.h"
      32             : #include "uassert.h"
      33             : #include "cpputils.h"
      34             : #include "cstring.h"
      35             : 
      36             : 
      37             : U_NAMESPACE_USE
      38             : 
      39             : 
      40             : U_CAPI UNumberFormat* U_EXPORT2
      41           0 : unum_open(  UNumberFormatStyle    style,  
      42             :             const    UChar*    pattern,
      43             :             int32_t            patternLength,
      44             :             const    char*     locale,
      45             :             UParseError*       parseErr,
      46             :             UErrorCode*        status) {
      47           0 :     if(U_FAILURE(*status)) {
      48           0 :         return NULL;
      49             :     }
      50             : 
      51           0 :     NumberFormat *retVal = NULL;
      52             : 
      53           0 :     switch(style) {
      54             :     case UNUM_DECIMAL:
      55             :     case UNUM_CURRENCY:
      56             :     case UNUM_PERCENT:
      57             :     case UNUM_SCIENTIFIC:
      58             :     case UNUM_CURRENCY_ISO:
      59             :     case UNUM_CURRENCY_PLURAL:
      60             :     case UNUM_CURRENCY_ACCOUNTING:
      61             :     case UNUM_CASH_CURRENCY:
      62             :     case UNUM_CURRENCY_STANDARD:
      63           0 :         retVal = NumberFormat::createInstance(Locale(locale), style, *status);
      64           0 :         break;
      65             : 
      66             :     case UNUM_PATTERN_DECIMAL: {
      67             :         UParseError tErr;
      68             :         /* UnicodeString can handle the case when patternLength = -1. */
      69           0 :         const UnicodeString pat(pattern, patternLength);
      70             : 
      71           0 :         if(parseErr==NULL){
      72           0 :             parseErr = &tErr;
      73             :         }
      74             : 
      75           0 :         DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale(locale), *status);
      76           0 :         if(syms == NULL) {
      77           0 :             *status = U_MEMORY_ALLOCATION_ERROR;
      78           0 :             return NULL;
      79             :         }
      80           0 :         if (U_FAILURE(*status)) {
      81           0 :             delete syms;
      82           0 :             return NULL;
      83             :         }
      84             : 
      85           0 :         retVal = new DecimalFormat(pat, syms, *parseErr, *status);
      86           0 :         if(retVal == NULL) {
      87           0 :             delete syms;
      88             :         }
      89           0 :     } break;
      90             : 
      91             : #if U_HAVE_RBNF
      92             :     case UNUM_PATTERN_RULEBASED: {
      93             :         UParseError tErr;
      94             :         /* UnicodeString can handle the case when patternLength = -1. */
      95           0 :         const UnicodeString pat(pattern, patternLength);
      96             :         
      97           0 :         if(parseErr==NULL){
      98           0 :             parseErr = &tErr;
      99             :         }
     100             :         
     101           0 :         retVal = new RuleBasedNumberFormat(pat, Locale(locale), *parseErr, *status);
     102           0 :     } break;
     103             : 
     104             :     case UNUM_SPELLOUT:
     105           0 :         retVal = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale(locale), *status);
     106           0 :         break;
     107             : 
     108             :     case UNUM_ORDINAL:
     109           0 :         retVal = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale(locale), *status);
     110           0 :         break;
     111             : 
     112             :     case UNUM_DURATION:
     113           0 :         retVal = new RuleBasedNumberFormat(URBNF_DURATION, Locale(locale), *status);
     114           0 :         break;
     115             : 
     116             :     case UNUM_NUMBERING_SYSTEM:
     117           0 :         retVal = new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM, Locale(locale), *status);
     118           0 :         break;
     119             : #endif
     120             : 
     121             :     case UNUM_DECIMAL_COMPACT_SHORT:
     122           0 :         retVal = CompactDecimalFormat::createInstance(Locale(locale), UNUM_SHORT, *status);
     123           0 :         break;
     124             : 
     125             :     case UNUM_DECIMAL_COMPACT_LONG:
     126           0 :         retVal = CompactDecimalFormat::createInstance(Locale(locale), UNUM_LONG, *status);
     127           0 :         break;
     128             : 
     129             :     default:
     130           0 :         *status = U_UNSUPPORTED_ERROR;
     131           0 :         return NULL;
     132             :     }
     133             : 
     134           0 :     if(retVal == NULL && U_SUCCESS(*status)) {
     135           0 :         *status = U_MEMORY_ALLOCATION_ERROR;
     136             :     }
     137             : 
     138           0 :     return reinterpret_cast<UNumberFormat *>(retVal);
     139             : }
     140             : 
     141             : U_CAPI void U_EXPORT2
     142           0 : unum_close(UNumberFormat* fmt)
     143             : {
     144           0 :     delete (NumberFormat*) fmt;
     145           0 : }
     146             : 
     147             : U_CAPI UNumberFormat* U_EXPORT2
     148           0 : unum_clone(const UNumberFormat *fmt,
     149             :        UErrorCode *status)
     150             : {
     151           0 :     if(U_FAILURE(*status))
     152           0 :         return 0;
     153             :     
     154           0 :     Format *res = 0;
     155           0 :     const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
     156           0 :     const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
     157           0 :     if (df != NULL) {
     158           0 :         res = df->clone();
     159             :     } else {
     160           0 :         const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
     161           0 :         U_ASSERT(rbnf != NULL);
     162           0 :         res = rbnf->clone();
     163             :     }
     164             : 
     165           0 :     if(res == 0) {
     166           0 :         *status = U_MEMORY_ALLOCATION_ERROR;
     167           0 :         return 0;
     168             :     }
     169             :     
     170           0 :     return (UNumberFormat*) res;
     171             : }
     172             : 
     173             : U_CAPI int32_t U_EXPORT2
     174           0 : unum_format(    const    UNumberFormat*    fmt,
     175             :         int32_t           number,
     176             :         UChar*            result,
     177             :         int32_t           resultLength,
     178             :         UFieldPosition    *pos,
     179             :         UErrorCode*       status)
     180             : {
     181           0 :         return unum_formatInt64(fmt, number, result, resultLength, pos, status);
     182             : }
     183             : 
     184             : U_CAPI int32_t U_EXPORT2
     185           0 : unum_formatInt64(const UNumberFormat* fmt,
     186             :         int64_t         number,
     187             :         UChar*          result,
     188             :         int32_t         resultLength,
     189             :         UFieldPosition *pos,
     190             :         UErrorCode*     status)
     191             : {
     192           0 :     if(U_FAILURE(*status))
     193           0 :         return -1;
     194             :     
     195           0 :     UnicodeString res;
     196           0 :     if(!(result==NULL && resultLength==0)) {
     197             :         // NULL destination for pure preflighting: empty dummy string
     198             :         // otherwise, alias the destination buffer
     199           0 :         res.setTo(result, 0, resultLength);
     200             :     }
     201             :     
     202           0 :     FieldPosition fp;
     203             :     
     204           0 :     if(pos != 0)
     205           0 :         fp.setField(pos->field);
     206             :     
     207           0 :     ((const NumberFormat*)fmt)->format(number, res, fp, *status);
     208             : 
     209           0 :     if(pos != 0) {
     210           0 :         pos->beginIndex = fp.getBeginIndex();
     211           0 :         pos->endIndex = fp.getEndIndex();
     212             :     }
     213             :     
     214           0 :     return res.extract(result, resultLength, *status);
     215             : }
     216             : 
     217             : U_CAPI int32_t U_EXPORT2
     218           0 : unum_formatDouble(    const    UNumberFormat*  fmt,
     219             :             double          number,
     220             :             UChar*          result,
     221             :             int32_t         resultLength,
     222             :             UFieldPosition  *pos, /* 0 if ignore */
     223             :             UErrorCode*     status)
     224             : {
     225             :  
     226           0 :   if(U_FAILURE(*status)) return -1;
     227             : 
     228           0 :   UnicodeString res;
     229           0 :   if(!(result==NULL && resultLength==0)) {
     230             :     // NULL destination for pure preflighting: empty dummy string
     231             :     // otherwise, alias the destination buffer
     232           0 :     res.setTo(result, 0, resultLength);
     233             :   }
     234             : 
     235           0 :   FieldPosition fp;
     236             :   
     237           0 :   if(pos != 0)
     238           0 :     fp.setField(pos->field);
     239             :   
     240           0 :   ((const NumberFormat*)fmt)->format(number, res, fp, *status);
     241             :   
     242           0 :   if(pos != 0) {
     243           0 :     pos->beginIndex = fp.getBeginIndex();
     244           0 :     pos->endIndex = fp.getEndIndex();
     245             :   }
     246             :   
     247           0 :   return res.extract(result, resultLength, *status);
     248             : }
     249             : 
     250             : U_CAPI int32_t U_EXPORT2
     251           0 : unum_formatDoubleForFields(const UNumberFormat* format,
     252             :                            double number,
     253             :                            UChar* result,
     254             :                            int32_t resultLength,
     255             :                            UFieldPositionIterator* fpositer,
     256             :                            UErrorCode* status)
     257             : {
     258           0 :     if (U_FAILURE(*status))
     259           0 :         return -1;
     260             : 
     261           0 :     if (result == NULL ? resultLength != 0 : resultLength < 0) {
     262           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     263           0 :         return -1;
     264             :     }
     265             : 
     266           0 :     UnicodeString res;
     267           0 :     if (result != NULL) {
     268             :         // NULL destination for pure preflighting: empty dummy string
     269             :         // otherwise, alias the destination buffer
     270           0 :         res.setTo(result, 0, resultLength);
     271             :     }
     272             : 
     273           0 :     ((const NumberFormat*)format)->format(number, res, (FieldPositionIterator*)fpositer, *status);
     274             : 
     275           0 :     return res.extract(result, resultLength, *status);
     276             : }
     277             : 
     278             : U_CAPI int32_t U_EXPORT2 
     279           0 : unum_formatDecimal(const    UNumberFormat*  fmt,
     280             :             const char *    number,
     281             :             int32_t         length,
     282             :             UChar*          result,
     283             :             int32_t         resultLength,
     284             :             UFieldPosition  *pos, /* 0 if ignore */
     285             :             UErrorCode*     status) {
     286             : 
     287           0 :     if(U_FAILURE(*status)) {
     288           0 :         return -1;
     289             :     }
     290           0 :     if ((result == NULL && resultLength != 0) || resultLength < 0) {
     291           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     292           0 :         return -1;
     293             :     }
     294             : 
     295           0 :     FieldPosition fp;
     296           0 :     if(pos != 0) {
     297           0 :         fp.setField(pos->field);
     298             :     }
     299             : 
     300           0 :     if (length < 0) {
     301           0 :         length = uprv_strlen(number);
     302             :     }
     303           0 :     StringPiece numSP(number, length);
     304           0 :     Formattable numFmtbl(numSP, *status);
     305             : 
     306           0 :     UnicodeString resultStr;
     307           0 :     if (resultLength > 0) {
     308             :         // Alias the destination buffer.
     309           0 :         resultStr.setTo(result, 0, resultLength);
     310             :     }
     311           0 :     ((const NumberFormat*)fmt)->format(numFmtbl, resultStr, fp, *status);
     312           0 :     if(pos != 0) {
     313           0 :         pos->beginIndex = fp.getBeginIndex();
     314           0 :         pos->endIndex = fp.getEndIndex();
     315             :     }
     316           0 :     return resultStr.extract(result, resultLength, *status);
     317             : }
     318             : 
     319             : 
     320             : 
     321             : 
     322             : U_CAPI int32_t U_EXPORT2 
     323           0 : unum_formatDoubleCurrency(const UNumberFormat* fmt,
     324             :                           double number,
     325             :                           UChar* currency,
     326             :                           UChar* result,
     327             :                           int32_t resultLength,
     328             :                           UFieldPosition* pos, /* ignored if 0 */
     329             :                           UErrorCode* status) {
     330           0 :     if (U_FAILURE(*status)) return -1;
     331             : 
     332           0 :     UnicodeString res;
     333           0 :     if (!(result==NULL && resultLength==0)) {
     334             :         // NULL destination for pure preflighting: empty dummy string
     335             :         // otherwise, alias the destination buffer
     336           0 :         res.setTo(result, 0, resultLength);
     337             :     }
     338             :     
     339           0 :     FieldPosition fp;
     340           0 :     if (pos != 0) {
     341           0 :         fp.setField(pos->field);
     342             :     }
     343           0 :     CurrencyAmount *tempCurrAmnt = new CurrencyAmount(number, currency, *status);
     344             :     // Check for null pointer.
     345           0 :     if (tempCurrAmnt == NULL) {
     346           0 :         *status = U_MEMORY_ALLOCATION_ERROR;
     347           0 :         return -1;
     348             :     }
     349           0 :     Formattable n(tempCurrAmnt);
     350           0 :     ((const NumberFormat*)fmt)->format(n, res, fp, *status);
     351             :     
     352           0 :     if (pos != 0) {
     353           0 :         pos->beginIndex = fp.getBeginIndex();
     354           0 :         pos->endIndex = fp.getEndIndex();
     355             :     }
     356             :   
     357           0 :     return res.extract(result, resultLength, *status);
     358             : }
     359             : 
     360             : static void
     361           0 : parseRes(Formattable& res,
     362             :          const   UNumberFormat*  fmt,
     363             :          const   UChar*          text,
     364             :          int32_t         textLength,
     365             :          int32_t         *parsePos /* 0 = start */,
     366             :          UErrorCode      *status)
     367             : {
     368           0 :     if(U_FAILURE(*status))
     369           0 :         return;
     370             :     
     371           0 :     const UnicodeString src((UBool)(textLength == -1), text, textLength);
     372           0 :     ParsePosition pp;
     373             :     
     374           0 :     if(parsePos != 0)
     375           0 :         pp.setIndex(*parsePos);
     376             :     
     377           0 :     ((const NumberFormat*)fmt)->parse(src, res, pp);
     378             :     
     379           0 :     if(pp.getErrorIndex() != -1) {
     380           0 :         *status = U_PARSE_ERROR;
     381           0 :         if(parsePos != 0) {
     382           0 :             *parsePos = pp.getErrorIndex();
     383             :         }
     384           0 :     } else if(parsePos != 0) {
     385           0 :         *parsePos = pp.getIndex();
     386             :     }
     387             : }
     388             : 
     389             : U_CAPI int32_t U_EXPORT2
     390           0 : unum_parse(    const   UNumberFormat*  fmt,
     391             :         const   UChar*          text,
     392             :         int32_t         textLength,
     393             :         int32_t         *parsePos /* 0 = start */,
     394             :         UErrorCode      *status)
     395             : {
     396           0 :     Formattable res;
     397           0 :     parseRes(res, fmt, text, textLength, parsePos, status);
     398           0 :     return res.getLong(*status);
     399             : }
     400             : 
     401             : U_CAPI int64_t U_EXPORT2
     402           0 : unum_parseInt64(    const   UNumberFormat*  fmt,
     403             :         const   UChar*          text,
     404             :         int32_t         textLength,
     405             :         int32_t         *parsePos /* 0 = start */,
     406             :         UErrorCode      *status)
     407             : {
     408           0 :     Formattable res;
     409           0 :     parseRes(res, fmt, text, textLength, parsePos, status);
     410           0 :     return res.getInt64(*status);
     411             : }
     412             : 
     413             : U_CAPI double U_EXPORT2
     414           0 : unum_parseDouble(    const   UNumberFormat*  fmt,
     415             :             const   UChar*          text,
     416             :             int32_t         textLength,
     417             :             int32_t         *parsePos /* 0 = start */,
     418             :             UErrorCode      *status)
     419             : {
     420           0 :     Formattable res;
     421           0 :     parseRes(res, fmt, text, textLength, parsePos, status);
     422           0 :     return res.getDouble(*status);
     423             : }
     424             : 
     425             : U_CAPI int32_t U_EXPORT2
     426           0 : unum_parseDecimal(const UNumberFormat*  fmt,
     427             :             const UChar*    text,
     428             :             int32_t         textLength,
     429             :             int32_t         *parsePos /* 0 = start */,
     430             :             char            *outBuf,
     431             :             int32_t         outBufLength,
     432             :             UErrorCode      *status)
     433             : {
     434           0 :     if (U_FAILURE(*status)) {
     435           0 :         return -1;
     436             :     }
     437           0 :     if ((outBuf == NULL && outBufLength != 0) || outBufLength < 0) {
     438           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     439           0 :         return -1;
     440             :     }
     441           0 :     Formattable res;
     442           0 :     parseRes(res, fmt, text, textLength, parsePos, status);
     443           0 :     StringPiece sp = res.getDecimalNumber(*status);
     444           0 :     if (U_FAILURE(*status)) {
     445           0 :        return -1;
     446           0 :     } else if (sp.size() > outBufLength) {
     447           0 :         *status = U_BUFFER_OVERFLOW_ERROR;
     448           0 :     } else if (sp.size() == outBufLength) {
     449           0 :         uprv_strncpy(outBuf, sp.data(), sp.size());
     450           0 :         *status = U_STRING_NOT_TERMINATED_WARNING;
     451             :     } else {
     452           0 :         U_ASSERT(outBufLength > 0);
     453           0 :         uprv_strcpy(outBuf, sp.data());
     454             :     }
     455           0 :     return sp.size();
     456             : }
     457             : 
     458             : U_CAPI double U_EXPORT2
     459           0 : unum_parseDoubleCurrency(const UNumberFormat* fmt,
     460             :                          const UChar* text,
     461             :                          int32_t textLength,
     462             :                          int32_t* parsePos, /* 0 = start */
     463             :                          UChar* currency,
     464             :                          UErrorCode* status) {
     465           0 :     double doubleVal = 0.0;
     466           0 :     currency[0] = 0;
     467           0 :     if (U_FAILURE(*status)) {
     468           0 :         return doubleVal;
     469             :     }
     470           0 :     const UnicodeString src((UBool)(textLength == -1), text, textLength);
     471           0 :     ParsePosition pp;
     472           0 :     if (parsePos != NULL) {
     473           0 :         pp.setIndex(*parsePos);
     474             :     }
     475           0 :     *status = U_PARSE_ERROR; // assume failure, reset if succeed
     476           0 :     LocalPointer<CurrencyAmount> currAmt(((const NumberFormat*)fmt)->parseCurrency(src, pp));
     477           0 :     if (pp.getErrorIndex() != -1) {
     478           0 :         if (parsePos != NULL) {
     479           0 :             *parsePos = pp.getErrorIndex();
     480             :         }
     481             :     } else {
     482           0 :         if (parsePos != NULL) {
     483           0 :             *parsePos = pp.getIndex();
     484             :         }
     485           0 :         if (pp.getIndex() > 0) {
     486           0 :             *status = U_ZERO_ERROR;
     487           0 :             u_strcpy(currency, currAmt->getISOCurrency());
     488           0 :             doubleVal = currAmt->getNumber().getDouble(*status);
     489             :         }
     490             :     }
     491           0 :     return doubleVal;
     492             : }
     493             : 
     494             : U_CAPI const char* U_EXPORT2
     495           0 : unum_getAvailable(int32_t index)
     496             : {
     497           0 :     return uloc_getAvailable(index);
     498             : }
     499             : 
     500             : U_CAPI int32_t U_EXPORT2
     501           0 : unum_countAvailable()
     502             : {
     503           0 :     return uloc_countAvailable();
     504             : }
     505             : 
     506             : U_CAPI int32_t U_EXPORT2
     507           0 : unum_getAttribute(const UNumberFormat*          fmt,
     508             :           UNumberFormatAttribute  attr)
     509             : {
     510           0 :   const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
     511           0 :   if ( attr == UNUM_LENIENT_PARSE ) {
     512             :     // Supported for all subclasses
     513           0 :     return nf->isLenient();
     514             :   }
     515             : 
     516             :   // The remaining attributea are only supported for DecimalFormat
     517           0 :   const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
     518           0 :   if (df != NULL) {
     519           0 :     UErrorCode ignoredStatus = U_ZERO_ERROR;
     520           0 :     return df->getAttribute( attr, ignoredStatus );
     521             :   }
     522             : 
     523           0 :   return -1;
     524             : }
     525             : 
     526             : U_CAPI void U_EXPORT2
     527           0 : unum_setAttribute(    UNumberFormat*          fmt,
     528             :             UNumberFormatAttribute  attr,
     529             :             int32_t                 newValue)
     530             : {
     531           0 :   NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
     532           0 :   if ( attr == UNUM_LENIENT_PARSE ) {
     533             :     // Supported for all subclasses
     534             :     // keep this here as the class may not be a DecimalFormat
     535           0 :     return nf->setLenient(newValue != 0);
     536             :   }
     537             :   // The remaining attributea are only supported for DecimalFormat
     538           0 :   DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
     539           0 :   if (df != NULL) {
     540           0 :     UErrorCode ignoredStatus = U_ZERO_ERROR;
     541           0 :     df->setAttribute(attr, newValue, ignoredStatus);
     542             :   }
     543             : }
     544             : 
     545             : U_CAPI double U_EXPORT2
     546           0 : unum_getDoubleAttribute(const UNumberFormat*          fmt,
     547             :           UNumberFormatAttribute  attr)
     548             : {
     549           0 :     const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
     550           0 :     const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
     551           0 :     if (df != NULL &&  attr == UNUM_ROUNDING_INCREMENT) {
     552           0 :         return df->getRoundingIncrement();
     553             :     } else {
     554           0 :         return -1.0;
     555             :     }
     556             : }
     557             : 
     558             : U_CAPI void U_EXPORT2
     559           0 : unum_setDoubleAttribute(    UNumberFormat*          fmt,
     560             :             UNumberFormatAttribute  attr,
     561             :             double                 newValue)
     562             : {
     563           0 :     NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
     564           0 :     DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
     565           0 :     if (df != NULL && attr == UNUM_ROUNDING_INCREMENT) {   
     566           0 :         df->setRoundingIncrement(newValue);
     567             :     }
     568           0 : }
     569             : 
     570             : U_CAPI int32_t U_EXPORT2
     571           0 : unum_getTextAttribute(const UNumberFormat*  fmt,
     572             :             UNumberFormatTextAttribute      tag,
     573             :             UChar*                          result,
     574             :             int32_t                         resultLength,
     575             :             UErrorCode*                     status)
     576             : {
     577           0 :     if(U_FAILURE(*status))
     578           0 :         return -1;
     579             : 
     580           0 :     UnicodeString res;
     581           0 :     if(!(result==NULL && resultLength==0)) {
     582             :         // NULL destination for pure preflighting: empty dummy string
     583             :         // otherwise, alias the destination buffer
     584           0 :         res.setTo(result, 0, resultLength);
     585             :     }
     586             : 
     587           0 :     const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
     588           0 :     const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
     589           0 :     if (df != NULL) {
     590           0 :         switch(tag) {
     591             :         case UNUM_POSITIVE_PREFIX:
     592           0 :             df->getPositivePrefix(res);
     593           0 :             break;
     594             : 
     595             :         case UNUM_POSITIVE_SUFFIX:
     596           0 :             df->getPositiveSuffix(res);
     597           0 :             break;
     598             : 
     599             :         case UNUM_NEGATIVE_PREFIX:
     600           0 :             df->getNegativePrefix(res);
     601           0 :             break;
     602             : 
     603             :         case UNUM_NEGATIVE_SUFFIX:
     604           0 :             df->getNegativeSuffix(res);
     605           0 :             break;
     606             : 
     607             :         case UNUM_PADDING_CHARACTER:
     608           0 :             res = df->getPadCharacterString();
     609           0 :             break;
     610             : 
     611             :         case UNUM_CURRENCY_CODE:
     612           0 :             res = UnicodeString(df->getCurrency());
     613           0 :             break;
     614             : 
     615             :         default:
     616           0 :             *status = U_UNSUPPORTED_ERROR;
     617           0 :             return -1;
     618             :         }
     619             :     } else {
     620           0 :         const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
     621           0 :         U_ASSERT(rbnf != NULL);
     622           0 :         if (tag == UNUM_DEFAULT_RULESET) {
     623           0 :             res = rbnf->getDefaultRuleSetName();
     624           0 :         } else if (tag == UNUM_PUBLIC_RULESETS) {
     625           0 :             int32_t count = rbnf->getNumberOfRuleSetNames();
     626           0 :             for (int i = 0; i < count; ++i) {
     627           0 :                 res += rbnf->getRuleSetName(i);
     628           0 :                 res += (UChar)0x003b; // semicolon
     629             :             }
     630             :         } else {
     631           0 :             *status = U_UNSUPPORTED_ERROR;
     632           0 :             return -1;
     633             :         }
     634             :     }
     635             : 
     636           0 :     return res.extract(result, resultLength, *status);
     637             : }
     638             : 
     639             : U_CAPI void U_EXPORT2
     640           0 : unum_setTextAttribute(    UNumberFormat*                    fmt,
     641             :             UNumberFormatTextAttribute      tag,
     642             :             const    UChar*                            newValue,
     643             :             int32_t                            newValueLength,
     644             :             UErrorCode                        *status)
     645             : {
     646           0 :     if(U_FAILURE(*status))
     647           0 :         return;
     648             : 
     649           0 :     UnicodeString val(newValue, newValueLength);
     650           0 :     NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
     651           0 :     DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
     652           0 :     if (df != NULL) {
     653           0 :       switch(tag) {
     654             :       case UNUM_POSITIVE_PREFIX:
     655           0 :         df->setPositivePrefix(val);
     656           0 :         break;
     657             :         
     658             :       case UNUM_POSITIVE_SUFFIX:
     659           0 :         df->setPositiveSuffix(val);
     660           0 :         break;
     661             :         
     662             :       case UNUM_NEGATIVE_PREFIX:
     663           0 :         df->setNegativePrefix(val);
     664           0 :         break;
     665             :         
     666             :       case UNUM_NEGATIVE_SUFFIX:
     667           0 :         df->setNegativeSuffix(val);
     668           0 :         break;
     669             :         
     670             :       case UNUM_PADDING_CHARACTER:
     671           0 :         df->setPadCharacter(val);
     672           0 :         break;
     673             :         
     674             :       case UNUM_CURRENCY_CODE:
     675           0 :         df->setCurrency(val.getTerminatedBuffer(), *status);
     676           0 :         break;
     677             :         
     678             :       default:
     679           0 :         *status = U_UNSUPPORTED_ERROR;
     680           0 :         break;
     681             :       }
     682             :     } else {
     683           0 :       RuleBasedNumberFormat* rbnf = dynamic_cast<RuleBasedNumberFormat*>(nf);
     684           0 :       U_ASSERT(rbnf != NULL);
     685           0 :       if (tag == UNUM_DEFAULT_RULESET) {
     686           0 :         rbnf->setDefaultRuleSet(val, *status);
     687             :       } else {
     688           0 :         *status = U_UNSUPPORTED_ERROR;
     689             :       }
     690             :     }
     691             : }
     692             : 
     693             : U_CAPI int32_t U_EXPORT2
     694           0 : unum_toPattern(    const    UNumberFormat*          fmt,
     695             :         UBool                  isPatternLocalized,
     696             :         UChar*                  result,
     697             :         int32_t                 resultLength,
     698             :         UErrorCode*             status)
     699             : {
     700           0 :     if(U_FAILURE(*status))
     701           0 :         return -1;
     702             :     
     703           0 :     UnicodeString pat;
     704           0 :     if(!(result==NULL && resultLength==0)) {
     705             :         // NULL destination for pure preflighting: empty dummy string
     706             :         // otherwise, alias the destination buffer
     707           0 :         pat.setTo(result, 0, resultLength);
     708             :     }
     709             : 
     710           0 :     const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
     711           0 :     const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
     712           0 :     if (df != NULL) {
     713           0 :       if(isPatternLocalized)
     714           0 :         df->toLocalizedPattern(pat);
     715             :       else
     716           0 :         df->toPattern(pat);
     717             :     } else {
     718           0 :       const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
     719           0 :       U_ASSERT(rbnf != NULL);
     720           0 :       pat = rbnf->getRules();
     721             :     }
     722           0 :     return pat.extract(result, resultLength, *status);
     723             : }
     724             : 
     725             : U_CAPI int32_t U_EXPORT2
     726           0 : unum_getSymbol(const UNumberFormat *fmt,
     727             :                UNumberFormatSymbol symbol,
     728             :                UChar *buffer,
     729             :                int32_t size,
     730             :                UErrorCode *status)
     731             : {
     732           0 :     if(status==NULL || U_FAILURE(*status)) {
     733           0 :         return 0;
     734             :     }
     735           0 :     if(fmt==NULL || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT) {
     736           0 :         *status=U_ILLEGAL_ARGUMENT_ERROR;
     737           0 :         return 0;
     738             :     }
     739           0 :     const NumberFormat *nf = reinterpret_cast<const NumberFormat *>(fmt);
     740           0 :     const DecimalFormat *dcf = dynamic_cast<const DecimalFormat *>(nf);
     741           0 :     if (dcf == NULL) {
     742           0 :       *status = U_UNSUPPORTED_ERROR;
     743           0 :       return 0;
     744             :     }
     745             : 
     746             :     return dcf->
     747           0 :       getDecimalFormatSymbols()->
     748           0 :         getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol).
     749           0 :           extract(buffer, size, *status);
     750             : }
     751             : 
     752             : U_CAPI void U_EXPORT2
     753           0 : unum_setSymbol(UNumberFormat *fmt,
     754             :                UNumberFormatSymbol symbol,
     755             :                const UChar *value,
     756             :                int32_t length,
     757             :                UErrorCode *status)
     758             : {
     759           0 :     if(status==NULL || U_FAILURE(*status)) {
     760           0 :         return;
     761             :     }
     762           0 :     if(fmt==NULL || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT || value==NULL || length<-1) {
     763           0 :         *status=U_ILLEGAL_ARGUMENT_ERROR;
     764           0 :         return;
     765             :     }
     766           0 :     NumberFormat *nf = reinterpret_cast<NumberFormat *>(fmt);
     767           0 :     DecimalFormat *dcf = dynamic_cast<DecimalFormat *>(nf);
     768           0 :     if (dcf == NULL) {
     769           0 :       *status = U_UNSUPPORTED_ERROR;
     770           0 :       return;
     771             :     }
     772             : 
     773           0 :     DecimalFormatSymbols symbols(*dcf->getDecimalFormatSymbols());
     774             :     symbols.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol,
     775           0 :         UnicodeString(value, length));  /* UnicodeString can handle the case when length = -1. */
     776           0 :     dcf->setDecimalFormatSymbols(symbols);
     777             : }
     778             : 
     779             : U_CAPI void U_EXPORT2
     780           0 : unum_applyPattern(  UNumberFormat  *fmt,
     781             :                     UBool          localized,
     782             :                     const UChar    *pattern,
     783             :                     int32_t        patternLength,
     784             :                     UParseError    *parseError,
     785             :                     UErrorCode*    status)
     786             : {
     787           0 :     UErrorCode tStatus = U_ZERO_ERROR;
     788             :     UParseError tParseError;
     789             :     
     790           0 :     if(parseError == NULL){
     791           0 :         parseError = &tParseError;
     792             :     }
     793             :     
     794           0 :     if(status==NULL){
     795           0 :         status = &tStatus;
     796             :     }
     797             :     
     798           0 :     int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength);
     799           0 :     const UnicodeString pat((UChar*)pattern, len, len);
     800             : 
     801             :     // Verify if the object passed is a DecimalFormat object
     802           0 :     NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
     803           0 :     DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
     804           0 :     if (df != NULL) {
     805           0 :       if(localized) {
     806           0 :         df->applyLocalizedPattern(pat,*parseError, *status);
     807             :       } else {
     808           0 :         df->applyPattern(pat,*parseError, *status);
     809             :       }
     810             :     } else {
     811           0 :       *status = U_UNSUPPORTED_ERROR;
     812           0 :       return;
     813             :     }
     814             : }
     815             : 
     816             : U_CAPI const char* U_EXPORT2
     817           0 : unum_getLocaleByType(const UNumberFormat *fmt,
     818             :                      ULocDataLocaleType type,
     819             :                      UErrorCode* status)
     820             : {
     821           0 :     if (fmt == NULL) {
     822           0 :         if (U_SUCCESS(*status)) {
     823           0 :             *status = U_ILLEGAL_ARGUMENT_ERROR;
     824             :         }
     825           0 :         return NULL;
     826             :     }
     827           0 :     return ((const Format*)fmt)->getLocaleID(type, *status);
     828             : }
     829             : 
     830             : U_CAPI void U_EXPORT2
     831           0 : unum_setContext(UNumberFormat* fmt, UDisplayContext value, UErrorCode* status)
     832             : {
     833           0 :     if (U_FAILURE(*status)) {
     834           0 :         return;
     835             :     }
     836           0 :     ((NumberFormat*)fmt)->setContext(value, *status);
     837           0 :     return;
     838             : }
     839             : 
     840             : U_CAPI UDisplayContext U_EXPORT2
     841           0 : unum_getContext(const UNumberFormat *fmt, UDisplayContextType type, UErrorCode* status)
     842             : {
     843           0 :     if (U_FAILURE(*status)) {
     844           0 :         return (UDisplayContext)0;
     845             :     }
     846           0 :     return ((const NumberFormat*)fmt)->getContext(type, *status);
     847             : }
     848             : 
     849             : U_INTERNAL UFormattable * U_EXPORT2
     850           0 : unum_parseToUFormattable(const UNumberFormat* fmt,
     851             :                          UFormattable *result,
     852             :                          const UChar* text,
     853             :                          int32_t textLength,
     854             :                          int32_t* parsePos, /* 0 = start */
     855             :                          UErrorCode* status) {
     856           0 :   UFormattable *newFormattable = NULL;
     857           0 :   if (U_FAILURE(*status)) return result;
     858           0 :   if (fmt == NULL || (text==NULL && textLength!=0)) {
     859           0 :     *status = U_ILLEGAL_ARGUMENT_ERROR;
     860           0 :     return result;
     861             :   }
     862           0 :   if (result == NULL) { // allocate if not allocated.
     863           0 :     newFormattable = result = ufmt_open(status);
     864             :   }
     865           0 :   parseRes(*(Formattable::fromUFormattable(result)), fmt, text, textLength, parsePos, status);
     866           0 :   if (U_FAILURE(*status) && newFormattable != NULL) {
     867           0 :     ufmt_close(newFormattable);
     868           0 :     result = NULL; // deallocate if there was a parse error
     869             :   }
     870           0 :   return result;
     871             : }
     872             : 
     873             : U_INTERNAL int32_t U_EXPORT2
     874           0 : unum_formatUFormattable(const UNumberFormat* fmt,
     875             :                         const UFormattable *number,
     876             :                         UChar *result,
     877             :                         int32_t resultLength,
     878             :                         UFieldPosition *pos, /* ignored if 0 */
     879             :                         UErrorCode *status) {
     880           0 :     if (U_FAILURE(*status)) {
     881           0 :       return 0;
     882             :     }
     883           0 :     if (fmt == NULL || number==NULL ||
     884           0 :         (result==NULL ? resultLength!=0 : resultLength<0)) {
     885           0 :       *status = U_ILLEGAL_ARGUMENT_ERROR;
     886           0 :       return 0;
     887             :     }
     888           0 :     UnicodeString res(result, 0, resultLength);
     889             : 
     890           0 :     FieldPosition fp;
     891             : 
     892           0 :     if(pos != 0)
     893           0 :         fp.setField(pos->field);
     894             : 
     895           0 :     ((const NumberFormat*)fmt)->format(*(Formattable::fromUFormattable(number)), res, fp, *status);
     896             : 
     897           0 :     if(pos != 0) {
     898           0 :         pos->beginIndex = fp.getBeginIndex();
     899           0 :         pos->endIndex = fp.getEndIndex();
     900             :     }
     901             : 
     902           0 :     return res.extract(result, resultLength, *status);
     903             : }
     904             : 
     905             : #endif /* #if !UCONFIG_NO_FORMATTING */

Generated by: LCOV version 1.13