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