2 *******************************************************************************
3 * Copyright (C) 1996-2015, 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 case UNUM_CURRENCY_STANDARD
:
61 retVal
= NumberFormat::createInstance(Locale(locale
), style
, *status
);
64 case UNUM_PATTERN_DECIMAL
: {
66 /* UnicodeString can handle the case when patternLength = -1. */
67 const UnicodeString
pat(pattern
, patternLength
);
73 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale(locale
), *status
);
75 *status
= U_MEMORY_ALLOCATION_ERROR
;
78 if (U_FAILURE(*status
)) {
83 retVal
= new DecimalFormat(pat
, syms
, *parseErr
, *status
);
90 case UNUM_PATTERN_RULEBASED
: {
92 /* UnicodeString can handle the case when patternLength = -1. */
93 const UnicodeString
pat(pattern
, patternLength
);
99 retVal
= new RuleBasedNumberFormat(pat
, Locale(locale
), *parseErr
, *status
);
103 retVal
= new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale(locale
), *status
);
107 retVal
= new RuleBasedNumberFormat(URBNF_ORDINAL
, Locale(locale
), *status
);
111 retVal
= new RuleBasedNumberFormat(URBNF_DURATION
, Locale(locale
), *status
);
114 case UNUM_NUMBERING_SYSTEM
:
115 retVal
= new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM
, Locale(locale
), *status
);
119 case UNUM_DECIMAL_COMPACT_SHORT
:
120 retVal
= CompactDecimalFormat::createInstance(Locale(locale
), UNUM_SHORT
, *status
);
123 case UNUM_DECIMAL_COMPACT_LONG
:
124 retVal
= CompactDecimalFormat::createInstance(Locale(locale
), UNUM_LONG
, *status
);
128 *status
= U_UNSUPPORTED_ERROR
;
132 if(retVal
== NULL
&& U_SUCCESS(*status
)) {
133 *status
= U_MEMORY_ALLOCATION_ERROR
;
136 return reinterpret_cast<UNumberFormat
*>(retVal
);
139 U_CAPI
void U_EXPORT2
140 unum_close(UNumberFormat
* fmt
)
142 delete (NumberFormat
*) fmt
;
145 U_CAPI UNumberFormat
* U_EXPORT2
146 unum_clone(const UNumberFormat
*fmt
,
149 if(U_FAILURE(*status
))
153 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
154 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
158 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
159 U_ASSERT(rbnf
!= NULL
);
164 *status
= U_MEMORY_ALLOCATION_ERROR
;
168 return (UNumberFormat
*) res
;
171 U_CAPI
int32_t U_EXPORT2
172 unum_format( const UNumberFormat
* fmt
,
175 int32_t resultLength
,
179 return unum_formatInt64(fmt
, number
, result
, resultLength
, pos
, status
);
182 U_CAPI
int32_t U_EXPORT2
183 unum_formatInt64(const UNumberFormat
* fmt
,
186 int32_t resultLength
,
190 if(U_FAILURE(*status
))
194 if(!(result
==NULL
&& resultLength
==0)) {
195 // NULL destination for pure preflighting: empty dummy string
196 // otherwise, alias the destination buffer
197 res
.setTo(result
, 0, resultLength
);
203 fp
.setField(pos
->field
);
205 const CompactDecimalFormat
* cdf
= dynamic_cast<const CompactDecimalFormat
*>((const NumberFormat
*)fmt
);
207 cdf
->format(number
, res
, fp
); // CompactDecimalFormat does not override the version with UErrorCode& !!
209 ((const NumberFormat
*)fmt
)->format(number
, res
, fp
, *status
);
213 pos
->beginIndex
= fp
.getBeginIndex();
214 pos
->endIndex
= fp
.getEndIndex();
217 return res
.extract(result
, resultLength
, *status
);
220 U_CAPI
int32_t U_EXPORT2
221 unum_formatDouble( const UNumberFormat
* fmt
,
224 int32_t resultLength
,
225 UFieldPosition
*pos
, /* 0 if ignore */
229 if(U_FAILURE(*status
)) return -1;
232 if(!(result
==NULL
&& resultLength
==0)) {
233 // NULL destination for pure preflighting: empty dummy string
234 // otherwise, alias the destination buffer
235 res
.setTo(result
, 0, resultLength
);
241 fp
.setField(pos
->field
);
243 const CompactDecimalFormat
* cdf
= dynamic_cast<const CompactDecimalFormat
*>((const NumberFormat
*)fmt
);
245 cdf
->format(number
, res
, fp
); // CompactDecimalFormat does not override the version with UErrorCode& !!
247 ((const NumberFormat
*)fmt
)->format(number
, res
, fp
, *status
);
251 pos
->beginIndex
= fp
.getBeginIndex();
252 pos
->endIndex
= fp
.getEndIndex();
255 return res
.extract(result
, resultLength
, *status
);
259 U_CAPI
int32_t U_EXPORT2
260 unum_formatDecimal(const UNumberFormat
* fmt
,
264 int32_t resultLength
,
265 UFieldPosition
*pos
, /* 0 if ignore */
266 UErrorCode
* status
) {
268 if(U_FAILURE(*status
)) {
271 if ((result
== NULL
&& resultLength
!= 0) || resultLength
< 0) {
272 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
278 fp
.setField(pos
->field
);
282 length
= uprv_strlen(number
);
284 StringPiece
numSP(number
, length
);
285 Formattable
numFmtbl(numSP
, *status
);
287 UnicodeString resultStr
;
288 if (resultLength
> 0) {
289 // Alias the destination buffer.
290 resultStr
.setTo(result
, 0, resultLength
);
292 ((const NumberFormat
*)fmt
)->format(numFmtbl
, resultStr
, fp
, *status
);
294 pos
->beginIndex
= fp
.getBeginIndex();
295 pos
->endIndex
= fp
.getEndIndex();
297 return resultStr
.extract(result
, resultLength
, *status
);
303 U_CAPI
int32_t U_EXPORT2
304 unum_formatDoubleCurrency(const UNumberFormat
* fmt
,
308 int32_t resultLength
,
309 UFieldPosition
* pos
, /* ignored if 0 */
310 UErrorCode
* status
) {
311 if (U_FAILURE(*status
)) return -1;
314 if (!(result
==NULL
&& resultLength
==0)) {
315 // NULL destination for pure preflighting: empty dummy string
316 // otherwise, alias the destination buffer
317 res
.setTo(result
, 0, resultLength
);
322 fp
.setField(pos
->field
);
324 CurrencyAmount
*tempCurrAmnt
= new CurrencyAmount(number
, currency
, *status
);
325 // Check for null pointer.
326 if (tempCurrAmnt
== NULL
) {
327 *status
= U_MEMORY_ALLOCATION_ERROR
;
330 Formattable
n(tempCurrAmnt
);
331 ((const NumberFormat
*)fmt
)->format(n
, res
, fp
, *status
);
334 pos
->beginIndex
= fp
.getBeginIndex();
335 pos
->endIndex
= fp
.getEndIndex();
338 return res
.extract(result
, resultLength
, *status
);
342 parseRes(Formattable
& res
,
343 const UNumberFormat
* fmt
,
346 int32_t *parsePos
/* 0 = start */,
349 if(U_FAILURE(*status
))
352 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
356 pp
.setIndex(*parsePos
);
358 ((const NumberFormat
*)fmt
)->parse(src
, res
, pp
);
360 if(pp
.getErrorIndex() != -1) {
361 *status
= U_PARSE_ERROR
;
363 *parsePos
= pp
.getErrorIndex();
365 } else if(parsePos
!= 0) {
366 *parsePos
= pp
.getIndex();
370 U_CAPI
int32_t U_EXPORT2
371 unum_parse( const UNumberFormat
* fmt
,
374 int32_t *parsePos
/* 0 = start */,
378 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
379 return res
.getLong(*status
);
382 U_CAPI
int64_t U_EXPORT2
383 unum_parseInt64( const UNumberFormat
* fmt
,
386 int32_t *parsePos
/* 0 = start */,
390 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
391 return res
.getInt64(*status
);
394 U_CAPI
double U_EXPORT2
395 unum_parseDouble( const UNumberFormat
* fmt
,
398 int32_t *parsePos
/* 0 = start */,
402 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
403 return res
.getDouble(*status
);
406 U_CAPI
int32_t U_EXPORT2
407 unum_parseDecimal(const UNumberFormat
* fmt
,
410 int32_t *parsePos
/* 0 = start */,
412 int32_t outBufLength
,
415 if (U_FAILURE(*status
)) {
418 if ((outBuf
== NULL
&& outBufLength
!= 0) || outBufLength
< 0) {
419 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
423 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
424 StringPiece sp
= res
.getDecimalNumber(*status
);
425 if (U_FAILURE(*status
)) {
427 } else if (sp
.size() > outBufLength
) {
428 *status
= U_BUFFER_OVERFLOW_ERROR
;
429 } else if (sp
.size() == outBufLength
) {
430 uprv_strncpy(outBuf
, sp
.data(), sp
.size());
431 *status
= U_STRING_NOT_TERMINATED_WARNING
;
433 U_ASSERT(outBufLength
> 0);
434 uprv_strcpy(outBuf
, sp
.data());
439 U_CAPI
double U_EXPORT2
440 unum_parseDoubleCurrency(const UNumberFormat
* fmt
,
443 int32_t* parsePos
, /* 0 = start */
445 UErrorCode
* status
) {
446 double doubleVal
= 0.0;
448 if (U_FAILURE(*status
)) {
451 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
453 if (parsePos
!= NULL
) {
454 pp
.setIndex(*parsePos
);
456 *status
= U_PARSE_ERROR
; // assume failure, reset if succeed
457 LocalPointer
<CurrencyAmount
> currAmt(((const NumberFormat
*)fmt
)->parseCurrency(src
, pp
));
458 if (pp
.getErrorIndex() != -1) {
459 if (parsePos
!= NULL
) {
460 *parsePos
= pp
.getErrorIndex();
463 if (parsePos
!= NULL
) {
464 *parsePos
= pp
.getIndex();
466 if (pp
.getIndex() > 0) {
467 *status
= U_ZERO_ERROR
;
468 u_strcpy(currency
, currAmt
->getISOCurrency());
469 doubleVal
= currAmt
->getNumber().getDouble(*status
);
475 U_CAPI
const char* U_EXPORT2
476 unum_getAvailable(int32_t index
)
478 return uloc_getAvailable(index
);
481 U_CAPI
int32_t U_EXPORT2
482 unum_countAvailable()
484 return uloc_countAvailable();
487 U_CAPI
int32_t U_EXPORT2
488 unum_getAttribute(const UNumberFormat
* fmt
,
489 UNumberFormatAttribute attr
)
491 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
492 if ( attr
== UNUM_LENIENT_PARSE
) {
493 // Supported for all subclasses
494 return nf
->isLenient();
497 // The remaining attributea are only supported for DecimalFormat
498 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
500 UErrorCode ignoredStatus
= U_ZERO_ERROR
;
501 return df
->getAttribute( attr
, ignoredStatus
);
507 U_CAPI
void U_EXPORT2
508 unum_setAttribute( UNumberFormat
* fmt
,
509 UNumberFormatAttribute attr
,
512 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
513 if ( attr
== UNUM_LENIENT_PARSE
) {
514 // Supported for all subclasses
515 // keep this here as the class may not be a DecimalFormat
516 return nf
->setLenient(newValue
!= 0);
518 // The remaining attributea are only supported for DecimalFormat
519 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
521 UErrorCode ignoredStatus
= U_ZERO_ERROR
;
522 df
->setAttribute(attr
, newValue
, ignoredStatus
);
526 U_CAPI
double U_EXPORT2
527 unum_getDoubleAttribute(const UNumberFormat
* fmt
,
528 UNumberFormatAttribute attr
)
530 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
531 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
532 if (df
!= NULL
&& attr
== UNUM_ROUNDING_INCREMENT
) {
533 return df
->getRoundingIncrement();
539 U_CAPI
void U_EXPORT2
540 unum_setDoubleAttribute( UNumberFormat
* fmt
,
541 UNumberFormatAttribute attr
,
544 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
545 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
546 if (df
!= NULL
&& attr
== UNUM_ROUNDING_INCREMENT
) {
547 df
->setRoundingIncrement(newValue
);
551 U_CAPI
int32_t U_EXPORT2
552 unum_getTextAttribute(const UNumberFormat
* fmt
,
553 UNumberFormatTextAttribute tag
,
555 int32_t resultLength
,
558 if(U_FAILURE(*status
))
562 if(!(result
==NULL
&& resultLength
==0)) {
563 // NULL destination for pure preflighting: empty dummy string
564 // otherwise, alias the destination buffer
565 res
.setTo(result
, 0, resultLength
);
568 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
569 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
572 case UNUM_POSITIVE_PREFIX
:
573 df
->getPositivePrefix(res
);
576 case UNUM_POSITIVE_SUFFIX
:
577 df
->getPositiveSuffix(res
);
580 case UNUM_NEGATIVE_PREFIX
:
581 df
->getNegativePrefix(res
);
584 case UNUM_NEGATIVE_SUFFIX
:
585 df
->getNegativeSuffix(res
);
588 case UNUM_PADDING_CHARACTER
:
589 res
= df
->getPadCharacterString();
592 case UNUM_CURRENCY_CODE
:
593 res
= UnicodeString(df
->getCurrency());
597 *status
= U_UNSUPPORTED_ERROR
;
601 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
602 U_ASSERT(rbnf
!= NULL
);
603 if (tag
== UNUM_DEFAULT_RULESET
) {
604 res
= rbnf
->getDefaultRuleSetName();
605 } else if (tag
== UNUM_PUBLIC_RULESETS
) {
606 int32_t count
= rbnf
->getNumberOfRuleSetNames();
607 for (int i
= 0; i
< count
; ++i
) {
608 res
+= rbnf
->getRuleSetName(i
);
609 res
+= (UChar
)0x003b; // semicolon
612 *status
= U_UNSUPPORTED_ERROR
;
617 return res
.extract(result
, resultLength
, *status
);
620 U_CAPI
void U_EXPORT2
621 unum_setTextAttribute( UNumberFormat
* fmt
,
622 UNumberFormatTextAttribute tag
,
623 const UChar
* newValue
,
624 int32_t newValueLength
,
627 if(U_FAILURE(*status
))
630 UnicodeString
val(newValue
, newValueLength
);
631 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
632 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
635 case UNUM_POSITIVE_PREFIX
:
636 df
->setPositivePrefix(val
);
639 case UNUM_POSITIVE_SUFFIX
:
640 df
->setPositiveSuffix(val
);
643 case UNUM_NEGATIVE_PREFIX
:
644 df
->setNegativePrefix(val
);
647 case UNUM_NEGATIVE_SUFFIX
:
648 df
->setNegativeSuffix(val
);
651 case UNUM_PADDING_CHARACTER
:
652 df
->setPadCharacter(val
);
655 case UNUM_CURRENCY_CODE
:
656 df
->setCurrency(val
.getTerminatedBuffer(), *status
);
660 *status
= U_UNSUPPORTED_ERROR
;
664 RuleBasedNumberFormat
* rbnf
= dynamic_cast<RuleBasedNumberFormat
*>(nf
);
665 U_ASSERT(rbnf
!= NULL
);
666 if (tag
== UNUM_DEFAULT_RULESET
) {
667 rbnf
->setDefaultRuleSet(val
, *status
);
669 *status
= U_UNSUPPORTED_ERROR
;
674 U_CAPI
int32_t U_EXPORT2
675 unum_toPattern( const UNumberFormat
* fmt
,
676 UBool isPatternLocalized
,
678 int32_t resultLength
,
681 if(U_FAILURE(*status
))
685 if(!(result
==NULL
&& resultLength
==0)) {
686 // NULL destination for pure preflighting: empty dummy string
687 // otherwise, alias the destination buffer
688 pat
.setTo(result
, 0, resultLength
);
691 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
692 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
694 if(isPatternLocalized
)
695 df
->toLocalizedPattern(pat
);
699 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
700 U_ASSERT(rbnf
!= NULL
);
701 pat
= rbnf
->getRules();
703 return pat
.extract(result
, resultLength
, *status
);
706 U_CAPI
int32_t U_EXPORT2
707 unum_getSymbol(const UNumberFormat
*fmt
,
708 UNumberFormatSymbol symbol
,
713 if(status
==NULL
|| U_FAILURE(*status
)) {
716 if(fmt
==NULL
|| symbol
< 0 || symbol
>=UNUM_FORMAT_SYMBOL_COUNT
) {
717 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
720 const NumberFormat
*nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
721 const DecimalFormat
*dcf
= dynamic_cast<const DecimalFormat
*>(nf
);
723 *status
= U_UNSUPPORTED_ERROR
;
728 getDecimalFormatSymbols()->
729 getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbol
).
730 extract(buffer
, size
, *status
);
733 U_CAPI
void U_EXPORT2
734 unum_setSymbol(UNumberFormat
*fmt
,
735 UNumberFormatSymbol symbol
,
740 if(status
==NULL
|| U_FAILURE(*status
)) {
743 if(fmt
==NULL
|| symbol
< 0 || symbol
>=UNUM_FORMAT_SYMBOL_COUNT
|| value
==NULL
|| length
<-1) {
744 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
747 NumberFormat
*nf
= reinterpret_cast<NumberFormat
*>(fmt
);
748 DecimalFormat
*dcf
= dynamic_cast<DecimalFormat
*>(nf
);
750 *status
= U_UNSUPPORTED_ERROR
;
754 DecimalFormatSymbols
symbols(*dcf
->getDecimalFormatSymbols());
755 symbols
.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbol
,
756 UnicodeString(value
, length
)); /* UnicodeString can handle the case when length = -1. */
757 dcf
->setDecimalFormatSymbols(symbols
);
760 U_CAPI
void U_EXPORT2
761 unum_applyPattern( UNumberFormat
*fmt
,
763 const UChar
*pattern
,
764 int32_t patternLength
,
765 UParseError
*parseError
,
768 UErrorCode tStatus
= U_ZERO_ERROR
;
769 UParseError tParseError
;
771 if(parseError
== NULL
){
772 parseError
= &tParseError
;
779 int32_t len
= (patternLength
== -1 ? u_strlen(pattern
) : patternLength
);
780 const UnicodeString
pat((UChar
*)pattern
, len
, len
);
782 // Verify if the object passed is a DecimalFormat object
783 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
784 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
787 df
->applyLocalizedPattern(pat
,*parseError
, *status
);
789 df
->applyPattern(pat
,*parseError
, *status
);
792 *status
= U_UNSUPPORTED_ERROR
;
797 U_CAPI
const char* U_EXPORT2
798 unum_getLocaleByType(const UNumberFormat
*fmt
,
799 ULocDataLocaleType type
,
803 if (U_SUCCESS(*status
)) {
804 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
808 return ((const Format
*)fmt
)->getLocaleID(type
, *status
);
811 U_CAPI
void U_EXPORT2
812 unum_setContext(UNumberFormat
* fmt
, UDisplayContext value
, UErrorCode
* status
)
814 if (U_FAILURE(*status
)) {
817 ((NumberFormat
*)fmt
)->setContext(value
, *status
);
821 U_CAPI UDisplayContext U_EXPORT2
822 unum_getContext(const UNumberFormat
*fmt
, UDisplayContextType type
, UErrorCode
* status
)
824 if (U_FAILURE(*status
)) {
825 return (UDisplayContext
)0;
827 return ((const NumberFormat
*)fmt
)->getContext(type
, *status
);
830 U_INTERNAL UFormattable
* U_EXPORT2
831 unum_parseToUFormattable(const UNumberFormat
* fmt
,
832 UFormattable
*result
,
835 int32_t* parsePos
, /* 0 = start */
836 UErrorCode
* status
) {
837 UFormattable
*newFormattable
= NULL
;
838 if (U_FAILURE(*status
)) return result
;
839 if (fmt
== NULL
|| (text
==NULL
&& textLength
!=0)) {
840 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
843 if (result
== NULL
) { // allocate if not allocated.
844 newFormattable
= result
= ufmt_open(status
);
846 parseRes(*(Formattable::fromUFormattable(result
)), fmt
, text
, textLength
, parsePos
, status
);
847 if (U_FAILURE(*status
) && newFormattable
!= NULL
) {
848 ufmt_close(newFormattable
);
849 result
= NULL
; // deallocate if there was a parse error
854 U_INTERNAL
int32_t U_EXPORT2
855 unum_formatUFormattable(const UNumberFormat
* fmt
,
856 const UFormattable
*number
,
858 int32_t resultLength
,
859 UFieldPosition
*pos
, /* ignored if 0 */
860 UErrorCode
*status
) {
861 if (U_FAILURE(*status
)) {
864 if (fmt
== NULL
|| number
==NULL
||
865 (result
==NULL
? resultLength
!=0 : resultLength
<0)) {
866 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
869 UnicodeString
res(result
, 0, resultLength
);
874 fp
.setField(pos
->field
);
876 ((const NumberFormat
*)fmt
)->format(*(Formattable::fromUFormattable(number
)), res
, fp
, *status
);
879 pos
->beginIndex
= fp
.getBeginIndex();
880 pos
->endIndex
= fp
.getEndIndex();
883 return res
.extract(result
, resultLength
, *status
);
886 #endif /* #if !UCONFIG_NO_FORMATTING */