2 *******************************************************************************
3 * Copyright (C) 1996-2014, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *******************************************************************************
6 * Modification History:
8 * Date Name Description
9 * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes
10 *******************************************************************************
13 #include "unicode/utypes.h"
15 #if !UCONFIG_NO_FORMATTING
17 #include "unicode/unum.h"
19 #include "unicode/uloc.h"
20 #include "unicode/numfmt.h"
21 #include "unicode/decimfmt.h"
22 #include "unicode/rbnf.h"
23 #include "unicode/compactdecimalformat.h"
24 #include "unicode/ustring.h"
25 #include "unicode/fmtable.h"
26 #include "unicode/dcfmtsym.h"
27 #include "unicode/curramt.h"
28 #include "unicode/localpointer.h"
29 #include "unicode/udisplaycontext.h"
38 U_CAPI UNumberFormat
* U_EXPORT2
39 unum_open( UNumberFormatStyle style
,
41 int32_t patternLength
,
43 UParseError
* parseErr
,
45 if(U_FAILURE(*status
)) {
49 NumberFormat
*retVal
= NULL
;
56 case UNUM_CURRENCY_ISO
:
57 case UNUM_CURRENCY_PLURAL
:
58 case UNUM_CURRENCY_ACCOUNTING
:
59 case UNUM_CASH_CURRENCY
:
60 retVal
= NumberFormat::createInstance(Locale(locale
), style
, *status
);
63 case UNUM_PATTERN_DECIMAL
: {
65 /* UnicodeString can handle the case when patternLength = -1. */
66 const UnicodeString
pat(pattern
, patternLength
);
72 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale(locale
), *status
);
74 *status
= U_MEMORY_ALLOCATION_ERROR
;
77 if (U_FAILURE(*status
)) {
82 retVal
= new DecimalFormat(pat
, syms
, *parseErr
, *status
);
89 case UNUM_PATTERN_RULEBASED
: {
91 /* UnicodeString can handle the case when patternLength = -1. */
92 const UnicodeString
pat(pattern
, patternLength
);
98 retVal
= new RuleBasedNumberFormat(pat
, Locale(locale
), *parseErr
, *status
);
102 retVal
= new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale(locale
), *status
);
106 retVal
= new RuleBasedNumberFormat(URBNF_ORDINAL
, Locale(locale
), *status
);
110 retVal
= new RuleBasedNumberFormat(URBNF_DURATION
, Locale(locale
), *status
);
113 case UNUM_NUMBERING_SYSTEM
:
114 retVal
= new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM
, Locale(locale
), *status
);
118 case UNUM_DECIMAL_COMPACT_SHORT
:
119 retVal
= CompactDecimalFormat::createInstance(Locale(locale
), UNUM_SHORT
, *status
);
122 case UNUM_DECIMAL_COMPACT_LONG
:
123 retVal
= CompactDecimalFormat::createInstance(Locale(locale
), UNUM_LONG
, *status
);
127 *status
= U_UNSUPPORTED_ERROR
;
131 if(retVal
== NULL
&& U_SUCCESS(*status
)) {
132 *status
= U_MEMORY_ALLOCATION_ERROR
;
135 return reinterpret_cast<UNumberFormat
*>(retVal
);
138 U_CAPI
void U_EXPORT2
139 unum_close(UNumberFormat
* fmt
)
141 delete (NumberFormat
*) fmt
;
144 U_CAPI UNumberFormat
* U_EXPORT2
145 unum_clone(const UNumberFormat
*fmt
,
148 if(U_FAILURE(*status
))
152 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
153 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
157 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
158 U_ASSERT(rbnf
!= NULL
);
163 *status
= U_MEMORY_ALLOCATION_ERROR
;
167 return (UNumberFormat
*) res
;
170 U_CAPI
int32_t U_EXPORT2
171 unum_format( const UNumberFormat
* fmt
,
174 int32_t resultLength
,
178 return unum_formatInt64(fmt
, number
, result
, resultLength
, pos
, status
);
181 U_CAPI
int32_t U_EXPORT2
182 unum_formatInt64(const UNumberFormat
* fmt
,
185 int32_t resultLength
,
189 if(U_FAILURE(*status
))
193 if(!(result
==NULL
&& resultLength
==0)) {
194 // NULL destination for pure preflighting: empty dummy string
195 // otherwise, alias the destination buffer
196 res
.setTo(result
, 0, resultLength
);
202 fp
.setField(pos
->field
);
204 const CompactDecimalFormat
* cdf
= dynamic_cast<const CompactDecimalFormat
*>((const NumberFormat
*)fmt
);
206 cdf
->format(number
, res
, fp
); // CompactDecimalFormat does not override the version with UErrorCode& !!
208 ((const NumberFormat
*)fmt
)->format(number
, res
, fp
, *status
);
212 pos
->beginIndex
= fp
.getBeginIndex();
213 pos
->endIndex
= fp
.getEndIndex();
216 return res
.extract(result
, resultLength
, *status
);
219 U_CAPI
int32_t U_EXPORT2
220 unum_formatDouble( const UNumberFormat
* fmt
,
223 int32_t resultLength
,
224 UFieldPosition
*pos
, /* 0 if ignore */
228 if(U_FAILURE(*status
)) return -1;
231 if(!(result
==NULL
&& resultLength
==0)) {
232 // NULL destination for pure preflighting: empty dummy string
233 // otherwise, alias the destination buffer
234 res
.setTo(result
, 0, resultLength
);
240 fp
.setField(pos
->field
);
242 const CompactDecimalFormat
* cdf
= dynamic_cast<const CompactDecimalFormat
*>((const NumberFormat
*)fmt
);
244 cdf
->format(number
, res
, fp
); // CompactDecimalFormat does not override the version with UErrorCode& !!
246 ((const NumberFormat
*)fmt
)->format(number
, res
, fp
, *status
);
250 pos
->beginIndex
= fp
.getBeginIndex();
251 pos
->endIndex
= fp
.getEndIndex();
254 return res
.extract(result
, resultLength
, *status
);
258 U_CAPI
int32_t U_EXPORT2
259 unum_formatDecimal(const UNumberFormat
* fmt
,
263 int32_t resultLength
,
264 UFieldPosition
*pos
, /* 0 if ignore */
265 UErrorCode
* status
) {
267 if(U_FAILURE(*status
)) {
270 if ((result
== NULL
&& resultLength
!= 0) || resultLength
< 0) {
271 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
277 fp
.setField(pos
->field
);
281 length
= uprv_strlen(number
);
283 StringPiece
numSP(number
, length
);
284 Formattable
numFmtbl(numSP
, *status
);
286 UnicodeString resultStr
;
287 if (resultLength
> 0) {
288 // Alias the destination buffer.
289 resultStr
.setTo(result
, 0, resultLength
);
291 ((const NumberFormat
*)fmt
)->format(numFmtbl
, resultStr
, fp
, *status
);
293 pos
->beginIndex
= fp
.getBeginIndex();
294 pos
->endIndex
= fp
.getEndIndex();
296 return resultStr
.extract(result
, resultLength
, *status
);
302 U_CAPI
int32_t U_EXPORT2
303 unum_formatDoubleCurrency(const UNumberFormat
* fmt
,
307 int32_t resultLength
,
308 UFieldPosition
* pos
, /* ignored if 0 */
309 UErrorCode
* status
) {
310 if (U_FAILURE(*status
)) return -1;
313 if (!(result
==NULL
&& resultLength
==0)) {
314 // NULL destination for pure preflighting: empty dummy string
315 // otherwise, alias the destination buffer
316 res
.setTo(result
, 0, resultLength
);
321 fp
.setField(pos
->field
);
323 CurrencyAmount
*tempCurrAmnt
= new CurrencyAmount(number
, currency
, *status
);
324 // Check for null pointer.
325 if (tempCurrAmnt
== NULL
) {
326 *status
= U_MEMORY_ALLOCATION_ERROR
;
329 Formattable
n(tempCurrAmnt
);
330 ((const NumberFormat
*)fmt
)->format(n
, res
, fp
, *status
);
333 pos
->beginIndex
= fp
.getBeginIndex();
334 pos
->endIndex
= fp
.getEndIndex();
337 return res
.extract(result
, resultLength
, *status
);
341 parseRes(Formattable
& res
,
342 const UNumberFormat
* fmt
,
345 int32_t *parsePos
/* 0 = start */,
348 if(U_FAILURE(*status
))
351 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
355 pp
.setIndex(*parsePos
);
357 ((const NumberFormat
*)fmt
)->parse(src
, res
, pp
);
359 if(pp
.getErrorIndex() != -1) {
360 *status
= U_PARSE_ERROR
;
362 *parsePos
= pp
.getErrorIndex();
364 } else if(parsePos
!= 0) {
365 *parsePos
= pp
.getIndex();
369 U_CAPI
int32_t U_EXPORT2
370 unum_parse( const UNumberFormat
* fmt
,
373 int32_t *parsePos
/* 0 = start */,
377 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
378 return res
.getLong(*status
);
381 U_CAPI
int64_t U_EXPORT2
382 unum_parseInt64( const UNumberFormat
* fmt
,
385 int32_t *parsePos
/* 0 = start */,
389 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
390 return res
.getInt64(*status
);
393 U_CAPI
double U_EXPORT2
394 unum_parseDouble( const UNumberFormat
* fmt
,
397 int32_t *parsePos
/* 0 = start */,
401 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
402 return res
.getDouble(*status
);
405 U_CAPI
int32_t U_EXPORT2
406 unum_parseDecimal(const UNumberFormat
* fmt
,
409 int32_t *parsePos
/* 0 = start */,
411 int32_t outBufLength
,
414 if (U_FAILURE(*status
)) {
417 if ((outBuf
== NULL
&& outBufLength
!= 0) || outBufLength
< 0) {
418 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
422 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
423 StringPiece sp
= res
.getDecimalNumber(*status
);
424 if (U_FAILURE(*status
)) {
426 } else if (sp
.size() > outBufLength
) {
427 *status
= U_BUFFER_OVERFLOW_ERROR
;
428 } else if (sp
.size() == outBufLength
) {
429 uprv_strncpy(outBuf
, sp
.data(), sp
.size());
430 *status
= U_STRING_NOT_TERMINATED_WARNING
;
432 U_ASSERT(outBufLength
> 0);
433 uprv_strcpy(outBuf
, sp
.data());
438 U_CAPI
double U_EXPORT2
439 unum_parseDoubleCurrency(const UNumberFormat
* fmt
,
442 int32_t* parsePos
, /* 0 = start */
444 UErrorCode
* status
) {
445 double doubleVal
= 0.0;
447 if (U_FAILURE(*status
)) {
450 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
452 if (parsePos
!= NULL
) {
453 pp
.setIndex(*parsePos
);
455 *status
= U_PARSE_ERROR
; // assume failure, reset if succeed
456 LocalPointer
<CurrencyAmount
> currAmt(((const NumberFormat
*)fmt
)->parseCurrency(src
, pp
));
457 if (pp
.getErrorIndex() != -1) {
458 if (parsePos
!= NULL
) {
459 *parsePos
= pp
.getErrorIndex();
462 if (parsePos
!= NULL
) {
463 *parsePos
= pp
.getIndex();
465 if (pp
.getIndex() > 0) {
466 *status
= U_ZERO_ERROR
;
467 u_strcpy(currency
, currAmt
->getISOCurrency());
468 doubleVal
= currAmt
->getNumber().getDouble(*status
);
474 U_CAPI
const char* U_EXPORT2
475 unum_getAvailable(int32_t index
)
477 return uloc_getAvailable(index
);
480 U_CAPI
int32_t U_EXPORT2
481 unum_countAvailable()
483 return uloc_countAvailable();
486 U_CAPI
int32_t U_EXPORT2
487 unum_getAttribute(const UNumberFormat
* fmt
,
488 UNumberFormatAttribute attr
)
490 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
491 if ( attr
== UNUM_LENIENT_PARSE
) {
492 // Supported for all subclasses
493 return nf
->isLenient();
496 // The remaining attributea are only supported for DecimalFormat
497 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
499 UErrorCode ignoredStatus
= U_ZERO_ERROR
;
500 return df
->getAttribute( attr
, ignoredStatus
);
506 U_CAPI
void U_EXPORT2
507 unum_setAttribute( UNumberFormat
* fmt
,
508 UNumberFormatAttribute attr
,
511 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
512 if ( attr
== UNUM_LENIENT_PARSE
) {
513 // Supported for all subclasses
514 // keep this here as the class may not be a DecimalFormat
515 return nf
->setLenient(newValue
!= 0);
517 // The remaining attributea are only supported for DecimalFormat
518 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
520 UErrorCode ignoredStatus
= U_ZERO_ERROR
;
521 df
->setAttribute(attr
, newValue
, ignoredStatus
);
525 U_CAPI
double U_EXPORT2
526 unum_getDoubleAttribute(const UNumberFormat
* fmt
,
527 UNumberFormatAttribute attr
)
529 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
530 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
531 if (df
!= NULL
&& attr
== UNUM_ROUNDING_INCREMENT
) {
532 return df
->getRoundingIncrement();
538 U_CAPI
void U_EXPORT2
539 unum_setDoubleAttribute( UNumberFormat
* fmt
,
540 UNumberFormatAttribute attr
,
543 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
544 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
545 if (df
!= NULL
&& attr
== UNUM_ROUNDING_INCREMENT
) {
546 df
->setRoundingIncrement(newValue
);
550 U_CAPI
int32_t U_EXPORT2
551 unum_getTextAttribute(const UNumberFormat
* fmt
,
552 UNumberFormatTextAttribute tag
,
554 int32_t resultLength
,
557 if(U_FAILURE(*status
))
561 if(!(result
==NULL
&& resultLength
==0)) {
562 // NULL destination for pure preflighting: empty dummy string
563 // otherwise, alias the destination buffer
564 res
.setTo(result
, 0, resultLength
);
567 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
568 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
571 case UNUM_POSITIVE_PREFIX
:
572 df
->getPositivePrefix(res
);
575 case UNUM_POSITIVE_SUFFIX
:
576 df
->getPositiveSuffix(res
);
579 case UNUM_NEGATIVE_PREFIX
:
580 df
->getNegativePrefix(res
);
583 case UNUM_NEGATIVE_SUFFIX
:
584 df
->getNegativeSuffix(res
);
587 case UNUM_PADDING_CHARACTER
:
588 res
= df
->getPadCharacterString();
591 case UNUM_CURRENCY_CODE
:
592 res
= UnicodeString(df
->getCurrency());
596 *status
= U_UNSUPPORTED_ERROR
;
600 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
601 U_ASSERT(rbnf
!= NULL
);
602 if (tag
== UNUM_DEFAULT_RULESET
) {
603 res
= rbnf
->getDefaultRuleSetName();
604 } else if (tag
== UNUM_PUBLIC_RULESETS
) {
605 int32_t count
= rbnf
->getNumberOfRuleSetNames();
606 for (int i
= 0; i
< count
; ++i
) {
607 res
+= rbnf
->getRuleSetName(i
);
608 res
+= (UChar
)0x003b; // semicolon
611 *status
= U_UNSUPPORTED_ERROR
;
616 return res
.extract(result
, resultLength
, *status
);
619 U_CAPI
void U_EXPORT2
620 unum_setTextAttribute( UNumberFormat
* fmt
,
621 UNumberFormatTextAttribute tag
,
622 const UChar
* newValue
,
623 int32_t newValueLength
,
626 if(U_FAILURE(*status
))
629 UnicodeString
val(newValue
, newValueLength
);
630 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
631 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
634 case UNUM_POSITIVE_PREFIX
:
635 df
->setPositivePrefix(val
);
638 case UNUM_POSITIVE_SUFFIX
:
639 df
->setPositiveSuffix(val
);
642 case UNUM_NEGATIVE_PREFIX
:
643 df
->setNegativePrefix(val
);
646 case UNUM_NEGATIVE_SUFFIX
:
647 df
->setNegativeSuffix(val
);
650 case UNUM_PADDING_CHARACTER
:
651 df
->setPadCharacter(val
);
654 case UNUM_CURRENCY_CODE
:
655 df
->setCurrency(val
.getTerminatedBuffer(), *status
);
659 *status
= U_UNSUPPORTED_ERROR
;
663 RuleBasedNumberFormat
* rbnf
= dynamic_cast<RuleBasedNumberFormat
*>(nf
);
664 U_ASSERT(rbnf
!= NULL
);
665 if (tag
== UNUM_DEFAULT_RULESET
) {
666 rbnf
->setDefaultRuleSet(val
, *status
);
668 *status
= U_UNSUPPORTED_ERROR
;
673 U_CAPI
int32_t U_EXPORT2
674 unum_toPattern( const UNumberFormat
* fmt
,
675 UBool isPatternLocalized
,
677 int32_t resultLength
,
680 if(U_FAILURE(*status
))
684 if(!(result
==NULL
&& resultLength
==0)) {
685 // NULL destination for pure preflighting: empty dummy string
686 // otherwise, alias the destination buffer
687 pat
.setTo(result
, 0, resultLength
);
690 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
691 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
693 if(isPatternLocalized
)
694 df
->toLocalizedPattern(pat
);
698 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
699 U_ASSERT(rbnf
!= NULL
);
700 pat
= rbnf
->getRules();
702 return pat
.extract(result
, resultLength
, *status
);
705 U_CAPI
int32_t U_EXPORT2
706 unum_getSymbol(const UNumberFormat
*fmt
,
707 UNumberFormatSymbol symbol
,
712 if(status
==NULL
|| U_FAILURE(*status
)) {
715 if(fmt
==NULL
|| symbol
< 0 || symbol
>=UNUM_FORMAT_SYMBOL_COUNT
) {
716 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
719 const NumberFormat
*nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
720 const DecimalFormat
*dcf
= dynamic_cast<const DecimalFormat
*>(nf
);
722 *status
= U_UNSUPPORTED_ERROR
;
727 getDecimalFormatSymbols()->
728 getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbol
).
729 extract(buffer
, size
, *status
);
732 U_CAPI
void U_EXPORT2
733 unum_setSymbol(UNumberFormat
*fmt
,
734 UNumberFormatSymbol symbol
,
739 if(status
==NULL
|| U_FAILURE(*status
)) {
742 if(fmt
==NULL
|| symbol
< 0 || symbol
>=UNUM_FORMAT_SYMBOL_COUNT
|| value
==NULL
|| length
<-1) {
743 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
746 NumberFormat
*nf
= reinterpret_cast<NumberFormat
*>(fmt
);
747 DecimalFormat
*dcf
= dynamic_cast<DecimalFormat
*>(nf
);
749 *status
= U_UNSUPPORTED_ERROR
;
753 DecimalFormatSymbols
symbols(*dcf
->getDecimalFormatSymbols());
754 symbols
.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbol
,
755 UnicodeString(value
, length
)); /* UnicodeString can handle the case when length = -1. */
756 dcf
->setDecimalFormatSymbols(symbols
);
759 U_CAPI
void U_EXPORT2
760 unum_applyPattern( UNumberFormat
*fmt
,
762 const UChar
*pattern
,
763 int32_t patternLength
,
764 UParseError
*parseError
,
767 UErrorCode tStatus
= U_ZERO_ERROR
;
768 UParseError tParseError
;
770 if(parseError
== NULL
){
771 parseError
= &tParseError
;
778 int32_t len
= (patternLength
== -1 ? u_strlen(pattern
) : patternLength
);
779 const UnicodeString
pat((UChar
*)pattern
, len
, len
);
781 // Verify if the object passed is a DecimalFormat object
782 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
783 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
786 df
->applyLocalizedPattern(pat
,*parseError
, *status
);
788 df
->applyPattern(pat
,*parseError
, *status
);
791 *status
= U_UNSUPPORTED_ERROR
;
796 U_CAPI
const char* U_EXPORT2
797 unum_getLocaleByType(const UNumberFormat
*fmt
,
798 ULocDataLocaleType type
,
802 if (U_SUCCESS(*status
)) {
803 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
807 return ((const Format
*)fmt
)->getLocaleID(type
, *status
);
810 U_CAPI
void U_EXPORT2
811 unum_setContext(UNumberFormat
* fmt
, UDisplayContext value
, UErrorCode
* status
)
813 if (U_FAILURE(*status
)) {
816 ((NumberFormat
*)fmt
)->setContext(value
, *status
);
820 U_CAPI UDisplayContext U_EXPORT2
821 unum_getContext(const UNumberFormat
*fmt
, UDisplayContextType type
, UErrorCode
* status
)
823 if (U_FAILURE(*status
)) {
824 return (UDisplayContext
)0;
826 return ((const NumberFormat
*)fmt
)->getContext(type
, *status
);
829 U_INTERNAL UFormattable
* U_EXPORT2
830 unum_parseToUFormattable(const UNumberFormat
* fmt
,
831 UFormattable
*result
,
834 int32_t* parsePos
, /* 0 = start */
835 UErrorCode
* status
) {
836 UFormattable
*newFormattable
= NULL
;
837 if (U_FAILURE(*status
)) return result
;
838 if (fmt
== NULL
|| (text
==NULL
&& textLength
!=0)) {
839 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
842 if (result
== NULL
) { // allocate if not allocated.
843 newFormattable
= result
= ufmt_open(status
);
845 parseRes(*(Formattable::fromUFormattable(result
)), fmt
, text
, textLength
, parsePos
, status
);
846 if (U_FAILURE(*status
) && newFormattable
!= NULL
) {
847 ufmt_close(newFormattable
);
848 result
= NULL
; // deallocate if there was a parse error
853 U_INTERNAL
int32_t U_EXPORT2
854 unum_formatUFormattable(const UNumberFormat
* fmt
,
855 const UFormattable
*number
,
857 int32_t resultLength
,
858 UFieldPosition
*pos
, /* ignored if 0 */
859 UErrorCode
*status
) {
860 if (U_FAILURE(*status
)) {
863 if (fmt
== NULL
|| number
==NULL
||
864 (result
==NULL
? resultLength
!=0 : resultLength
<0)) {
865 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
868 UnicodeString
res(result
, 0, resultLength
);
873 fp
.setField(pos
->field
);
875 ((const NumberFormat
*)fmt
)->format(*(Formattable::fromUFormattable(number
)), res
, fp
, *status
);
878 pos
->beginIndex
= fp
.getBeginIndex();
879 pos
->endIndex
= fp
.getEndIndex();
882 return res
.extract(result
, resultLength
, *status
);
885 #endif /* #if !UCONFIG_NO_FORMATTING */