1 /* 2 ******************************************************************************* 3 * Copyright (C) 1996-2012, 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 */ 12 13 #include "unicode/utypes.h" 14 15 #if !UCONFIG_NO_FORMATTING 16 17 #include "unicode/unum.h" 18 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" 31 32 33 U_NAMESPACE_USE 34 35 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 } 46 47 NumberFormat *retVal = NULL; 48 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; 56 57 case UNUM_PATTERN_DECIMAL: { 58 UParseError tErr; 59 /* UnicodeString can handle the case when patternLength = -1. */ 60 const UnicodeString pat(pattern, patternLength); 61 62 if(parseErr==NULL){ 63 parseErr = &tErr; 64 } 65 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 } 75 76 retVal = new DecimalFormat(pat, syms, *parseErr, *status); 77 if(retVal == NULL) { 78 delete syms; 79 } 80 } break; 81 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); 87 88 if(parseErr==NULL){ 89 parseErr = &tErr; 90 } 91 92 retVal = new RuleBasedNumberFormat(pat, Locale(locale), *parseErr, *status); 93 } break; 94 95 case UNUM_SPELLOUT: 96 retVal = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale(locale), *status); 97 break; 98 99 case UNUM_ORDINAL: 100 retVal = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale(locale), *status); 101 break; 102 103 case UNUM_DURATION: 104 retVal = new RuleBasedNumberFormat(URBNF_DURATION, Locale(locale), *status); 105 break; 106 107 case UNUM_NUMBERING_SYSTEM: 108 retVal = new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM, Locale(locale), *status); 109 break; 110 #endif 111 112 default: 113 *status = U_UNSUPPORTED_ERROR; 114 return NULL; 115 } 116 117 if(retVal == NULL && U_SUCCESS(*status)) { 118 *status = U_MEMORY_ALLOCATION_ERROR; 119 } 120 121 return reinterpret_cast<UNumberFormat *>(retVal); 122 } 123 124 U_CAPI void U_EXPORT2 125 unum_close(UNumberFormat* fmt) 126 { 127 delete (NumberFormat*) fmt; 128 } 129 130 U_CAPI UNumberFormat* U_EXPORT2 131 unum_clone(const UNumberFormat *fmt, 132 UErrorCode *status) 133 { 134 if(U_FAILURE(*status)) 135 return 0; 136 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 } 147 148 if(res == 0) { 149 *status = U_MEMORY_ALLOCATION_ERROR; 150 return 0; 151 } 152 153 return (UNumberFormat*) res; 154 } 155 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 } 166 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; 177 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 } 184 185 FieldPosition fp; 186 187 if(pos != 0) 188 fp.setField(pos->field); 189 190 ((const NumberFormat*)fmt)->format(number, res, fp, *status); 191 192 if(pos != 0) { 193 pos->beginIndex = fp.getBeginIndex(); 194 pos->endIndex = fp.getEndIndex(); 195 } 196 197 return res.extract(result, resultLength, *status); 198 } 199 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 { 208 209 if(U_FAILURE(*status)) return -1; 210 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 } 217 218 FieldPosition fp; 219 220 if(pos != 0) 221 fp.setField(pos->field); 222 223 ((const NumberFormat*)fmt)->format(number, res, fp, *status); 224 225 if(pos != 0) { 226 pos->beginIndex = fp.getBeginIndex(); 227 pos->endIndex = fp.getEndIndex(); 228 } 229 230 return res.extract(result, resultLength, *status); 231 } 232 233 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) { 242 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 } 250 251 FieldPosition fp; 252 if(pos != 0) { 253 fp.setField(pos->field); 254 } 255 256 if (length < 0) { 257 length = uprv_strlen(number); 258 } 259 StringPiece numSP(number, length); 260 Formattable numFmtbl(numSP, *status); 261 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 } 274 275 276 277 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; 287 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 } 294 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); 307 308 if (pos != 0) { 309 pos->beginIndex = fp.getBeginIndex(); 310 pos->endIndex = fp.getEndIndex(); 311 } 312 313 return res.extract(result, resultLength, *status); 314 } 315 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; 326 327 const UnicodeString src((UBool)(textLength == -1), text, textLength); 328 ParsePosition pp; 329 330 if(parsePos != 0) 331 pp.setIndex(*parsePos); 332 333 ((const NumberFormat*)fmt)->parse(src, res, pp); 334 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 } 344 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 } 356 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 } 368 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 } 380 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 } 413 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 } 449 450 U_CAPI const char* U_EXPORT2 451 unum_getAvailable(int32_t index) 452 { 453 return uloc_getAvailable(index); 454 } 455 456 U_CAPI int32_t U_EXPORT2 457 unum_countAvailable() 458 { 459 return uloc_countAvailable(); 460 } 461 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 } 471 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 } 478 479 return -1; 480 } 481 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 } 500 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 } 513 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 } 525 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; 535 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 } 542 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; 550 551 case UNUM_POSITIVE_SUFFIX: 552 df->getPositiveSuffix(res); 553 break; 554 555 case UNUM_NEGATIVE_PREFIX: 556 df->getNegativePrefix(res); 557 break; 558 559 case UNUM_NEGATIVE_SUFFIX: 560 df->getNegativeSuffix(res); 561 break; 562 563 case UNUM_PADDING_CHARACTER: 564 res = df->getPadCharacterString(); 565 break; 566 567 case UNUM_CURRENCY_CODE: 568 res = UnicodeString(df->getCurrency()); 569 break; 570 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 } 591 592 return res.extract(result, resultLength, *status); 593 } 594 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; 604 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; 613 614 case UNUM_POSITIVE_SUFFIX: 615 df->setPositiveSuffix(val); 616 break; 617 618 case UNUM_NEGATIVE_PREFIX: 619 df->setNegativePrefix(val); 620 break; 621 622 case UNUM_NEGATIVE_SUFFIX: 623 df->setNegativeSuffix(val); 624 break; 625 626 case UNUM_PADDING_CHARACTER: 627 df->setPadCharacter(val); 628 break; 629 630 case UNUM_CURRENCY_CODE: 631 df->setCurrency(val.getTerminatedBuffer(), *status); 632 break; 633 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 } 648 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; 658 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 } 665 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 } 680 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 } 701 702 return dcf-> 703 getDecimalFormatSymbols()-> 704 getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol). 705 extract(buffer, size, *status); 706 } 707 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 } 728 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 } 734 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; 745 746 if(parseError == NULL){ 747 parseError = &tParseError; 748 } 749 750 if(status==NULL){ 751 status = &tStatus; 752 } 753 754 int32_t len = (patternLength == -1 ? u_strlen(pattern) : patternLength); 755 const UnicodeString pat((UChar*)pattern, len, len); 756 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 } 771 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 } 785 786 #endif /* #if !UCONFIG_NO_FORMATTING */ 787