1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
5 * Copyright (C) 1996-2015, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * Modification History:
10 * Date Name Description
11 * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes
12 *******************************************************************************
15 #include "unicode/utypes.h"
17 #if !UCONFIG_NO_FORMATTING
19 #include "unicode/unum.h"
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"
40 U_CAPI UNumberFormat
* U_EXPORT2
41 unum_open( UNumberFormatStyle style
,
43 int32_t patternLength
,
45 UParseError
* parseErr
,
47 if(U_FAILURE(*status
)) {
51 NumberFormat
*retVal
= NULL
;
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 retVal
= NumberFormat::createInstance(Locale(locale
), style
, *status
);
66 case UNUM_PATTERN_DECIMAL
: {
68 /* UnicodeString can handle the case when patternLength = -1. */
69 const UnicodeString
pat(pattern
, patternLength
);
75 DecimalFormatSymbols
*syms
= new DecimalFormatSymbols(Locale(locale
), *status
);
77 *status
= U_MEMORY_ALLOCATION_ERROR
;
80 if (U_FAILURE(*status
)) {
85 retVal
= new DecimalFormat(pat
, syms
, *parseErr
, *status
);
92 case UNUM_PATTERN_RULEBASED
: {
94 /* UnicodeString can handle the case when patternLength = -1. */
95 const UnicodeString
pat(pattern
, patternLength
);
101 retVal
= new RuleBasedNumberFormat(pat
, Locale(locale
), *parseErr
, *status
);
105 retVal
= new RuleBasedNumberFormat(URBNF_SPELLOUT
, Locale(locale
), *status
);
109 retVal
= new RuleBasedNumberFormat(URBNF_ORDINAL
, Locale(locale
), *status
);
113 retVal
= new RuleBasedNumberFormat(URBNF_DURATION
, Locale(locale
), *status
);
116 case UNUM_NUMBERING_SYSTEM
:
117 retVal
= new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM
, Locale(locale
), *status
);
121 case UNUM_DECIMAL_COMPACT_SHORT
:
122 retVal
= CompactDecimalFormat::createInstance(Locale(locale
), UNUM_SHORT
, *status
);
125 case UNUM_DECIMAL_COMPACT_LONG
:
126 retVal
= CompactDecimalFormat::createInstance(Locale(locale
), UNUM_LONG
, *status
);
130 *status
= U_UNSUPPORTED_ERROR
;
134 if(retVal
== NULL
&& U_SUCCESS(*status
)) {
135 *status
= U_MEMORY_ALLOCATION_ERROR
;
138 return reinterpret_cast<UNumberFormat
*>(retVal
);
141 U_CAPI
void U_EXPORT2
142 unum_close(UNumberFormat
* fmt
)
144 delete (NumberFormat
*) fmt
;
147 U_CAPI UNumberFormat
* U_EXPORT2
148 unum_clone(const UNumberFormat
*fmt
,
151 if(U_FAILURE(*status
))
155 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
156 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
160 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
161 U_ASSERT(rbnf
!= NULL
);
166 *status
= U_MEMORY_ALLOCATION_ERROR
;
170 return (UNumberFormat
*) res
;
173 U_CAPI
int32_t U_EXPORT2
174 unum_format( const UNumberFormat
* fmt
,
177 int32_t resultLength
,
181 return unum_formatInt64(fmt
, number
, result
, resultLength
, pos
, status
);
184 U_CAPI
int32_t U_EXPORT2
185 unum_formatInt64(const UNumberFormat
* fmt
,
188 int32_t resultLength
,
192 if(U_FAILURE(*status
))
196 if(!(result
==NULL
&& resultLength
==0)) {
197 // NULL destination for pure preflighting: empty dummy string
198 // otherwise, alias the destination buffer
199 res
.setTo(result
, 0, resultLength
);
205 fp
.setField(pos
->field
);
207 const CompactDecimalFormat
* cdf
= dynamic_cast<const CompactDecimalFormat
*>((const NumberFormat
*)fmt
);
209 cdf
->format(number
, res
, fp
); // CompactDecimalFormat does not override the version with UErrorCode& !!
211 ((const NumberFormat
*)fmt
)->format(number
, res
, fp
, *status
);
215 pos
->beginIndex
= fp
.getBeginIndex();
216 pos
->endIndex
= fp
.getEndIndex();
219 return res
.extract(result
, resultLength
, *status
);
222 U_CAPI
int32_t U_EXPORT2
223 unum_formatDouble( const UNumberFormat
* fmt
,
226 int32_t resultLength
,
227 UFieldPosition
*pos
, /* 0 if ignore */
231 if(U_FAILURE(*status
)) return -1;
234 if(!(result
==NULL
&& resultLength
==0)) {
235 // NULL destination for pure preflighting: empty dummy string
236 // otherwise, alias the destination buffer
237 res
.setTo(result
, 0, resultLength
);
243 fp
.setField(pos
->field
);
245 const CompactDecimalFormat
* cdf
= dynamic_cast<const CompactDecimalFormat
*>((const NumberFormat
*)fmt
);
247 cdf
->format(number
, res
, fp
); // CompactDecimalFormat does not override the version with UErrorCode& !!
249 ((const NumberFormat
*)fmt
)->format(number
, res
, fp
, *status
);
253 pos
->beginIndex
= fp
.getBeginIndex();
254 pos
->endIndex
= fp
.getEndIndex();
257 return res
.extract(result
, resultLength
, *status
);
260 U_CAPI
int32_t U_EXPORT2
261 unum_formatDoubleForFields(const UNumberFormat
* format
,
264 int32_t resultLength
,
265 UFieldPositionIterator
* fpositer
,
268 if (U_FAILURE(*status
))
271 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
272 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
277 if (result
!= NULL
) {
278 // NULL destination for pure preflighting: empty dummy string
279 // otherwise, alias the destination buffer
280 res
.setTo(result
, 0, resultLength
);
283 ((const NumberFormat
*)format
)->format(number
, res
, (FieldPositionIterator
*)fpositer
, *status
);
285 return res
.extract(result
, resultLength
, *status
);
288 U_CAPI
int32_t U_EXPORT2
289 unum_formatDecimal(const UNumberFormat
* fmt
,
293 int32_t resultLength
,
294 UFieldPosition
*pos
, /* 0 if ignore */
295 UErrorCode
* status
) {
297 if(U_FAILURE(*status
)) {
300 if ((result
== NULL
&& resultLength
!= 0) || resultLength
< 0) {
301 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
307 fp
.setField(pos
->field
);
311 length
= static_cast<int32_t>(uprv_strlen(number
));
313 StringPiece
numSP(number
, length
);
314 Formattable
numFmtbl(numSP
, *status
);
316 UnicodeString resultStr
;
317 if (resultLength
> 0) {
318 // Alias the destination buffer.
319 resultStr
.setTo(result
, 0, resultLength
);
321 ((const NumberFormat
*)fmt
)->format(numFmtbl
, resultStr
, fp
, *status
);
323 pos
->beginIndex
= fp
.getBeginIndex();
324 pos
->endIndex
= fp
.getEndIndex();
326 return resultStr
.extract(result
, resultLength
, *status
);
332 U_CAPI
int32_t U_EXPORT2
333 unum_formatDoubleCurrency(const UNumberFormat
* fmt
,
337 int32_t resultLength
,
338 UFieldPosition
* pos
, /* ignored if 0 */
339 UErrorCode
* status
) {
340 if (U_FAILURE(*status
)) return -1;
343 if (!(result
==NULL
&& resultLength
==0)) {
344 // NULL destination for pure preflighting: empty dummy string
345 // otherwise, alias the destination buffer
346 res
.setTo(result
, 0, resultLength
);
351 fp
.setField(pos
->field
);
353 CurrencyAmount
*tempCurrAmnt
= new CurrencyAmount(number
, currency
, *status
);
354 // Check for null pointer.
355 if (tempCurrAmnt
== NULL
) {
356 *status
= U_MEMORY_ALLOCATION_ERROR
;
359 Formattable
n(tempCurrAmnt
);
360 ((const NumberFormat
*)fmt
)->format(n
, res
, fp
, *status
);
363 pos
->beginIndex
= fp
.getBeginIndex();
364 pos
->endIndex
= fp
.getEndIndex();
367 return res
.extract(result
, resultLength
, *status
);
371 parseRes(Formattable
& res
,
372 const UNumberFormat
* fmt
,
375 int32_t *parsePos
/* 0 = start */,
378 if(U_FAILURE(*status
))
381 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
385 pp
.setIndex(*parsePos
);
387 ((const NumberFormat
*)fmt
)->parse(src
, res
, pp
);
389 if(pp
.getErrorIndex() != -1) {
390 *status
= U_PARSE_ERROR
;
392 *parsePos
= pp
.getErrorIndex();
394 } else if(parsePos
!= 0) {
395 *parsePos
= pp
.getIndex();
399 U_CAPI
int32_t U_EXPORT2
400 unum_parse( const UNumberFormat
* fmt
,
403 int32_t *parsePos
/* 0 = start */,
407 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
408 return res
.getLong(*status
);
411 U_CAPI
int64_t U_EXPORT2
412 unum_parseInt64( const UNumberFormat
* fmt
,
415 int32_t *parsePos
/* 0 = start */,
419 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
420 return res
.getInt64(*status
);
423 U_CAPI
double U_EXPORT2
424 unum_parseDouble( const UNumberFormat
* fmt
,
427 int32_t *parsePos
/* 0 = start */,
431 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
432 return res
.getDouble(*status
);
435 U_CAPI
int32_t U_EXPORT2
436 unum_parseDecimal(const UNumberFormat
* fmt
,
439 int32_t *parsePos
/* 0 = start */,
441 int32_t outBufLength
,
444 if (U_FAILURE(*status
)) {
447 if ((outBuf
== NULL
&& outBufLength
!= 0) || outBufLength
< 0) {
448 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
452 parseRes(res
, fmt
, text
, textLength
, parsePos
, status
);
453 StringPiece sp
= res
.getDecimalNumber(*status
);
454 if (U_FAILURE(*status
)) {
456 } else if (sp
.size() > outBufLength
) {
457 *status
= U_BUFFER_OVERFLOW_ERROR
;
458 } else if (sp
.size() == outBufLength
) {
459 uprv_strncpy(outBuf
, sp
.data(), sp
.size());
460 *status
= U_STRING_NOT_TERMINATED_WARNING
;
462 U_ASSERT(outBufLength
> 0);
463 uprv_strcpy(outBuf
, sp
.data());
468 U_CAPI
double U_EXPORT2
469 unum_parseDoubleCurrency(const UNumberFormat
* fmt
,
472 int32_t* parsePos
, /* 0 = start */
474 UErrorCode
* status
) {
475 double doubleVal
= 0.0;
477 if (U_FAILURE(*status
)) {
480 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
482 if (parsePos
!= NULL
) {
483 pp
.setIndex(*parsePos
);
485 *status
= U_PARSE_ERROR
; // assume failure, reset if succeed
486 LocalPointer
<CurrencyAmount
> currAmt(((const NumberFormat
*)fmt
)->parseCurrency(src
, pp
));
487 if (pp
.getErrorIndex() != -1) {
488 if (parsePos
!= NULL
) {
489 *parsePos
= pp
.getErrorIndex();
492 if (parsePos
!= NULL
) {
493 *parsePos
= pp
.getIndex();
495 if (pp
.getIndex() > 0) {
496 *status
= U_ZERO_ERROR
;
497 u_strcpy(currency
, currAmt
->getISOCurrency());
498 doubleVal
= currAmt
->getNumber().getDouble(*status
);
504 U_CAPI
const char* U_EXPORT2
505 unum_getAvailable(int32_t index
)
507 return uloc_getAvailable(index
);
510 U_CAPI
int32_t U_EXPORT2
511 unum_countAvailable()
513 return uloc_countAvailable();
516 U_CAPI
int32_t U_EXPORT2
517 unum_getAttribute(const UNumberFormat
* fmt
,
518 UNumberFormatAttribute attr
)
520 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
521 if (attr
== UNUM_LENIENT_PARSE
) {
522 // Supported for all subclasses
523 return nf
->isLenient();
525 else if (attr
== UNUM_MAX_INTEGER_DIGITS
) {
526 return nf
->getMaximumIntegerDigits();
528 else if (attr
== UNUM_MIN_INTEGER_DIGITS
) {
529 return nf
->getMinimumIntegerDigits();
531 else if (attr
== UNUM_INTEGER_DIGITS
) {
532 // TODO: what should this return?
533 return nf
->getMinimumIntegerDigits();
535 else if (attr
== UNUM_MAX_FRACTION_DIGITS
) {
536 return nf
->getMaximumFractionDigits();
538 else if (attr
== UNUM_MIN_FRACTION_DIGITS
) {
539 return nf
->getMinimumFractionDigits();
541 else if (attr
== UNUM_FRACTION_DIGITS
) {
542 // TODO: what should this return?
543 return nf
->getMinimumFractionDigits();
545 else if (attr
== UNUM_ROUNDING_MODE
) {
546 return nf
->getRoundingMode();
549 // The remaining attributes are only supported for DecimalFormat
550 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
552 UErrorCode ignoredStatus
= U_ZERO_ERROR
;
553 return df
->getAttribute(attr
, ignoredStatus
);
559 U_CAPI
void U_EXPORT2
560 unum_setAttribute( UNumberFormat
* fmt
,
561 UNumberFormatAttribute attr
,
564 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
565 if (attr
== UNUM_LENIENT_PARSE
) {
566 // Supported for all subclasses
567 // keep this here as the class may not be a DecimalFormat
568 return nf
->setLenient(newValue
!= 0);
570 else if (attr
== UNUM_MAX_INTEGER_DIGITS
) {
571 return nf
->setMaximumIntegerDigits(newValue
);
573 else if (attr
== UNUM_MIN_INTEGER_DIGITS
) {
574 return nf
->setMinimumIntegerDigits(newValue
);
576 else if (attr
== UNUM_INTEGER_DIGITS
) {
577 nf
->setMinimumIntegerDigits(newValue
);
578 return nf
->setMaximumIntegerDigits(newValue
);
580 else if (attr
== UNUM_MAX_FRACTION_DIGITS
) {
581 return nf
->setMaximumFractionDigits(newValue
);
583 else if (attr
== UNUM_MIN_FRACTION_DIGITS
) {
584 return nf
->setMinimumFractionDigits(newValue
);
586 else if (attr
== UNUM_FRACTION_DIGITS
) {
587 nf
->setMinimumFractionDigits(newValue
);
588 return nf
->setMaximumFractionDigits(newValue
);
590 else if (attr
== UNUM_ROUNDING_MODE
) {
591 return nf
->setRoundingMode((NumberFormat::ERoundingMode
)newValue
);
594 // The remaining attributes are only supported for DecimalFormat
595 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
597 UErrorCode ignoredStatus
= U_ZERO_ERROR
;
598 df
->setAttribute(attr
, newValue
, ignoredStatus
);
602 U_CAPI
double U_EXPORT2
603 unum_getDoubleAttribute(const UNumberFormat
* fmt
,
604 UNumberFormatAttribute attr
)
606 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
607 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
608 if (df
!= NULL
&& attr
== UNUM_ROUNDING_INCREMENT
) {
609 return df
->getRoundingIncrement();
615 U_CAPI
void U_EXPORT2
616 unum_setDoubleAttribute( UNumberFormat
* fmt
,
617 UNumberFormatAttribute attr
,
620 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
621 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
622 if (df
!= NULL
&& attr
== UNUM_ROUNDING_INCREMENT
) {
623 df
->setRoundingIncrement(newValue
);
627 U_CAPI
int32_t U_EXPORT2
628 unum_getTextAttribute(const UNumberFormat
* fmt
,
629 UNumberFormatTextAttribute tag
,
631 int32_t resultLength
,
634 if(U_FAILURE(*status
))
638 if(!(result
==NULL
&& resultLength
==0)) {
639 // NULL destination for pure preflighting: empty dummy string
640 // otherwise, alias the destination buffer
641 res
.setTo(result
, 0, resultLength
);
644 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
645 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
648 case UNUM_POSITIVE_PREFIX
:
649 df
->getPositivePrefix(res
);
652 case UNUM_POSITIVE_SUFFIX
:
653 df
->getPositiveSuffix(res
);
656 case UNUM_NEGATIVE_PREFIX
:
657 df
->getNegativePrefix(res
);
660 case UNUM_NEGATIVE_SUFFIX
:
661 df
->getNegativeSuffix(res
);
664 case UNUM_PADDING_CHARACTER
:
665 res
= df
->getPadCharacterString();
668 case UNUM_CURRENCY_CODE
:
669 res
= UnicodeString(df
->getCurrency());
673 *status
= U_UNSUPPORTED_ERROR
;
677 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
678 U_ASSERT(rbnf
!= NULL
);
679 if (tag
== UNUM_DEFAULT_RULESET
) {
680 res
= rbnf
->getDefaultRuleSetName();
681 } else if (tag
== UNUM_PUBLIC_RULESETS
) {
682 int32_t count
= rbnf
->getNumberOfRuleSetNames();
683 for (int i
= 0; i
< count
; ++i
) {
684 res
+= rbnf
->getRuleSetName(i
);
685 res
+= (UChar
)0x003b; // semicolon
688 *status
= U_UNSUPPORTED_ERROR
;
693 return res
.extract(result
, resultLength
, *status
);
696 U_CAPI
void U_EXPORT2
697 unum_setTextAttribute( UNumberFormat
* fmt
,
698 UNumberFormatTextAttribute tag
,
699 const UChar
* newValue
,
700 int32_t newValueLength
,
703 if(U_FAILURE(*status
))
706 UnicodeString
val(newValue
, newValueLength
);
707 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
708 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
711 case UNUM_POSITIVE_PREFIX
:
712 df
->setPositivePrefix(val
);
715 case UNUM_POSITIVE_SUFFIX
:
716 df
->setPositiveSuffix(val
);
719 case UNUM_NEGATIVE_PREFIX
:
720 df
->setNegativePrefix(val
);
723 case UNUM_NEGATIVE_SUFFIX
:
724 df
->setNegativeSuffix(val
);
727 case UNUM_PADDING_CHARACTER
:
728 df
->setPadCharacter(val
);
731 case UNUM_CURRENCY_CODE
:
732 df
->setCurrency(val
.getTerminatedBuffer(), *status
);
736 *status
= U_UNSUPPORTED_ERROR
;
740 RuleBasedNumberFormat
* rbnf
= dynamic_cast<RuleBasedNumberFormat
*>(nf
);
741 U_ASSERT(rbnf
!= NULL
);
742 if (tag
== UNUM_DEFAULT_RULESET
) {
743 rbnf
->setDefaultRuleSet(val
, *status
);
745 *status
= U_UNSUPPORTED_ERROR
;
750 U_CAPI
int32_t U_EXPORT2
751 unum_toPattern( const UNumberFormat
* fmt
,
752 UBool isPatternLocalized
,
754 int32_t resultLength
,
757 if(U_FAILURE(*status
))
761 if(!(result
==NULL
&& resultLength
==0)) {
762 // NULL destination for pure preflighting: empty dummy string
763 // otherwise, alias the destination buffer
764 pat
.setTo(result
, 0, resultLength
);
767 const NumberFormat
* nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
768 const DecimalFormat
* df
= dynamic_cast<const DecimalFormat
*>(nf
);
770 if(isPatternLocalized
)
771 df
->toLocalizedPattern(pat
);
775 const RuleBasedNumberFormat
* rbnf
= dynamic_cast<const RuleBasedNumberFormat
*>(nf
);
776 U_ASSERT(rbnf
!= NULL
);
777 pat
= rbnf
->getRules();
779 return pat
.extract(result
, resultLength
, *status
);
782 U_CAPI
int32_t U_EXPORT2
783 unum_getSymbol(const UNumberFormat
*fmt
,
784 UNumberFormatSymbol symbol
,
789 if(status
==NULL
|| U_FAILURE(*status
)) {
792 if(fmt
==NULL
|| symbol
< 0 || symbol
>=UNUM_FORMAT_SYMBOL_COUNT
) {
793 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
796 const NumberFormat
*nf
= reinterpret_cast<const NumberFormat
*>(fmt
);
797 const DecimalFormat
*dcf
= dynamic_cast<const DecimalFormat
*>(nf
);
799 *status
= U_UNSUPPORTED_ERROR
;
804 getDecimalFormatSymbols()->
805 getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbol
).
806 extract(buffer
, size
, *status
);
809 U_CAPI
void U_EXPORT2
810 unum_setSymbol(UNumberFormat
*fmt
,
811 UNumberFormatSymbol symbol
,
816 if(status
==NULL
|| U_FAILURE(*status
)) {
819 if(fmt
==NULL
|| symbol
< 0 || symbol
>=UNUM_FORMAT_SYMBOL_COUNT
|| value
==NULL
|| length
<-1) {
820 *status
=U_ILLEGAL_ARGUMENT_ERROR
;
823 NumberFormat
*nf
= reinterpret_cast<NumberFormat
*>(fmt
);
824 DecimalFormat
*dcf
= dynamic_cast<DecimalFormat
*>(nf
);
826 *status
= U_UNSUPPORTED_ERROR
;
830 DecimalFormatSymbols
symbols(*dcf
->getDecimalFormatSymbols());
831 symbols
.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol
)symbol
,
832 UnicodeString(value
, length
)); /* UnicodeString can handle the case when length = -1. */
833 dcf
->setDecimalFormatSymbols(symbols
);
836 U_CAPI
void U_EXPORT2
837 unum_applyPattern( UNumberFormat
*fmt
,
839 const UChar
*pattern
,
840 int32_t patternLength
,
841 UParseError
*parseError
,
844 UErrorCode tStatus
= U_ZERO_ERROR
;
845 UParseError tParseError
;
847 if(parseError
== NULL
){
848 parseError
= &tParseError
;
855 int32_t len
= (patternLength
== -1 ? u_strlen(pattern
) : patternLength
);
856 const UnicodeString
pat((UChar
*)pattern
, len
, len
);
858 // Verify if the object passed is a DecimalFormat object
859 NumberFormat
* nf
= reinterpret_cast<NumberFormat
*>(fmt
);
860 DecimalFormat
* df
= dynamic_cast<DecimalFormat
*>(nf
);
863 df
->applyLocalizedPattern(pat
,*parseError
, *status
);
865 df
->applyPattern(pat
,*parseError
, *status
);
868 *status
= U_UNSUPPORTED_ERROR
;
873 U_CAPI
const char* U_EXPORT2
874 unum_getLocaleByType(const UNumberFormat
*fmt
,
875 ULocDataLocaleType type
,
879 if (U_SUCCESS(*status
)) {
880 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
884 return ((const Format
*)fmt
)->getLocaleID(type
, *status
);
887 U_CAPI
void U_EXPORT2
888 unum_setContext(UNumberFormat
* fmt
, UDisplayContext value
, UErrorCode
* status
)
890 if (U_FAILURE(*status
)) {
893 ((NumberFormat
*)fmt
)->setContext(value
, *status
);
897 U_CAPI UDisplayContext U_EXPORT2
898 unum_getContext(const UNumberFormat
*fmt
, UDisplayContextType type
, UErrorCode
* status
)
900 if (U_FAILURE(*status
)) {
901 return (UDisplayContext
)0;
903 return ((const NumberFormat
*)fmt
)->getContext(type
, *status
);
906 U_INTERNAL UFormattable
* U_EXPORT2
907 unum_parseToUFormattable(const UNumberFormat
* fmt
,
908 UFormattable
*result
,
911 int32_t* parsePos
, /* 0 = start */
912 UErrorCode
* status
) {
913 UFormattable
*newFormattable
= NULL
;
914 if (U_FAILURE(*status
)) return result
;
915 if (fmt
== NULL
|| (text
==NULL
&& textLength
!=0)) {
916 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
919 if (result
== NULL
) { // allocate if not allocated.
920 newFormattable
= result
= ufmt_open(status
);
922 parseRes(*(Formattable::fromUFormattable(result
)), fmt
, text
, textLength
, parsePos
, status
);
923 if (U_FAILURE(*status
) && newFormattable
!= NULL
) {
924 ufmt_close(newFormattable
);
925 result
= NULL
; // deallocate if there was a parse error
930 U_INTERNAL
int32_t U_EXPORT2
931 unum_formatUFormattable(const UNumberFormat
* fmt
,
932 const UFormattable
*number
,
934 int32_t resultLength
,
935 UFieldPosition
*pos
, /* ignored if 0 */
936 UErrorCode
*status
) {
937 if (U_FAILURE(*status
)) {
940 if (fmt
== NULL
|| number
==NULL
||
941 (result
==NULL
? resultLength
!=0 : resultLength
<0)) {
942 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
945 UnicodeString
res(result
, 0, resultLength
);
950 fp
.setField(pos
->field
);
952 ((const NumberFormat
*)fmt
)->format(*(Formattable::fromUFormattable(number
)), res
, fp
, *status
);
955 pos
->beginIndex
= fp
.getBeginIndex();
956 pos
->endIndex
= fp
.getEndIndex();
959 return res
.extract(result
, resultLength
, *status
);
962 #endif /* #if !UCONFIG_NO_FORMATTING */