decimfmt.cpp revision b13da9df870a61b11249bf741347908dbea0edd8
1/* 2******************************************************************************* 3* Copyright (C) 1997-2007, International Business Machines Corporation and * 4* others. All Rights Reserved. * 5******************************************************************************* 6* 7* File DECIMFMT.CPP 8* 9* Modification History: 10* 11* Date Name Description 12* 02/19/97 aliu Converted from java. 13* 03/20/97 clhuang Implemented with new APIs. 14* 03/31/97 aliu Moved isLONG_MIN to DigitList, and fixed it. 15* 04/3/97 aliu Rewrote parsing and formatting completely, and 16* cleaned up and debugged. Actually works now. 17* Implemented NAN and INF handling, for both parsing 18* and formatting. Extensive testing & debugging. 19* 04/10/97 aliu Modified to compile on AIX. 20* 04/16/97 aliu Rewrote to use DigitList, which has been resurrected. 21* Changed DigitCount to int per code review. 22* 07/09/97 helena Made ParsePosition into a class. 23* 08/26/97 aliu Extensive changes to applyPattern; completely 24* rewritten from the Java. 25* 09/09/97 aliu Ported over support for exponential formats. 26* 07/20/98 stephen JDK 1.2 sync up. 27* Various instances of '0' replaced with 'NULL' 28* Check for grouping size in subFormat() 29* Brought subParse() in line with Java 1.2 30* Added method appendAffix() 31* 08/24/1998 srl Removed Mutex calls. This is not a thread safe class! 32* 02/22/99 stephen Removed character literals for EBCDIC safety 33* 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes 34* 06/28/99 stephen Fixed bugs in toPattern(). 35* 06/29/99 stephen Fixed operator= to copy fFormatWidth, fPad, 36* fPadPosition 37******************************************************************************** 38*/ 39 40#include "unicode/utypes.h" 41 42#if !UCONFIG_NO_FORMATTING 43 44#include "unicode/decimfmt.h" 45#include "unicode/choicfmt.h" 46#include "unicode/ucurr.h" 47#include "unicode/ustring.h" 48#include "unicode/dcfmtsym.h" 49#include "unicode/ures.h" 50#include "unicode/uchar.h" 51#include "unicode/curramt.h" 52#include "ucurrimp.h" 53#include "util.h" 54#include "digitlst.h" 55#include "cmemory.h" 56#include "cstring.h" 57#include "umutex.h" 58#include "uassert.h" 59#include "putilimp.h" 60 61U_NAMESPACE_BEGIN 62 63//#define FMT_DEBUG 64 65#ifdef FMT_DEBUG 66#include <stdio.h> 67static void debugout(UnicodeString s) { 68 char buf[2000]; 69 s.extract((int32_t) 0, s.length(), buf); 70 printf("%s", buf); 71} 72#define debug(x) printf("%s", x); 73#else 74#define debugout(x) 75#define debug(x) 76#endif 77 78// ***************************************************************************** 79// class DecimalFormat 80// ***************************************************************************** 81 82UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat) 83 84// Constants for characters used in programmatic (unlocalized) patterns. 85#define kPatternZeroDigit ((UChar)0x0030) /*'0'*/ 86#define kPatternSignificantDigit ((UChar)0x0040) /*'@'*/ 87#define kPatternGroupingSeparator ((UChar)0x002C) /*','*/ 88#define kPatternDecimalSeparator ((UChar)0x002E) /*'.'*/ 89#define kPatternPerMill ((UChar)0x2030) 90#define kPatternPercent ((UChar)0x0025) /*'%'*/ 91#define kPatternDigit ((UChar)0x0023) /*'#'*/ 92#define kPatternSeparator ((UChar)0x003B) /*';'*/ 93#define kPatternExponent ((UChar)0x0045) /*'E'*/ 94#define kPatternPlus ((UChar)0x002B) /*'+'*/ 95#define kPatternMinus ((UChar)0x002D) /*'-'*/ 96#define kPatternPadEscape ((UChar)0x002A) /*'*'*/ 97#define kQuote ((UChar)0x0027) /*'\''*/ 98/** 99 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It 100 * is used in patterns and substitued with either the currency symbol, 101 * or if it is doubled, with the international currency symbol. If the 102 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is 103 * replaced with the monetary decimal separator. 104 */ 105#define kCurrencySign ((UChar)0x00A4) 106#define kDefaultPad ((UChar)0x0020) /* */ 107 108const int32_t DecimalFormat::kDoubleIntegerDigits = 309; 109const int32_t DecimalFormat::kDoubleFractionDigits = 340; 110 111const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8; 112 113/** 114 * These are the tags we expect to see in normal resource bundle files associated 115 * with a locale. 116 */ 117const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; 118 119inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; } 120inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; } 121 122//------------------------------------------------------------------------------ 123// Constructs a DecimalFormat instance in the default locale. 124 125DecimalFormat::DecimalFormat(UErrorCode& status) 126: NumberFormat(), 127 fPosPrefixPattern(0), 128 fPosSuffixPattern(0), 129 fNegPrefixPattern(0), 130 fNegSuffixPattern(0), 131 fCurrencyChoice(0), 132 fMultiplier(0), 133 fGroupingSize(0), 134 fGroupingSize2(0), 135 fSymbols(0), 136 fUseSignificantDigits(FALSE), 137 fMinSignificantDigits(1), 138 fMaxSignificantDigits(6), 139 fMinExponentDigits(0), 140 fRoundingIncrement(0), 141 fPad(0), 142 fFormatWidth(0) 143{ 144 UParseError parseError; 145 construct(status, parseError); 146} 147 148//------------------------------------------------------------------------------ 149// Constructs a DecimalFormat instance with the specified number format 150// pattern in the default locale. 151 152DecimalFormat::DecimalFormat(const UnicodeString& pattern, 153 UErrorCode& status) 154: NumberFormat(), 155 fPosPrefixPattern(0), 156 fPosSuffixPattern(0), 157 fNegPrefixPattern(0), 158 fNegSuffixPattern(0), 159 fCurrencyChoice(0), 160 fMultiplier(0), 161 fGroupingSize(0), 162 fGroupingSize2(0), 163 fSymbols(0), 164 fUseSignificantDigits(FALSE), 165 fMinSignificantDigits(1), 166 fMaxSignificantDigits(6), 167 fMinExponentDigits(0), 168 fRoundingIncrement(0), 169 fPad(0), 170 fFormatWidth(0) 171{ 172 UParseError parseError; 173 construct(status, parseError, &pattern); 174} 175 176//------------------------------------------------------------------------------ 177// Constructs a DecimalFormat instance with the specified number format 178// pattern and the number format symbols in the default locale. The 179// created instance owns the symbols. 180 181DecimalFormat::DecimalFormat(const UnicodeString& pattern, 182 DecimalFormatSymbols* symbolsToAdopt, 183 UErrorCode& status) 184: NumberFormat(), 185 fPosPrefixPattern(0), 186 fPosSuffixPattern(0), 187 fNegPrefixPattern(0), 188 fNegSuffixPattern(0), 189 fCurrencyChoice(0), 190 fMultiplier(0), 191 fGroupingSize(0), 192 fGroupingSize2(0), 193 fSymbols(0), 194 fUseSignificantDigits(FALSE), 195 fMinSignificantDigits(1), 196 fMaxSignificantDigits(6), 197 fMinExponentDigits(0), 198 fRoundingIncrement(0), 199 fPad(0), 200 fFormatWidth(0) 201{ 202 UParseError parseError; 203 if (symbolsToAdopt == NULL) 204 status = U_ILLEGAL_ARGUMENT_ERROR; 205 construct(status, parseError, &pattern, symbolsToAdopt); 206} 207 208DecimalFormat::DecimalFormat( const UnicodeString& pattern, 209 DecimalFormatSymbols* symbolsToAdopt, 210 UParseError& parseErr, 211 UErrorCode& status) 212: NumberFormat(), 213 fPosPrefixPattern(0), 214 fPosSuffixPattern(0), 215 fNegPrefixPattern(0), 216 fNegSuffixPattern(0), 217 fCurrencyChoice(0), 218 fMultiplier(0), 219 fGroupingSize(0), 220 fGroupingSize2(0), 221 fSymbols(0), 222 fUseSignificantDigits(FALSE), 223 fMinSignificantDigits(1), 224 fMaxSignificantDigits(6), 225 fMinExponentDigits(0), 226 fRoundingIncrement(0), 227 fPad(0), 228 fFormatWidth(0) 229{ 230 if (symbolsToAdopt == NULL) 231 status = U_ILLEGAL_ARGUMENT_ERROR; 232 construct(status,parseErr, &pattern, symbolsToAdopt); 233} 234//------------------------------------------------------------------------------ 235// Constructs a DecimalFormat instance with the specified number format 236// pattern and the number format symbols in the default locale. The 237// created instance owns the clone of the symbols. 238 239DecimalFormat::DecimalFormat(const UnicodeString& pattern, 240 const DecimalFormatSymbols& symbols, 241 UErrorCode& status) 242: NumberFormat(), 243 fPosPrefixPattern(0), 244 fPosSuffixPattern(0), 245 fNegPrefixPattern(0), 246 fNegSuffixPattern(0), 247 fCurrencyChoice(0), 248 fMultiplier(0), 249 fGroupingSize(0), 250 fGroupingSize2(0), 251 fSymbols(0), 252 fUseSignificantDigits(FALSE), 253 fMinSignificantDigits(1), 254 fMaxSignificantDigits(6), 255 fMinExponentDigits(0), 256 fRoundingIncrement(0), 257 fPad(0), 258 fFormatWidth(0) 259{ 260 UParseError parseError; 261 construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols)); 262} 263 264//------------------------------------------------------------------------------ 265// Constructs a DecimalFormat instance with the specified number format 266// pattern and the number format symbols in the desired locale. The 267// created instance owns the symbols. 268 269void 270DecimalFormat::construct(UErrorCode& status, 271 UParseError& parseErr, 272 const UnicodeString* pattern, 273 DecimalFormatSymbols* symbolsToAdopt) 274{ 275 fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!! 276// fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!! 277 fRoundingIncrement = NULL; 278 fRoundingDouble = 0.0; 279 fRoundingMode = kRoundHalfEven; 280 fPad = kPatternPadEscape; 281 fPadPosition = kPadBeforePrefix; 282 if (U_FAILURE(status)) 283 return; 284 285 fPosPrefixPattern = fPosSuffixPattern = NULL; 286 fNegPrefixPattern = fNegSuffixPattern = NULL; 287 fMultiplier = 1; 288 fGroupingSize = 3; 289 fGroupingSize2 = 0; 290 fDecimalSeparatorAlwaysShown = FALSE; 291 fIsCurrencyFormat = FALSE; 292 fUseExponentialNotation = FALSE; 293 fMinExponentDigits = 0; 294 295 if (fSymbols == NULL) 296 { 297 fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status); 298 /* test for NULL */ 299 if (fSymbols == 0) { 300 status = U_MEMORY_ALLOCATION_ERROR; 301 return; 302 } 303 } 304 305 UnicodeString str; 306 // Uses the default locale's number format pattern if there isn't 307 // one specified. 308 if (pattern == NULL) 309 { 310 int32_t len = 0; 311 UResourceBundle *resource = ures_open(NULL, Locale::getDefault().getName(), &status); 312 313 resource = ures_getByKey(resource, fgNumberPatterns, resource, &status); 314 const UChar *resStr = ures_getStringByIndex(resource, (int32_t)0, &len, &status); 315 str.setTo(TRUE, resStr, len); 316 pattern = &str; 317 ures_close(resource); 318 } 319 320 if (U_FAILURE(status)) 321 { 322 return; 323 } 324 325 if (pattern->indexOf((UChar)kCurrencySign) >= 0) { 326 // If it looks like we are going to use a currency pattern 327 // then do the time consuming lookup. 328 setCurrencyForSymbols(); 329 } else { 330 setCurrency(NULL, status); 331 } 332 333 applyPattern(*pattern, FALSE /*not localized*/,parseErr, status); 334 335 // If it was a currency format, apply the appropriate rounding by 336 // resetting the currency. NOTE: this copies fCurrency on top of itself. 337 if (fIsCurrencyFormat) { 338 setCurrency(getCurrency(), status); 339 } 340} 341 342//------------------------------------------------------------------------------ 343 344DecimalFormat::~DecimalFormat() 345{ 346// delete fDigitList; 347 delete fPosPrefixPattern; 348 delete fPosSuffixPattern; 349 delete fNegPrefixPattern; 350 delete fNegSuffixPattern; 351 delete fCurrencyChoice; 352 delete fSymbols; 353 delete fRoundingIncrement; 354} 355 356//------------------------------------------------------------------------------ 357// copy constructor 358 359DecimalFormat::DecimalFormat(const DecimalFormat &source) 360: NumberFormat(source), 361// fDigitList(NULL), 362 fPosPrefixPattern(NULL), 363 fPosSuffixPattern(NULL), 364 fNegPrefixPattern(NULL), 365 fNegSuffixPattern(NULL), 366 fCurrencyChoice(NULL), 367 fSymbols(NULL), 368 fRoundingIncrement(NULL) 369{ 370 *this = source; 371} 372 373//------------------------------------------------------------------------------ 374// assignment operator 375// Note that fDigitList is not considered a significant part of the 376// DecimalFormat because it's used as a buffer to process the numbers. 377 378static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) { 379 if (source == NULL) { 380 delete *pdest; 381 *pdest = NULL; 382 } else if (*pdest == NULL) { 383 *pdest = new UnicodeString(*source); 384 } else { 385 **pdest = *source; 386 } 387} 388 389DecimalFormat& 390DecimalFormat::operator=(const DecimalFormat& rhs) 391{ 392 if(this != &rhs) { 393 NumberFormat::operator=(rhs); 394 fPositivePrefix = rhs.fPositivePrefix; 395 fPositiveSuffix = rhs.fPositiveSuffix; 396 fNegativePrefix = rhs.fNegativePrefix; 397 fNegativeSuffix = rhs.fNegativeSuffix; 398 _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern); 399 _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern); 400 _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern); 401 _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern); 402 if (rhs.fCurrencyChoice == 0) { 403 delete fCurrencyChoice; 404 fCurrencyChoice = 0; 405 } else { 406 fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone(); 407 } 408 if(rhs.fRoundingIncrement == NULL) { 409 delete fRoundingIncrement; 410 fRoundingIncrement = NULL; 411 } 412 else if(fRoundingIncrement == NULL) { 413 fRoundingIncrement = new DigitList(*rhs.fRoundingIncrement); 414 } 415 else { 416 *fRoundingIncrement = *rhs.fRoundingIncrement; 417 } 418 fRoundingDouble = rhs.fRoundingDouble; 419 fRoundingMode = rhs.fRoundingMode; 420 fMultiplier = rhs.fMultiplier; 421 fGroupingSize = rhs.fGroupingSize; 422 fGroupingSize2 = rhs.fGroupingSize2; 423 fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown; 424 if(fSymbols == NULL) { 425 fSymbols = new DecimalFormatSymbols(*rhs.fSymbols); 426 } else { 427 *fSymbols = *rhs.fSymbols; 428 } 429 fUseExponentialNotation = rhs.fUseExponentialNotation; 430 fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown; 431 /*Bertrand A. D. Update 98.03.17*/ 432 fIsCurrencyFormat = rhs.fIsCurrencyFormat; 433 /*end of Update*/ 434 fMinExponentDigits = rhs.fMinExponentDigits; 435 // if (fDigitList == NULL) 436 // fDigitList = new DigitList(); 437 438 /* sfb 990629 */ 439 fFormatWidth = rhs.fFormatWidth; 440 fPad = rhs.fPad; 441 fPadPosition = rhs.fPadPosition; 442 /* end sfb */ 443 fMinSignificantDigits = rhs.fMinSignificantDigits; 444 fMaxSignificantDigits = rhs.fMaxSignificantDigits; 445 fUseSignificantDigits = rhs.fUseSignificantDigits; 446 } 447 return *this; 448} 449 450//------------------------------------------------------------------------------ 451 452UBool 453DecimalFormat::operator==(const Format& that) const 454{ 455 if (this == &that) 456 return TRUE; 457 458 // NumberFormat::operator== guarantees this cast is safe 459 const DecimalFormat* other = (DecimalFormat*)&that; 460 461#ifdef FMT_DEBUG 462 // This code makes it easy to determine why two format objects that should 463 // be equal aren't. 464 UBool first = TRUE; 465 if (!NumberFormat::operator==(that)) { 466 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 467 debug("NumberFormat::!="); 468 } 469 if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null 470 fPositivePrefix == other->fPositivePrefix) 471 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && 472 *fPosPrefixPattern == *other->fPosPrefixPattern))) { 473 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 474 debug("Pos Prefix !="); 475 } 476 if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null 477 fPositiveSuffix == other->fPositiveSuffix) 478 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && 479 *fPosSuffixPattern == *other->fPosSuffixPattern))) { 480 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 481 debug("Pos Suffix !="); 482 } 483 if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null 484 fNegativePrefix == other->fNegativePrefix) 485 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && 486 *fNegPrefixPattern == *other->fNegPrefixPattern))) { 487 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 488 debug("Neg Prefix "); 489 if (fNegPrefixPattern == NULL) { 490 debug("NULL("); 491 debugout(fNegativePrefix); 492 debug(")"); 493 } else { 494 debugout(*fNegPrefixPattern); 495 } 496 debug(" != "); 497 if (other->fNegPrefixPattern == NULL) { 498 debug("NULL("); 499 debugout(other->fNegativePrefix); 500 debug(")"); 501 } else { 502 debugout(*other->fNegPrefixPattern); 503 } 504 } 505 if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null 506 fNegativeSuffix == other->fNegativeSuffix) 507 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && 508 *fNegSuffixPattern == *other->fNegSuffixPattern))) { 509 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 510 debug("Neg Suffix "); 511 if (fNegSuffixPattern == NULL) { 512 debug("NULL("); 513 debugout(fNegativeSuffix); 514 debug(")"); 515 } else { 516 debugout(*fNegSuffixPattern); 517 } 518 debug(" != "); 519 if (other->fNegSuffixPattern == NULL) { 520 debug("NULL("); 521 debugout(other->fNegativeSuffix); 522 debug(")"); 523 } else { 524 debugout(*other->fNegSuffixPattern); 525 } 526 } 527 if (!((fRoundingIncrement == other->fRoundingIncrement) // both null 528 || (fRoundingIncrement != NULL && 529 other->fRoundingIncrement != NULL && 530 *fRoundingIncrement == *other->fRoundingIncrement))) { 531 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 532 debug("Rounding Increment !="); 533 } 534 if (fMultiplier != other->fMultiplier) { 535 if (first) { printf("[ "); first = FALSE; } 536 printf("Multiplier %ld != %ld", fMultiplier, other->fMultiplier); 537 } 538 if (fGroupingSize != other->fGroupingSize) { 539 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 540 printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize); 541 } 542 if (fGroupingSize2 != other->fGroupingSize2) { 543 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 544 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2); 545 } 546 if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) { 547 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 548 printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown); 549 } 550 if (fUseExponentialNotation != other->fUseExponentialNotation) { 551 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 552 debug("Use Exp !="); 553 } 554 if (!(!fUseExponentialNotation || 555 fMinExponentDigits != other->fMinExponentDigits)) { 556 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 557 debug("Exp Digits !="); 558 } 559 if (*fSymbols != *(other->fSymbols)) { 560 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 561 debug("Symbols !="); 562 } 563 // TODO Add debug stuff for significant digits here 564 if (!first) { printf(" ]"); } 565#endif 566 567 return (NumberFormat::operator==(that) && 568 ((fPosPrefixPattern == other->fPosPrefixPattern && // both null 569 fPositivePrefix == other->fPositivePrefix) 570 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && 571 *fPosPrefixPattern == *other->fPosPrefixPattern)) && 572 ((fPosSuffixPattern == other->fPosSuffixPattern && // both null 573 fPositiveSuffix == other->fPositiveSuffix) 574 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && 575 *fPosSuffixPattern == *other->fPosSuffixPattern)) && 576 ((fNegPrefixPattern == other->fNegPrefixPattern && // both null 577 fNegativePrefix == other->fNegativePrefix) 578 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && 579 *fNegPrefixPattern == *other->fNegPrefixPattern)) && 580 ((fNegSuffixPattern == other->fNegSuffixPattern && // both null 581 fNegativeSuffix == other->fNegativeSuffix) 582 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && 583 *fNegSuffixPattern == *other->fNegSuffixPattern)) && 584 ((fRoundingIncrement == other->fRoundingIncrement) // both null 585 || (fRoundingIncrement != NULL && 586 other->fRoundingIncrement != NULL && 587 *fRoundingIncrement == *other->fRoundingIncrement)) && 588 fMultiplier == other->fMultiplier && 589 fGroupingSize == other->fGroupingSize && 590 fGroupingSize2 == other->fGroupingSize2 && 591 fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown && 592 fUseExponentialNotation == other->fUseExponentialNotation && 593 (!fUseExponentialNotation || 594 fMinExponentDigits == other->fMinExponentDigits) && 595 *fSymbols == *(other->fSymbols) && 596 fUseSignificantDigits == other->fUseSignificantDigits && 597 (!fUseSignificantDigits || 598 (fMinSignificantDigits == other->fMinSignificantDigits && 599 fMaxSignificantDigits == other->fMaxSignificantDigits))); 600} 601 602//------------------------------------------------------------------------------ 603 604Format* 605DecimalFormat::clone() const 606{ 607 return new DecimalFormat(*this); 608} 609 610//------------------------------------------------------------------------------ 611 612UnicodeString& 613DecimalFormat::format(int32_t number, 614 UnicodeString& appendTo, 615 FieldPosition& fieldPosition) const 616{ 617 return format((int64_t)number, appendTo, fieldPosition); 618} 619 620//------------------------------------------------------------------------------ 621 622UnicodeString& 623DecimalFormat::format(int64_t number, 624 UnicodeString& appendTo, 625 FieldPosition& fieldPosition) const 626{ 627 DigitList digits; 628 629 // Clears field positions. 630 fieldPosition.setBeginIndex(0); 631 fieldPosition.setEndIndex(0); 632 633 // If we are to do rounding, we need to move into the BigDecimal 634 // domain in order to do divide/multiply correctly. 635 // || 636 // In general, long values always represent real finite numbers, so 637 // we don't have to check for +/- Infinity or NaN. However, there 638 // is one case we have to be careful of: The multiplier can push 639 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We 640 // check for this before multiplying, and if it happens we use doubles 641 // instead, trading off accuracy for range. 642 if (fRoundingIncrement != NULL 643 || (fMultiplier != 0 && (number > (U_INT64_MAX / fMultiplier) 644 || number < (U_INT64_MIN / fMultiplier)))) 645 { 646 digits.set(((double)number) * fMultiplier, 647 precision(FALSE), 648 !fUseExponentialNotation && !areSignificantDigitsUsed()); 649 } 650 else 651 { 652 digits.set(number * fMultiplier, precision(TRUE)); 653 } 654 655 return subformat(appendTo, fieldPosition, digits, TRUE); 656} 657 658//------------------------------------------------------------------------------ 659 660UnicodeString& 661DecimalFormat::format( double number, 662 UnicodeString& appendTo, 663 FieldPosition& fieldPosition) const 664{ 665 // Clears field positions. 666 fieldPosition.setBeginIndex(0); 667 fieldPosition.setEndIndex(0); 668 669 // Special case for NaN, sets the begin and end index to be the 670 // the string length of localized name of NaN. 671 if (uprv_isNaN(number)) 672 { 673 if (fieldPosition.getField() == NumberFormat::kIntegerField) 674 fieldPosition.setBeginIndex(appendTo.length()); 675 676 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); 677 678 if (fieldPosition.getField() == NumberFormat::kIntegerField) 679 fieldPosition.setEndIndex(appendTo.length()); 680 681 addPadding(appendTo, fieldPosition, 0, 0); 682 return appendTo; 683 } 684 685 /* Detecting whether a double is negative is easy with the exception of 686 * the value -0.0. This is a double which has a zero mantissa (and 687 * exponent), but a negative sign bit. It is semantically distinct from 688 * a zero with a positive sign bit, and this distinction is important 689 * to certain kinds of computations. However, it's a little tricky to 690 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may 691 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) == 692 * -Infinity. Proper detection of -0.0 is needed to deal with the 693 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98. 694 */ 695 UBool isNegative = uprv_isNegative(number); 696 697 // Do this BEFORE checking to see if value is infinite! Sets the 698 // begin and end index to be length of the string composed of 699 // localized name of Infinite and the positive/negative localized 700 // signs. 701 702 number *= fMultiplier; 703 704 // Apply rounding after multiplier 705 if (fRoundingIncrement != NULL) { 706 if (isNegative) // For rounding in the correct direction 707 number = -number; 708 number = fRoundingDouble 709 * round(number / fRoundingDouble, fRoundingMode, isNegative); 710 if (isNegative) 711 number = -number; 712 } 713 714 // Special case for INFINITE, 715 if (uprv_isInfinite(number)) 716 { 717 int32_t prefixLen = appendAffix(appendTo, number, isNegative, TRUE); 718 719 if (fieldPosition.getField() == NumberFormat::kIntegerField) 720 fieldPosition.setBeginIndex(appendTo.length()); 721 722 appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); 723 724 if (fieldPosition.getField() == NumberFormat::kIntegerField) 725 fieldPosition.setEndIndex(appendTo.length()); 726 727 int32_t suffixLen = appendAffix(appendTo, number, isNegative, FALSE); 728 729 addPadding(appendTo, fieldPosition, prefixLen, suffixLen); 730 return appendTo; 731 } 732 733 DigitList digits; 734 735 // This detects negativity too. 736 if (fRoundingIncrement == NULL) { 737 // If we did not round in binary space, round in decimal space 738 digits.fRoundingMode = fRoundingMode; 739 } 740 digits.set(number, precision(FALSE), 741 !fUseExponentialNotation && !areSignificantDigitsUsed()); 742 743 return subformat(appendTo, fieldPosition, digits, FALSE); 744} 745 746/** 747 * Round a double value to the nearest integer according to the 748 * given mode. 749 * @param a the absolute value of the number to be rounded 750 * @param mode a BigDecimal rounding mode 751 * @param isNegative true if the number to be rounded is negative 752 * @return the absolute value of the rounded result 753 */ 754double DecimalFormat::round(double a, ERoundingMode mode, UBool isNegative) { 755 switch (mode) { 756 case kRoundCeiling: 757 return isNegative ? uprv_floor(a) : uprv_ceil(a); 758 case kRoundFloor: 759 return isNegative ? uprv_ceil(a) : uprv_floor(a); 760 case kRoundDown: 761 return uprv_floor(a); 762 case kRoundUp: 763 return uprv_ceil(a); 764 case kRoundHalfEven: 765 { 766 double f = uprv_floor(a); 767 if ((a - f) != 0.5) { 768 return uprv_floor(a + 0.5); 769 } 770 double g = f / 2.0; 771 return (g == uprv_floor(g)) ? f : (f + 1.0); 772 } 773 case kRoundHalfDown: 774 return ((a - uprv_floor(a)) <= 0.5) ? uprv_floor(a) : uprv_ceil(a); 775 case kRoundHalfUp: 776 return ((a - uprv_floor(a)) < 0.5) ? uprv_floor(a) : uprv_ceil(a); 777 } 778 return 1.0; 779} 780 781UnicodeString& 782DecimalFormat::format( const Formattable& obj, 783 UnicodeString& appendTo, 784 FieldPosition& fieldPosition, 785 UErrorCode& status) const 786{ 787 return NumberFormat::format(obj, appendTo, fieldPosition, status); 788} 789 790/** 791 * Return true if a grouping separator belongs at the given 792 * position, based on whether grouping is in use and the values of 793 * the primary and secondary grouping interval. 794 * @param pos the number of integer digits to the right of 795 * the current position. Zero indicates the position after the 796 * rightmost integer digit. 797 * @return true if a grouping character belongs at the current 798 * position. 799 */ 800UBool DecimalFormat::isGroupingPosition(int32_t pos) const { 801 UBool result = FALSE; 802 if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) { 803 if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) { 804 result = ((pos - fGroupingSize) % fGroupingSize2) == 0; 805 } else { 806 result = pos % fGroupingSize == 0; 807 } 808 } 809 return result; 810} 811 812//------------------------------------------------------------------------------ 813 814/** 815 * Complete the formatting of a finite number. On entry, the fDigitList must 816 * be filled in with the correct digits. 817 */ 818UnicodeString& 819DecimalFormat::subformat(UnicodeString& appendTo, 820 FieldPosition& fieldPosition, 821 DigitList& digits, 822 UBool isInteger) const 823{ 824 // Gets the localized zero Unicode character. 825 UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 826 int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero 827 const UnicodeString *grouping ; 828 if(fIsCurrencyFormat) { 829 grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol); 830 }else{ 831 grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol); 832 } 833 const UnicodeString *decimal; 834 if(fIsCurrencyFormat) { 835 decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); 836 } else { 837 decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 838 } 839 UBool useSigDig = areSignificantDigitsUsed(); 840 int32_t maxIntDig = getMaximumIntegerDigits(); 841 int32_t minIntDig = getMinimumIntegerDigits(); 842 843 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which 844 * format as zero. This allows sensible computations and preserves 845 * relations such as signum(1/x) = signum(x), where x is +Infinity or 846 * -Infinity. Prior to this fix, we always formatted zero values as if 847 * they were positive. Liu 7/6/98. 848 */ 849 if (digits.isZero()) 850 { 851 digits.fDecimalAt = digits.fCount = 0; // Normalize 852 } 853 854 // Appends the prefix. 855 double doubleValue = digits.getDouble(); 856 int32_t prefixLen = appendAffix(appendTo, doubleValue, !digits.fIsPositive, TRUE); 857 858 if (fUseExponentialNotation) 859 { 860 // Record field information for caller. 861 if (fieldPosition.getField() == NumberFormat::kIntegerField) 862 { 863 fieldPosition.setBeginIndex(appendTo.length()); 864 fieldPosition.setEndIndex(-1); 865 } 866 else if (fieldPosition.getField() == NumberFormat::kFractionField) 867 { 868 fieldPosition.setBeginIndex(-1); 869 } 870 871 int32_t minFracDig = 0; 872 if (useSigDig) { 873 maxIntDig = minIntDig = 1; 874 minFracDig = getMinimumSignificantDigits() - 1; 875 } else { 876 minFracDig = getMinimumFractionDigits(); 877 if (maxIntDig > kMaxScientificIntegerDigits) { 878 maxIntDig = 1; 879 if (maxIntDig < minIntDig) { 880 maxIntDig = minIntDig; 881 } 882 } 883 if (maxIntDig > minIntDig) { 884 minIntDig = 1; 885 } 886 } 887 888 // Minimum integer digits are handled in exponential format by 889 // adjusting the exponent. For example, 0.01234 with 3 minimum 890 // integer digits is "123.4E-4". 891 892 // Maximum integer digits are interpreted as indicating the 893 // repeating range. This is useful for engineering notation, in 894 // which the exponent is restricted to a multiple of 3. For 895 // example, 0.01234 with 3 maximum integer digits is "12.34e-3". 896 // If maximum integer digits are defined and are larger than 897 // minimum integer digits, then minimum integer digits are 898 // ignored. 899 int32_t exponent = digits.fDecimalAt; 900 if (maxIntDig > 1 && maxIntDig != minIntDig) { 901 // A exponent increment is defined; adjust to it. 902 exponent = (exponent > 0) ? (exponent - 1) / maxIntDig 903 : (exponent / maxIntDig) - 1; 904 exponent *= maxIntDig; 905 } else { 906 // No exponent increment is defined; use minimum integer digits. 907 // If none is specified, as in "#E0", generate 1 integer digit. 908 exponent -= (minIntDig > 0 || minFracDig > 0) 909 ? minIntDig : 1; 910 } 911 912 // We now output a minimum number of digits, and more if there 913 // are more digits, up to the maximum number of digits. We 914 // place the decimal point after the "integer" digits, which 915 // are the first (decimalAt - exponent) digits. 916 int32_t minimumDigits = minIntDig + minFracDig; 917 // The number of integer digits is handled specially if the number 918 // is zero, since then there may be no digits. 919 int32_t integerDigits = digits.isZero() ? minIntDig : 920 digits.fDecimalAt - exponent; 921 int32_t totalDigits = digits.fCount; 922 if (minimumDigits > totalDigits) 923 totalDigits = minimumDigits; 924 if (integerDigits > totalDigits) 925 totalDigits = integerDigits; 926 927 // totalDigits records total number of digits needs to be processed 928 int32_t i; 929 for (i=0; i<totalDigits; ++i) 930 { 931 if (i == integerDigits) 932 { 933 // Record field information for caller. 934 if (fieldPosition.getField() == NumberFormat::kIntegerField) 935 fieldPosition.setEndIndex(appendTo.length()); 936 937 appendTo += *decimal; 938 939 // Record field information for caller. 940 if (fieldPosition.getField() == NumberFormat::kFractionField) 941 fieldPosition.setBeginIndex(appendTo.length()); 942 } 943 // Restores the digit character or pads the buffer with zeros. 944 UChar32 c = (UChar32)((i < digits.fCount) ? 945 (digits.fDigits[i] + zeroDelta) : 946 zero); 947 appendTo += c; 948 } 949 950 // Record field information 951 if (fieldPosition.getField() == NumberFormat::kIntegerField) 952 { 953 if (fieldPosition.getEndIndex() < 0) 954 fieldPosition.setEndIndex(appendTo.length()); 955 } 956 else if (fieldPosition.getField() == NumberFormat::kFractionField) 957 { 958 if (fieldPosition.getBeginIndex() < 0) 959 fieldPosition.setBeginIndex(appendTo.length()); 960 fieldPosition.setEndIndex(appendTo.length()); 961 } 962 963 // The exponent is output using the pattern-specified minimum 964 // exponent digits. There is no maximum limit to the exponent 965 // digits, since truncating the exponent would appendTo in an 966 // unacceptable inaccuracy. 967 appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); 968 969 // For zero values, we force the exponent to zero. We 970 // must do this here, and not earlier, because the value 971 // is used to determine integer digit count above. 972 if (digits.isZero()) 973 exponent = 0; 974 975 if (exponent < 0) { 976 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 977 } else if (fExponentSignAlwaysShown) { 978 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 979 } 980 981 DigitList expDigits; 982 expDigits.set(exponent); 983 { 984 int expDig = fMinExponentDigits; 985 if (fUseExponentialNotation && expDig < 1) { 986 expDig = 1; 987 } 988 for (i=expDigits.fDecimalAt; i<expDig; ++i) 989 appendTo += (zero); 990 } 991 for (i=0; i<expDigits.fDecimalAt; ++i) 992 { 993 UChar32 c = (UChar32)((i < expDigits.fCount) ? 994 (expDigits.fDigits[i] + zeroDelta) : zero); 995 appendTo += c; 996 } 997 } 998 else // Not using exponential notation 999 { 1000 // Record field information for caller. 1001 if (fieldPosition.getField() == NumberFormat::kIntegerField) 1002 fieldPosition.setBeginIndex(appendTo.length()); 1003 1004 int32_t sigCount = 0; 1005 int32_t minSigDig = getMinimumSignificantDigits(); 1006 int32_t maxSigDig = getMaximumSignificantDigits(); 1007 if (!useSigDig) { 1008 minSigDig = 0; 1009 maxSigDig = INT32_MAX; 1010 } 1011 1012 // Output the integer portion. Here 'count' is the total 1013 // number of integer digits we will display, including both 1014 // leading zeros required to satisfy getMinimumIntegerDigits, 1015 // and actual digits present in the number. 1016 int32_t count = useSigDig ? 1017 _max(1, digits.fDecimalAt) : minIntDig; 1018 if (digits.fDecimalAt > 0 && count < digits.fDecimalAt) { 1019 count = digits.fDecimalAt; 1020 } 1021 1022 // Handle the case where getMaximumIntegerDigits() is smaller 1023 // than the real number of integer digits. If this is so, we 1024 // output the least significant max integer digits. For example, 1025 // the value 1997 printed with 2 max integer digits is just "97". 1026 1027 int32_t digitIndex = 0; // Index into digitList.fDigits[] 1028 if (count > maxIntDig && maxIntDig >= 0) { 1029 count = maxIntDig; 1030 digitIndex = digits.fDecimalAt - count; 1031 } 1032 1033 int32_t sizeBeforeIntegerPart = appendTo.length(); 1034 1035 int32_t i; 1036 for (i=count-1; i>=0; --i) 1037 { 1038 if (i < digits.fDecimalAt && digitIndex < digits.fCount && 1039 sigCount < maxSigDig) { 1040 // Output a real digit 1041 appendTo += ((UChar32)(digits.fDigits[digitIndex++] + zeroDelta)); 1042 ++sigCount; 1043 } 1044 else 1045 { 1046 // Output a zero (leading or trailing) 1047 appendTo += (zero); 1048 if (sigCount > 0) { 1049 ++sigCount; 1050 } 1051 } 1052 1053 // Output grouping separator if necessary. 1054 if (isGroupingPosition(i)) { 1055 appendTo.append(*grouping); 1056 } 1057 } 1058 1059 // Record field information for caller. 1060 if (fieldPosition.getField() == NumberFormat::kIntegerField) 1061 fieldPosition.setEndIndex(appendTo.length()); 1062 1063 // Determine whether or not there are any printable fractional 1064 // digits. If we've used up the digits we know there aren't. 1065 UBool fractionPresent = (!isInteger && digitIndex < digits.fCount) || 1066 (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0)); 1067 1068 // If there is no fraction present, and we haven't printed any 1069 // integer digits, then print a zero. Otherwise we won't print 1070 // _any_ digits, and we won't be able to parse this string. 1071 if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart) 1072 appendTo += (zero); 1073 1074 // Output the decimal separator if we always do so. 1075 if (fDecimalSeparatorAlwaysShown || fractionPresent) 1076 appendTo += *decimal; 1077 1078 // Record field information for caller. 1079 if (fieldPosition.getField() == NumberFormat::kFractionField) 1080 fieldPosition.setBeginIndex(appendTo.length()); 1081 1082 count = useSigDig ? INT32_MAX : getMaximumFractionDigits(); 1083 if (useSigDig && (sigCount == maxSigDig || 1084 (sigCount >= minSigDig && digitIndex == digits.fCount))) { 1085 count = 0; 1086 } 1087 1088 for (i=0; i < count; ++i) { 1089 // Here is where we escape from the loop. We escape 1090 // if we've output the maximum fraction digits 1091 // (specified in the for expression above). We also 1092 // stop when we've output the minimum digits and 1093 // either: we have an integer, so there is no 1094 // fractional stuff to display, or we're out of 1095 // significant digits. 1096 if (!useSigDig && i >= getMinimumFractionDigits() && 1097 (isInteger || digitIndex >= digits.fCount)) { 1098 break; 1099 } 1100 1101 // Output leading fractional zeros. These are zeros 1102 // that come after the decimal but before any 1103 // significant digits. These are only output if 1104 // abs(number being formatted) < 1.0. 1105 if (-1-i > (digits.fDecimalAt-1)) { 1106 appendTo += zero; 1107 continue; 1108 } 1109 1110 // Output a digit, if we have any precision left, or a 1111 // zero if we don't. We don't want to output noise digits. 1112 if (!isInteger && digitIndex < digits.fCount) { 1113 appendTo += ((UChar32)(digits.fDigits[digitIndex++] + zeroDelta)); 1114 } else { 1115 appendTo += zero; 1116 } 1117 1118 // If we reach the maximum number of significant 1119 // digits, or if we output all the real digits and 1120 // reach the minimum, then we are done. 1121 ++sigCount; 1122 if (useSigDig && 1123 (sigCount == maxSigDig || 1124 (digitIndex == digits.fCount && sigCount >= minSigDig))) { 1125 break; 1126 } 1127 } 1128 1129 // Record field information for caller. 1130 if (fieldPosition.getField() == NumberFormat::kFractionField) 1131 fieldPosition.setEndIndex(appendTo.length()); 1132 } 1133 1134 int32_t suffixLen = appendAffix(appendTo, doubleValue, !digits.fIsPositive, FALSE); 1135 1136 addPadding(appendTo, fieldPosition, prefixLen, suffixLen); 1137 return appendTo; 1138} 1139 1140/** 1141 * Inserts the character fPad as needed to expand result to fFormatWidth. 1142 * @param result the string to be padded 1143 */ 1144void DecimalFormat::addPadding(UnicodeString& appendTo, 1145 FieldPosition& fieldPosition, 1146 int32_t prefixLen, 1147 int32_t suffixLen) const 1148{ 1149 if (fFormatWidth > 0) { 1150 int32_t len = fFormatWidth - appendTo.length(); 1151 if (len > 0) { 1152 UnicodeString padding; 1153 for (int32_t i=0; i<len; ++i) { 1154 padding += fPad; 1155 } 1156 switch (fPadPosition) { 1157 case kPadAfterPrefix: 1158 appendTo.insert(prefixLen, padding); 1159 break; 1160 case kPadBeforePrefix: 1161 appendTo.insert(0, padding); 1162 break; 1163 case kPadBeforeSuffix: 1164 appendTo.insert(appendTo.length() - suffixLen, padding); 1165 break; 1166 case kPadAfterSuffix: 1167 appendTo += padding; 1168 break; 1169 } 1170 if (fPadPosition == kPadBeforePrefix || 1171 fPadPosition == kPadAfterPrefix) { 1172 fieldPosition.setBeginIndex(len + fieldPosition.getBeginIndex()); 1173 fieldPosition.setEndIndex(len + fieldPosition.getEndIndex()); 1174 } 1175 } 1176 } 1177} 1178 1179//------------------------------------------------------------------------------ 1180 1181void 1182DecimalFormat::parse(const UnicodeString& text, 1183 Formattable& result, 1184 UErrorCode& status) const 1185{ 1186 NumberFormat::parse(text, result, status); 1187} 1188 1189void 1190DecimalFormat::parse(const UnicodeString& text, 1191 Formattable& result, 1192 ParsePosition& parsePosition) const { 1193 parse(text, result, parsePosition, FALSE); 1194} 1195 1196Formattable& DecimalFormat::parseCurrency(const UnicodeString& text, 1197 Formattable& result, 1198 ParsePosition& pos) const { 1199 parse(text, result, pos, TRUE); 1200 return result; 1201} 1202 1203/** 1204 * Parses the given text as either a number or a currency amount. 1205 * @param text the string to parse 1206 * @param result output parameter for the result 1207 * @param parsePosition input-output position; on input, the 1208 * position within text to match; must have 0 <= pos.getIndex() < 1209 * text.length(); on output, the position after the last matched 1210 * character. If the parse fails, the position in unchanged upon 1211 * output. 1212 * @param parseCurrency if true, a currency amount is parsed; 1213 * otherwise a Number is parsed 1214 */ 1215void DecimalFormat::parse(const UnicodeString& text, 1216 Formattable& result, 1217 ParsePosition& parsePosition, 1218 UBool parseCurrency) const { 1219 int32_t backup; 1220 int32_t i = backup = parsePosition.getIndex(); 1221 1222 // Handle NaN as a special case: 1223 1224 // Skip padding characters, if around prefix 1225 if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix || 1226 fPadPosition == kPadAfterPrefix)) { 1227 i = skipPadding(text, i); 1228 } 1229 // If the text is composed of the representation of NaN, returns NaN.length 1230 const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol); 1231 int32_t nanLen = (text.compare(i, nan->length(), *nan) 1232 ? 0 : nan->length()); 1233 if (nanLen) { 1234 i += nanLen; 1235 if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix || 1236 fPadPosition == kPadAfterSuffix)) { 1237 i = skipPadding(text, i); 1238 } 1239 parsePosition.setIndex(i); 1240 result.setDouble(uprv_getNaN()); 1241 return; 1242 } 1243 1244 // NaN parse failed; start over 1245 i = backup; 1246 1247 // status is used to record whether a number is infinite. 1248 UBool status[fgStatusLength]; 1249 UChar curbuf[4]; 1250 UChar* currency = parseCurrency ? curbuf : NULL; 1251 DigitList digits; 1252 1253 if (!subparse(text, parsePosition, digits, status, currency)) { 1254 parsePosition.setIndex(backup); 1255 return; 1256 } 1257 1258 // Handle infinity 1259 if (status[fgStatusInfinite]) { 1260 double inf = uprv_getInfinity(); 1261 result.setDouble(digits.fIsPositive ? inf : -inf); 1262 } 1263 1264 else { 1265 // Do as much of the multiplier conversion as possible without 1266 // losing accuracy. 1267 int32_t mult = fMultiplier; // Don't modify this.multiplier 1268 while (mult % 10 == 0) { 1269 mult /= 10; 1270 --digits.fDecimalAt; 1271 } 1272 1273 // Handle integral values. We want to return the most 1274 // parsimonious type that will accommodate all of the result's 1275 // precision. We therefore only return a long if the result fits 1276 // entirely within a long (taking into account the multiplier) -- 1277 // otherwise we fall through and return a double. When more 1278 // numeric types are supported by Formattable (e.g., 64-bit 1279 // integers, bignums) we will extend this logic to include them. 1280 if (digits.fitsIntoLong(isParseIntegerOnly())) { 1281 int32_t n = digits.getLong(); 1282 if (n % mult == 0) { 1283 result.setLong(n / mult); 1284 } 1285 else { // else handle the remainder 1286 result.setDouble(((double)n) / mult); 1287 } 1288 } 1289 else if (digits.fitsIntoInt64(isParseIntegerOnly())) { 1290 int64_t n = digits.getInt64(); 1291 if (n % mult == 0) { 1292 result.setInt64(n / mult); 1293 } 1294 else { // else handle the remainder 1295 result.setDouble(((double)n) / mult); 1296 } 1297 } 1298 else { 1299 // Handle non-integral or very large values 1300 // Dividing by one is okay and not that costly. 1301 result.setDouble(digits.getDouble() / mult); 1302 } 1303 } 1304 1305 if (parseCurrency) { 1306 UErrorCode ec = U_ZERO_ERROR; 1307 Formattable n(result); 1308 result.adoptObject(new CurrencyAmount(n, curbuf, ec)); 1309 U_ASSERT(U_SUCCESS(ec)); // should always succeed 1310 } 1311} 1312 1313 1314/* 1315This is an old implimentation that was preparing for 64-bit numbers in ICU. 1316It is very slow, and 64-bit numbers are not ANSI-C compatible. This code 1317is here if we change our minds. 1318 1319^^^ what is this referring to? remove? ^^^ [alan] 1320*/ 1321 1322/** 1323 * Parse the given text into a number. The text is parsed beginning at 1324 * parsePosition, until an unparseable character is seen. 1325 * @param text the string to parse. 1326 * @param parsePosition The position at which to being parsing. Upon 1327 * return, the first unparsed character. 1328 * @param digits the DigitList to set to the parsed value. 1329 * @param status output param containing boolean status flags indicating 1330 * whether the value was infinite and whether it was positive. 1331 * @param currency return value for parsed currency, for generic 1332 * currency parsing mode, or NULL for normal parsing. In generic 1333 * currency parsing mode, any currency is parsed, not just the 1334 * currency that this formatter is set to. 1335 */ 1336UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePosition, 1337 DigitList& digits, UBool* status, 1338 UChar* currency) const 1339{ 1340 int32_t position = parsePosition.getIndex(); 1341 int32_t oldStart = position; 1342 1343 // Match padding before prefix 1344 if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) { 1345 position = skipPadding(text, position); 1346 } 1347 1348 // Match positive and negative prefixes; prefer longest match. 1349 int32_t posMatch = compareAffix(text, position, FALSE, TRUE, currency); 1350 int32_t negMatch = compareAffix(text, position, TRUE, TRUE, currency); 1351 if (posMatch >= 0 && negMatch >= 0) { 1352 if (posMatch > negMatch) { 1353 negMatch = -1; 1354 } else if (negMatch > posMatch) { 1355 posMatch = -1; 1356 } 1357 } 1358 if (posMatch >= 0) { 1359 position += posMatch; 1360 } else if (negMatch >= 0) { 1361 position += negMatch; 1362 } else { 1363 parsePosition.setErrorIndex(position); 1364 return FALSE; 1365 } 1366 1367 // Match padding before prefix 1368 if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) { 1369 position = skipPadding(text, position); 1370 } 1371 1372 // process digits or Inf, find decimal position 1373 const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); 1374 int32_t infLen = (text.compare(position, inf->length(), *inf) 1375 ? 0 : inf->length()); 1376 position += infLen; // infLen is non-zero when it does equal to infinity 1377 status[fgStatusInfinite] = (UBool)infLen; 1378 if (!infLen) 1379 { 1380 // We now have a string of digits, possibly with grouping symbols, 1381 // and decimal points. We want to process these into a DigitList. 1382 // We don't want to put a bunch of leading zeros into the DigitList 1383 // though, so we keep track of the location of the decimal point, 1384 // put only significant digits into the DigitList, and adjust the 1385 // exponent as needed. 1386 1387 digits.fDecimalAt = digits.fCount = 0; 1388 UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 1389 1390 const UnicodeString *decimal; 1391 if(fIsCurrencyFormat) { 1392 decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); 1393 } else { 1394 decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 1395 } 1396 const UnicodeString *grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol); 1397 UBool sawDecimal = FALSE; 1398 UBool sawDigit = FALSE; 1399 int32_t backup = -1; 1400 int32_t digit; 1401 int32_t textLength = text.length(); // One less pointer to follow 1402 int32_t groupingLen = grouping->length(); 1403 int32_t decimalLen = decimal->length(); 1404 1405 // We have to track digitCount ourselves, because digits.fCount will 1406 // pin when the maximum allowable digits is reached. 1407 int32_t digitCount = 0; 1408 1409 for (; position < textLength; ) 1410 { 1411 UChar32 ch = text.char32At(position); 1412 1413 /* We recognize all digit ranges, not only the Latin digit range 1414 * '0'..'9'. We do so by using the Character.digit() method, 1415 * which converts a valid Unicode digit to the range 0..9. 1416 * 1417 * The character 'ch' may be a digit. If so, place its value 1418 * from 0 to 9 in 'digit'. First try using the locale digit, 1419 * which may or MAY NOT be a standard Unicode digit range. If 1420 * this fails, try using the standard Unicode digit ranges by 1421 * calling Character.digit(). If this also fails, digit will 1422 * have a value outside the range 0..9. 1423 */ 1424 digit = ch - zero; 1425 if (digit < 0 || digit > 9) 1426 { 1427 digit = u_charDigitValue(ch); 1428 } 1429 1430 if (digit > 0 && digit <= 9) 1431 { 1432 // Cancel out backup setting (see grouping handler below) 1433 backup = -1; 1434 1435 sawDigit = TRUE; 1436 // output a regular non-zero digit. 1437 ++digitCount; 1438 digits.append((char)(digit + '0')); 1439 position += U16_LENGTH(ch); 1440 } 1441 else if (digit == 0) 1442 { 1443 // Cancel out backup setting (see grouping handler below) 1444 backup = -1; 1445 sawDigit = TRUE; 1446 1447 // Check for leading zeros 1448 if (digits.fCount != 0) 1449 { 1450 // output a regular zero digit. 1451 ++digitCount; 1452 digits.append((char)(digit + '0')); 1453 } 1454 else if (sawDecimal) 1455 { 1456 // If we have seen the decimal, but no significant digits yet, 1457 // then we account for leading zeros by decrementing the 1458 // digits.fDecimalAt into negative values. 1459 --digits.fDecimalAt; 1460 } 1461 // else ignore leading zeros in integer part of number. 1462 position += U16_LENGTH(ch); 1463 } 1464 else if (!text.compare(position, groupingLen, *grouping) && isGroupingUsed()) 1465 { 1466 // Ignore grouping characters, if we are using them, but require 1467 // that they be followed by a digit. Otherwise we backup and 1468 // reprocess them. 1469 backup = position; 1470 position += groupingLen; 1471 } 1472 else if (!text.compare(position, decimalLen, *decimal) && !isParseIntegerOnly() && !sawDecimal) 1473 { 1474 // If we're only parsing integers, or if we ALREADY saw the 1475 // decimal, then don't parse this one. 1476 1477 digits.fDecimalAt = digitCount; // Not digits.fCount! 1478 sawDecimal = TRUE; 1479 position += decimalLen; 1480 } 1481 else { 1482 const UnicodeString *tmp; 1483 tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); 1484 if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit 1485 { 1486 // Parse sign, if present 1487 int32_t pos = position + tmp->length(); 1488 DigitList exponentDigits; 1489 1490 if (pos < textLength) 1491 { 1492 tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 1493 if (!text.compare(pos, tmp->length(), *tmp)) 1494 { 1495 pos += tmp->length(); 1496 } 1497 else { 1498 tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 1499 if (!text.compare(pos, tmp->length(), *tmp)) 1500 { 1501 pos += tmp->length(); 1502 exponentDigits.fIsPositive = FALSE; 1503 } 1504 } 1505 } 1506 1507 while (pos < textLength) { 1508 ch = text[(int32_t)pos]; 1509 digit = ch - zero; 1510 1511 if (digit < 0 || digit > 9) { 1512 digit = u_charDigitValue(ch); 1513 } 1514 if (0 <= digit && digit <= 9) { 1515 ++pos; 1516 exponentDigits.append((char)(digit + '0')); 1517 } else { 1518 break; 1519 } 1520 } 1521 1522 if (exponentDigits.fCount > 0) { 1523 exponentDigits.fDecimalAt = exponentDigits.fCount; 1524 digits.fDecimalAt += exponentDigits.getLong(); 1525 position = pos; // Advance past the exponent 1526 } 1527 1528 break; // Whether we fail or succeed, we exit this loop 1529 } 1530 else { 1531 break; 1532 } 1533 } 1534 } 1535 1536 if (backup != -1) 1537 { 1538 position = backup; 1539 } 1540 1541 // If there was no decimal point we have an integer 1542 if (!sawDecimal) 1543 { 1544 digits.fDecimalAt += digitCount; // Not digits.fCount! 1545 } 1546 1547 // If none of the text string was recognized. For example, parse 1548 // "x" with pattern "#0.00" (return index and error index both 0) 1549 // parse "$" with pattern "$#0.00". (return index 0 and error index 1550 // 1). 1551 if (!sawDigit && digitCount == 0) { 1552 parsePosition.setIndex(oldStart); 1553 parsePosition.setErrorIndex(oldStart); 1554 return FALSE; 1555 } 1556 } 1557 1558 // Match padding before suffix 1559 if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) { 1560 position = skipPadding(text, position); 1561 } 1562 1563 // Match positive and negative suffixes; prefer longest match. 1564 if (posMatch >= 0) { 1565 posMatch = compareAffix(text, position, FALSE, FALSE, currency); 1566 } 1567 if (negMatch >= 0) { 1568 negMatch = compareAffix(text, position, TRUE, FALSE, currency); 1569 } 1570 if (posMatch >= 0 && negMatch >= 0) { 1571 if (posMatch > negMatch) { 1572 negMatch = -1; 1573 } else if (negMatch > posMatch) { 1574 posMatch = -1; 1575 } 1576 } 1577 1578 // Fail if neither or both 1579 if ((posMatch >= 0) == (negMatch >= 0)) { 1580 parsePosition.setErrorIndex(position); 1581 return FALSE; 1582 } 1583 1584 position += (posMatch>=0 ? posMatch : negMatch); 1585 1586 // Match padding before suffix 1587 if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) { 1588 position = skipPadding(text, position); 1589 } 1590 1591 parsePosition.setIndex(position); 1592 1593 digits.fIsPositive = (posMatch >= 0); 1594 1595 if(parsePosition.getIndex() == oldStart) 1596 { 1597 parsePosition.setErrorIndex(position); 1598 return FALSE; 1599 } 1600 return TRUE; 1601} 1602 1603/** 1604 * Starting at position, advance past a run of pad characters, if any. 1605 * Return the index of the first character after position that is not a pad 1606 * character. Result is >= position. 1607 */ 1608int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const { 1609 int32_t padLen = U16_LENGTH(fPad); 1610 while (position < text.length() && 1611 text.char32At(position) == fPad) { 1612 position += padLen; 1613 } 1614 return position; 1615} 1616 1617/** 1618 * Return the length matched by the given affix, or -1 if none. 1619 * Runs of white space in the affix, match runs of white space in 1620 * the input. Pattern white space and input white space are 1621 * determined differently; see code. 1622 * @param text input text 1623 * @param pos offset into input at which to begin matching 1624 * @param isNegative 1625 * @param isPrefix 1626 * @param currency return value for parsed currency, for generic 1627 * currency parsing mode, or null for normal parsing. In generic 1628 * currency parsing mode, any currency is parsed, not just the 1629 * currency that this formatter is set to. 1630 * @return length of input that matches, or -1 if match failure 1631 */ 1632int32_t DecimalFormat::compareAffix(const UnicodeString& text, 1633 int32_t pos, 1634 UBool isNegative, 1635 UBool isPrefix, 1636 UChar* currency) const 1637{ 1638 const UnicodeString *patternToCompare; 1639 if (fCurrencyChoice != NULL || currency != NULL) { 1640 if (isNegative) { 1641 if (isPrefix) { 1642 patternToCompare = fNegPrefixPattern; 1643 } 1644 else { 1645 patternToCompare = fNegSuffixPattern; 1646 } 1647 } 1648 else { 1649 if (isPrefix) { 1650 patternToCompare = fPosPrefixPattern; 1651 } 1652 else { 1653 patternToCompare = fPosSuffixPattern; 1654 } 1655 } 1656 if (patternToCompare != NULL) { 1657 return compareComplexAffix(*patternToCompare, text, pos, currency); 1658 } 1659 /* else the caller modified the pattern. Fallback to normal behavior. */ 1660 } 1661 1662 if (isNegative) { 1663 if (isPrefix) { 1664 patternToCompare = &fNegativePrefix; 1665 } 1666 else { 1667 patternToCompare = &fNegativeSuffix; 1668 } 1669 } 1670 else { 1671 if (isPrefix) { 1672 patternToCompare = &fPositivePrefix; 1673 } 1674 else { 1675 patternToCompare = &fPositiveSuffix; 1676 } 1677 } 1678 return compareSimpleAffix(*patternToCompare, text, pos); 1679} 1680 1681/** 1682 * Return the length matched by the given affix, or -1 if none. 1683 * Runs of white space in the affix, match runs of white space in 1684 * the input. Pattern white space and input white space are 1685 * determined differently; see code. 1686 * @param affix pattern string, taken as a literal 1687 * @param input input text 1688 * @param pos offset into input at which to begin matching 1689 * @return length of input that matches, or -1 if match failure 1690 */ 1691int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix, 1692 const UnicodeString& input, 1693 int32_t pos) { 1694 int32_t start = pos; 1695 for (int32_t i=0; i<affix.length(); ) { 1696 UChar32 c = affix.char32At(i); 1697 int32_t len = U16_LENGTH(c); 1698 if (uprv_isRuleWhiteSpace(c)) { 1699 // We may have a pattern like: \u200F \u0020 1700 // and input text like: \u200F \u0020 1701 // Note that U+200F and U+0020 are RuleWhiteSpace but only 1702 // U+0020 is UWhiteSpace. So we have to first do a direct 1703 // match of the run of RULE whitespace in the pattern, 1704 // then match any extra characters. 1705 UBool literalMatch = FALSE; 1706 while (pos < input.length() && 1707 input.char32At(pos) == c) { 1708 literalMatch = TRUE; 1709 i += len; 1710 pos += len; 1711 if (i == affix.length()) { 1712 break; 1713 } 1714 c = affix.char32At(i); 1715 len = U16_LENGTH(c); 1716 if (!uprv_isRuleWhiteSpace(c)) { 1717 break; 1718 } 1719 } 1720 1721 // Advance over run in pattern 1722 i = skipRuleWhiteSpace(affix, i); 1723 1724 // Advance over run in input text 1725 // Must see at least one white space char in input, 1726 // unless we've already matched some characters literally. 1727 int32_t s = pos; 1728 pos = skipUWhiteSpace(input, pos); 1729 if (pos == s && !literalMatch) { 1730 return -1; 1731 } 1732 } else { 1733 if (pos < input.length() && 1734 input.char32At(pos) == c) { 1735 i += len; 1736 pos += len; 1737 } else { 1738 return -1; 1739 } 1740 } 1741 } 1742 return pos - start; 1743} 1744 1745/** 1746 * Skip over a run of zero or more isRuleWhiteSpace() characters at 1747 * pos in text. 1748 */ 1749int32_t DecimalFormat::skipRuleWhiteSpace(const UnicodeString& text, int32_t pos) { 1750 while (pos < text.length()) { 1751 UChar32 c = text.char32At(pos); 1752 if (!uprv_isRuleWhiteSpace(c)) { 1753 break; 1754 } 1755 pos += U16_LENGTH(c); 1756 } 1757 return pos; 1758} 1759 1760/** 1761 * Skip over a run of zero or more isUWhiteSpace() characters at pos 1762 * in text. 1763 */ 1764int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) { 1765 while (pos < text.length()) { 1766 UChar32 c = text.char32At(pos); 1767 if (!u_isUWhiteSpace(c)) { 1768 break; 1769 } 1770 pos += U16_LENGTH(c); 1771 } 1772 return pos; 1773} 1774 1775/** 1776 * Return the length matched by the given affix, or -1 if none. 1777 * @param affixPat pattern string 1778 * @param input input text 1779 * @param pos offset into input at which to begin matching 1780 * @param currency return value for parsed currency, for generic 1781 * currency parsing mode, or null for normal parsing. In generic 1782 * currency parsing mode, any currency is parsed, not just the 1783 * currency that this formatter is set to. 1784 * @return length of input that matches, or -1 if match failure 1785 */ 1786int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat, 1787 const UnicodeString& text, 1788 int32_t pos, 1789 UChar* currency) const 1790{ 1791 int32_t start = pos; 1792 U_ASSERT(currency != NULL || 1793 (fCurrencyChoice != NULL && *getCurrency() != 0)); 1794 1795 for (int32_t i=0; i<affixPat.length() && pos >= 0; ) { 1796 UChar32 c = affixPat.char32At(i); 1797 i += U16_LENGTH(c); 1798 1799 if (c == kQuote) { 1800 U_ASSERT(i <= affixPat.length()); 1801 c = affixPat.char32At(i); 1802 i += U16_LENGTH(c); 1803 1804 const UnicodeString* affix = NULL; 1805 1806 switch (c) { 1807 case kCurrencySign: { 1808 // If currency != null, then perform generic currency matching. 1809 // Otherwise, do currency choice parsing. 1810 UBool intl = i<affixPat.length() && 1811 affixPat.char32At(i) == kCurrencySign; 1812 // Parse generic currency -- anything for which we 1813 // have a display name, or any 3-letter ISO code. 1814 if (currency != NULL) { 1815 // Try to parse display name for our locale; first 1816 // determine our locale. 1817 UErrorCode ec = U_ZERO_ERROR; 1818 const char* loc = getLocaleID(ULOC_VALID_LOCALE, ec); 1819 if (U_FAILURE(ec) || loc == NULL || *loc == 0) { 1820 // applyPattern has been called; use the symbols 1821 loc = fSymbols->getLocale().getName(); 1822 ec = U_ZERO_ERROR; 1823 } 1824 // Delegate parse of display name => ISO code to Currency 1825 ParsePosition ppos(pos); 1826 UChar curr[4]; 1827 uprv_parseCurrency(loc, text, ppos, curr, ec); 1828 1829 // If parse succeeds, populate currency[0] 1830 if (U_SUCCESS(ec) && ppos.getIndex() != pos) { 1831 u_strcpy(currency, curr); 1832 pos = ppos.getIndex(); 1833 } else { 1834 pos = -1; 1835 } 1836 } else { 1837 if (intl) { 1838 ++i; 1839 pos = match(text, pos, getCurrency()); 1840 } else { 1841 ParsePosition ppos(pos); 1842 Formattable result; 1843 fCurrencyChoice->parse(text, result, ppos); 1844 pos = (ppos.getIndex() == pos) ? -1 : ppos.getIndex(); 1845 } 1846 } 1847 continue; 1848 } 1849 case kPatternPercent: 1850 affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 1851 break; 1852 case kPatternPerMill: 1853 affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 1854 break; 1855 case kPatternPlus: 1856 affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 1857 break; 1858 case kPatternMinus: 1859 affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 1860 break; 1861 default: 1862 // fall through to affix!=0 test, which will fail 1863 break; 1864 } 1865 1866 if (affix != NULL) { 1867 pos = match(text, pos, *affix); 1868 continue; 1869 } 1870 } 1871 1872 pos = match(text, pos, c); 1873 if (uprv_isRuleWhiteSpace(c)) { 1874 i = skipRuleWhiteSpace(affixPat, i); 1875 } 1876 } 1877 return pos - start; 1878} 1879 1880/** 1881 * Match a single character at text[pos] and return the index of the 1882 * next character upon success. Return -1 on failure. If 1883 * isRuleWhiteSpace(ch) then match a run of white space in text. 1884 */ 1885int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) { 1886 if (uprv_isRuleWhiteSpace(ch)) { 1887 // Advance over run of white space in input text 1888 // Must see at least one white space char in input 1889 int32_t s = pos; 1890 pos = skipUWhiteSpace(text, pos); 1891 if (pos == s) { 1892 return -1; 1893 } 1894 return pos; 1895 } 1896 return (pos >= 0 && text.char32At(pos) == ch) ? 1897 (pos + U16_LENGTH(ch)) : -1; 1898} 1899 1900/** 1901 * Match a string at text[pos] and return the index of the next 1902 * character upon success. Return -1 on failure. Match a run of 1903 * white space in str with a run of white space in text. 1904 */ 1905int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) { 1906 for (int32_t i=0; i<str.length() && pos >= 0; ) { 1907 UChar32 ch = str.char32At(i); 1908 i += U16_LENGTH(ch); 1909 if (uprv_isRuleWhiteSpace(ch)) { 1910 i = skipRuleWhiteSpace(str, i); 1911 } 1912 pos = match(text, pos, ch); 1913 } 1914 return pos; 1915} 1916 1917//------------------------------------------------------------------------------ 1918// Gets the pointer to the localized decimal format symbols 1919 1920const DecimalFormatSymbols* 1921DecimalFormat::getDecimalFormatSymbols() const 1922{ 1923 return fSymbols; 1924} 1925 1926//------------------------------------------------------------------------------ 1927// De-owning the current localized symbols and adopt the new symbols. 1928 1929void 1930DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) 1931{ 1932 if (symbolsToAdopt == NULL) { 1933 return; // do not allow caller to set fSymbols to NULL 1934 } 1935 1936 UBool sameSymbols = FALSE; 1937 if (fSymbols != NULL) { 1938 sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == 1939 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) && 1940 getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == 1941 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 1942 delete fSymbols; 1943 } 1944 1945 fSymbols = symbolsToAdopt; 1946 if (!sameSymbols) { 1947 // If the currency symbols are the same, there is no need to recalculate. 1948 setCurrencyForSymbols(); 1949 } 1950 expandAffixes(); 1951} 1952//------------------------------------------------------------------------------ 1953// Setting the symbols is equlivalent to adopting a newly created localized 1954// symbols. 1955 1956void 1957DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) 1958{ 1959 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); 1960} 1961 1962/** 1963 * Update the currency object to match the symbols. This method 1964 * is used only when the caller has passed in a symbols object 1965 * that may not be the default object for its locale. 1966 */ 1967void 1968DecimalFormat::setCurrencyForSymbols() { 1969 /*Bug 4212072 1970 Update the affix strings accroding to symbols in order to keep 1971 the affix strings up to date. 1972 [Richard/GCL] 1973 */ 1974 1975 // With the introduction of the Currency object, the currency 1976 // symbols in the DFS object are ignored. For backward 1977 // compatibility, we check any explicitly set DFS object. If it 1978 // is a default symbols object for its locale, we change the 1979 // currency object to one for that locale. If it is custom, 1980 // we set the currency to null. 1981 UErrorCode ec = U_ZERO_ERROR; 1982 const UChar* c = NULL; 1983 const char* loc = fSymbols->getLocale().getName(); 1984 UChar intlCurrencySymbol[4]; 1985 ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec); 1986 UnicodeString currencySymbol; 1987 1988 uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec); 1989 if (U_SUCCESS(ec) 1990 && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol 1991 && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == intlCurrencySymbol) 1992 { 1993 // Trap an error in mapping locale to currency. If we can't 1994 // map, then don't fail and set the currency to "". 1995 c = intlCurrencySymbol; 1996 } 1997 ec = U_ZERO_ERROR; // reset local error code! 1998 setCurrency(c, ec); 1999} 2000 2001 2002//------------------------------------------------------------------------------ 2003// Gets the positive prefix of the number pattern. 2004 2005UnicodeString& 2006DecimalFormat::getPositivePrefix(UnicodeString& result) const 2007{ 2008 result = fPositivePrefix; 2009 return result; 2010} 2011 2012//------------------------------------------------------------------------------ 2013// Sets the positive prefix of the number pattern. 2014 2015void 2016DecimalFormat::setPositivePrefix(const UnicodeString& newValue) 2017{ 2018 fPositivePrefix = newValue; 2019 delete fPosPrefixPattern; 2020 fPosPrefixPattern = 0; 2021} 2022 2023//------------------------------------------------------------------------------ 2024// Gets the negative prefix of the number pattern. 2025 2026UnicodeString& 2027DecimalFormat::getNegativePrefix(UnicodeString& result) const 2028{ 2029 result = fNegativePrefix; 2030 return result; 2031} 2032 2033//------------------------------------------------------------------------------ 2034// Gets the negative prefix of the number pattern. 2035 2036void 2037DecimalFormat::setNegativePrefix(const UnicodeString& newValue) 2038{ 2039 fNegativePrefix = newValue; 2040 delete fNegPrefixPattern; 2041 fNegPrefixPattern = 0; 2042} 2043 2044//------------------------------------------------------------------------------ 2045// Gets the positive suffix of the number pattern. 2046 2047UnicodeString& 2048DecimalFormat::getPositiveSuffix(UnicodeString& result) const 2049{ 2050 result = fPositiveSuffix; 2051 return result; 2052} 2053 2054//------------------------------------------------------------------------------ 2055// Sets the positive suffix of the number pattern. 2056 2057void 2058DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) 2059{ 2060 fPositiveSuffix = newValue; 2061 delete fPosSuffixPattern; 2062 fPosSuffixPattern = 0; 2063} 2064 2065//------------------------------------------------------------------------------ 2066// Gets the negative suffix of the number pattern. 2067 2068UnicodeString& 2069DecimalFormat::getNegativeSuffix(UnicodeString& result) const 2070{ 2071 result = fNegativeSuffix; 2072 return result; 2073} 2074 2075//------------------------------------------------------------------------------ 2076// Sets the negative suffix of the number pattern. 2077 2078void 2079DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) 2080{ 2081 fNegativeSuffix = newValue; 2082 delete fNegSuffixPattern; 2083 fNegSuffixPattern = 0; 2084} 2085 2086//------------------------------------------------------------------------------ 2087// Gets the multiplier of the number pattern. 2088 2089int32_t DecimalFormat::getMultiplier() const 2090{ 2091 return fMultiplier; 2092} 2093 2094//------------------------------------------------------------------------------ 2095// Sets the multiplier of the number pattern. 2096void 2097DecimalFormat::setMultiplier(int32_t newValue) 2098{ 2099// if (newValue <= 0) { 2100// throw new IllegalArgumentException("Bad multiplier: " + newValue); 2101// } 2102 if (newValue > 0) { 2103 fMultiplier = newValue; 2104 } 2105 // else No way to return an error. 2106} 2107 2108/** 2109 * Get the rounding increment. 2110 * @return A positive rounding increment, or 0.0 if rounding 2111 * is not in effect. 2112 * @see #setRoundingIncrement 2113 * @see #getRoundingMode 2114 * @see #setRoundingMode 2115 */ 2116double DecimalFormat::getRoundingIncrement() const { 2117 return fRoundingDouble; 2118} 2119 2120/** 2121 * Set the rounding increment. This method also controls whether 2122 * rounding is enabled. 2123 * @param newValue A positive rounding increment, or 0.0 to disable rounding. 2124 * Negative increments are equivalent to 0.0. 2125 * @see #getRoundingIncrement 2126 * @see #getRoundingMode 2127 * @see #setRoundingMode 2128 */ 2129void DecimalFormat::setRoundingIncrement(double newValue) { 2130 if (newValue > 0.0) { 2131 if (fRoundingIncrement == NULL) { 2132 fRoundingIncrement = new DigitList(); 2133 } 2134 fRoundingIncrement->set((int32_t)newValue); 2135 fRoundingDouble = newValue; 2136 } else { 2137 delete fRoundingIncrement; 2138 fRoundingIncrement = NULL; 2139 fRoundingDouble = 0.0; 2140 } 2141} 2142 2143/** 2144 * Get the rounding mode. 2145 * @return A rounding mode 2146 * @see #setRoundingIncrement 2147 * @see #getRoundingIncrement 2148 * @see #setRoundingMode 2149 */ 2150DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const { 2151 return fRoundingMode; 2152} 2153 2154/** 2155 * Set the rounding mode. This has no effect unless the rounding 2156 * increment is greater than zero. 2157 * @param roundingMode A rounding mode 2158 * @see #setRoundingIncrement 2159 * @see #getRoundingIncrement 2160 * @see #getRoundingMode 2161 */ 2162void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { 2163 fRoundingMode = roundingMode; 2164} 2165 2166/** 2167 * Get the width to which the output of <code>format()</code> is padded. 2168 * @return the format width, or zero if no padding is in effect 2169 * @see #setFormatWidth 2170 * @see #getPadCharacter 2171 * @see #setPadCharacter 2172 * @see #getPadPosition 2173 * @see #setPadPosition 2174 */ 2175int32_t DecimalFormat::getFormatWidth() const { 2176 return fFormatWidth; 2177} 2178 2179/** 2180 * Set the width to which the output of <code>format()</code> is padded. 2181 * This method also controls whether padding is enabled. 2182 * @param width the width to which to pad the result of 2183 * <code>format()</code>, or zero to disable padding. A negative 2184 * width is equivalent to 0. 2185 * @see #getFormatWidth 2186 * @see #getPadCharacter 2187 * @see #setPadCharacter 2188 * @see #getPadPosition 2189 * @see #setPadPosition 2190 */ 2191void DecimalFormat::setFormatWidth(int32_t width) { 2192 fFormatWidth = (width > 0) ? width : 0; 2193} 2194 2195UnicodeString DecimalFormat::getPadCharacterString() const { 2196 return fPad; 2197} 2198 2199void DecimalFormat::setPadCharacter(const UnicodeString &padChar) { 2200 if (padChar.length() > 0) { 2201 fPad = padChar.char32At(0); 2202 } 2203 else { 2204 fPad = kDefaultPad; 2205 } 2206} 2207 2208/** 2209 * Get the position at which padding will take place. This is the location 2210 * at which padding will be inserted if the result of <code>format()</code> 2211 * is shorter than the format width. 2212 * @return the pad position, one of <code>kPadBeforePrefix</code>, 2213 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or 2214 * <code>kPadAfterSuffix</code>. 2215 * @see #setFormatWidth 2216 * @see #getFormatWidth 2217 * @see #setPadCharacter 2218 * @see #getPadCharacter 2219 * @see #setPadPosition 2220 * @see #kPadBeforePrefix 2221 * @see #kPadAfterPrefix 2222 * @see #kPadBeforeSuffix 2223 * @see #kPadAfterSuffix 2224 */ 2225DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const { 2226 return fPadPosition; 2227} 2228 2229/** 2230 * <strong><font face=helvetica color=red>NEW</font></strong> 2231 * Set the position at which padding will take place. This is the location 2232 * at which padding will be inserted if the result of <code>format()</code> 2233 * is shorter than the format width. This has no effect unless padding is 2234 * enabled. 2235 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>, 2236 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or 2237 * <code>kPadAfterSuffix</code>. 2238 * @see #setFormatWidth 2239 * @see #getFormatWidth 2240 * @see #setPadCharacter 2241 * @see #getPadCharacter 2242 * @see #getPadPosition 2243 * @see #kPadBeforePrefix 2244 * @see #kPadAfterPrefix 2245 * @see #kPadBeforeSuffix 2246 * @see #kPadAfterSuffix 2247 */ 2248void DecimalFormat::setPadPosition(EPadPosition padPos) { 2249 fPadPosition = padPos; 2250} 2251 2252/** 2253 * Return whether or not scientific notation is used. 2254 * @return TRUE if this object formats and parses scientific notation 2255 * @see #setScientificNotation 2256 * @see #getMinimumExponentDigits 2257 * @see #setMinimumExponentDigits 2258 * @see #isExponentSignAlwaysShown 2259 * @see #setExponentSignAlwaysShown 2260 */ 2261UBool DecimalFormat::isScientificNotation() { 2262 return fUseExponentialNotation; 2263} 2264 2265/** 2266 * Set whether or not scientific notation is used. 2267 * @param useScientific TRUE if this object formats and parses scientific 2268 * notation 2269 * @see #isScientificNotation 2270 * @see #getMinimumExponentDigits 2271 * @see #setMinimumExponentDigits 2272 * @see #isExponentSignAlwaysShown 2273 * @see #setExponentSignAlwaysShown 2274 */ 2275void DecimalFormat::setScientificNotation(UBool useScientific) { 2276 fUseExponentialNotation = useScientific; 2277} 2278 2279/** 2280 * Return the minimum exponent digits that will be shown. 2281 * @return the minimum exponent digits that will be shown 2282 * @see #setScientificNotation 2283 * @see #isScientificNotation 2284 * @see #setMinimumExponentDigits 2285 * @see #isExponentSignAlwaysShown 2286 * @see #setExponentSignAlwaysShown 2287 */ 2288int8_t DecimalFormat::getMinimumExponentDigits() const { 2289 return fMinExponentDigits; 2290} 2291 2292/** 2293 * Set the minimum exponent digits that will be shown. This has no 2294 * effect unless scientific notation is in use. 2295 * @param minExpDig a value >= 1 indicating the fewest exponent digits 2296 * that will be shown. Values less than 1 will be treated as 1. 2297 * @see #setScientificNotation 2298 * @see #isScientificNotation 2299 * @see #getMinimumExponentDigits 2300 * @see #isExponentSignAlwaysShown 2301 * @see #setExponentSignAlwaysShown 2302 */ 2303void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { 2304 fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1); 2305} 2306 2307/** 2308 * Return whether the exponent sign is always shown. 2309 * @return TRUE if the exponent is always prefixed with either the 2310 * localized minus sign or the localized plus sign, false if only negative 2311 * exponents are prefixed with the localized minus sign. 2312 * @see #setScientificNotation 2313 * @see #isScientificNotation 2314 * @see #setMinimumExponentDigits 2315 * @see #getMinimumExponentDigits 2316 * @see #setExponentSignAlwaysShown 2317 */ 2318UBool DecimalFormat::isExponentSignAlwaysShown() { 2319 return fExponentSignAlwaysShown; 2320} 2321 2322/** 2323 * Set whether the exponent sign is always shown. This has no effect 2324 * unless scientific notation is in use. 2325 * @param expSignAlways TRUE if the exponent is always prefixed with either 2326 * the localized minus sign or the localized plus sign, false if only 2327 * negative exponents are prefixed with the localized minus sign. 2328 * @see #setScientificNotation 2329 * @see #isScientificNotation 2330 * @see #setMinimumExponentDigits 2331 * @see #getMinimumExponentDigits 2332 * @see #isExponentSignAlwaysShown 2333 */ 2334void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { 2335 fExponentSignAlwaysShown = expSignAlways; 2336} 2337 2338//------------------------------------------------------------------------------ 2339// Gets the grouping size of the number pattern. For example, thousand or 10 2340// thousand groupings. 2341 2342int32_t 2343DecimalFormat::getGroupingSize() const 2344{ 2345 return fGroupingSize; 2346} 2347 2348//------------------------------------------------------------------------------ 2349// Gets the grouping size of the number pattern. 2350 2351void 2352DecimalFormat::setGroupingSize(int32_t newValue) 2353{ 2354 fGroupingSize = newValue; 2355} 2356 2357//------------------------------------------------------------------------------ 2358 2359int32_t 2360DecimalFormat::getSecondaryGroupingSize() const 2361{ 2362 return fGroupingSize2; 2363} 2364 2365//------------------------------------------------------------------------------ 2366 2367void 2368DecimalFormat::setSecondaryGroupingSize(int32_t newValue) 2369{ 2370 fGroupingSize2 = newValue; 2371} 2372 2373//------------------------------------------------------------------------------ 2374// Checks if to show the decimal separator. 2375 2376UBool 2377DecimalFormat::isDecimalSeparatorAlwaysShown() const 2378{ 2379 return fDecimalSeparatorAlwaysShown; 2380} 2381 2382//------------------------------------------------------------------------------ 2383// Sets to always show the decimal separator. 2384 2385void 2386DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) 2387{ 2388 fDecimalSeparatorAlwaysShown = newValue; 2389} 2390 2391//------------------------------------------------------------------------------ 2392// Emits the pattern of this DecimalFormat instance. 2393 2394UnicodeString& 2395DecimalFormat::toPattern(UnicodeString& result) const 2396{ 2397 return toPattern(result, FALSE); 2398} 2399 2400//------------------------------------------------------------------------------ 2401// Emits the localized pattern this DecimalFormat instance. 2402 2403UnicodeString& 2404DecimalFormat::toLocalizedPattern(UnicodeString& result) const 2405{ 2406 return toPattern(result, TRUE); 2407} 2408 2409//------------------------------------------------------------------------------ 2410/** 2411 * Expand the affix pattern strings into the expanded affix strings. If any 2412 * affix pattern string is null, do not expand it. This method should be 2413 * called any time the symbols or the affix patterns change in order to keep 2414 * the expanded affix strings up to date. 2415 */ 2416void DecimalFormat::expandAffixes() { 2417 if (fPosPrefixPattern != 0) { 2418 expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, FALSE); 2419 } 2420 if (fPosSuffixPattern != 0) { 2421 expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, FALSE); 2422 } 2423 if (fNegPrefixPattern != 0) { 2424 expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, FALSE); 2425 } 2426 if (fNegSuffixPattern != 0) { 2427 expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, FALSE); 2428 } 2429#ifdef FMT_DEBUG 2430 UnicodeString s; 2431 s.append("[") 2432 .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern) 2433 .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern) 2434 .append("]->[") 2435 .append(fPositivePrefix).append("|").append(fPositiveSuffix) 2436 .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix) 2437 .append("]\n"); 2438 debugout(s); 2439#endif 2440} 2441 2442/** 2443 * Expand an affix pattern into an affix string. All characters in the 2444 * pattern are literal unless prefixed by kQuote. The following characters 2445 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 2446 * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote + 2447 * kCurrencySign + kCurrencySign), it is interpreted as an international 2448 * currency sign. Any other character after a kQuote represents itself. 2449 * kQuote must be followed by another character; kQuote may not occur by 2450 * itself at the end of the pattern. 2451 * 2452 * This method is used in two distinct ways. First, it is used to expand 2453 * the stored affix patterns into actual affixes. For this usage, doFormat 2454 * must be false. Second, it is used to expand the stored affix patterns 2455 * given a specific number (doFormat == true), for those rare cases in 2456 * which a currency format references a ChoiceFormat (e.g., en_IN display 2457 * name for INR). The number itself is taken from digitList. 2458 * 2459 * When used in the first way, this method has a side effect: It sets 2460 * currencyChoice to a ChoiceFormat object, if the currency's display name 2461 * in this locale is a ChoiceFormat pattern (very rare). It only does this 2462 * if currencyChoice is null to start with. 2463 * 2464 * @param pattern the non-null, fPossibly empty pattern 2465 * @param affix string to receive the expanded equivalent of pattern. 2466 * Previous contents are deleted. 2467 * @param doFormat if false, then the pattern will be expanded, and if a 2468 * currency symbol is encountered that expands to a ChoiceFormat, the 2469 * currencyChoice member variable will be initialized if it is null. If 2470 * doFormat is true, then it is assumed that the currencyChoice has been 2471 * created, and it will be used to format the value in digitList. 2472 */ 2473void DecimalFormat::expandAffix(const UnicodeString& pattern, 2474 UnicodeString& affix, 2475 double number, 2476 UBool doFormat) const { 2477 affix.remove(); 2478 for (int i=0; i<pattern.length(); ) { 2479 UChar32 c = pattern.char32At(i); 2480 i += U16_LENGTH(c); 2481 if (c == kQuote) { 2482 c = pattern.char32At(i); 2483 i += U16_LENGTH(c); 2484 switch (c) { 2485 case kCurrencySign: { 2486 // As of ICU 2.2 we use the currency object, and 2487 // ignore the currency symbols in the DFS, unless 2488 // we have a null currency object. This occurs if 2489 // resurrecting a pre-2.2 object or if the user 2490 // sets a custom DFS. 2491 UBool intl = i<pattern.length() && 2492 pattern.char32At(i) == kCurrencySign; 2493 if (intl) { 2494 ++i; 2495 } 2496 const UChar* currencyUChars = getCurrency(); 2497 if (currencyUChars[0] != 0) { 2498 UErrorCode ec = U_ZERO_ERROR; 2499 if(intl) { 2500 affix += currencyUChars; 2501 } else { 2502 int32_t len; 2503 UBool isChoiceFormat; 2504 const UChar* s = ucurr_getName(currencyUChars, fSymbols->getLocale().getName(), 2505 UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec); 2506 if (isChoiceFormat) { 2507 // Two modes here: If doFormat is false, we set up 2508 // currencyChoice. If doFormat is true, we use the 2509 // previously created currencyChoice to format the 2510 // value in digitList. 2511 if (!doFormat) { 2512 // If the currency is handled by a ChoiceFormat, 2513 // then we're not going to use the expanded 2514 // patterns. Instantiate the ChoiceFormat and 2515 // return. 2516 if (fCurrencyChoice == NULL) { 2517 // TODO Replace double-check with proper thread-safe code 2518 ChoiceFormat* fmt = new ChoiceFormat(s, ec); 2519 if (U_SUCCESS(ec)) { 2520 umtx_lock(NULL); 2521 if (fCurrencyChoice == NULL) { 2522 // Cast away const 2523 ((DecimalFormat*)this)->fCurrencyChoice = fmt; 2524 fmt = NULL; 2525 } 2526 umtx_unlock(NULL); 2527 delete fmt; 2528 } 2529 } 2530 // We could almost return null or "" here, since the 2531 // expanded affixes are almost not used at all 2532 // in this situation. However, one method -- 2533 // toPattern() -- still does use the expanded 2534 // affixes, in order to set up a padding 2535 // pattern. We use the CURRENCY_SIGN as a 2536 // placeholder. 2537 affix.append(kCurrencySign); 2538 } else { 2539 if (fCurrencyChoice != NULL) { 2540 FieldPosition pos(0); // ignored 2541 if (number < 0) { 2542 number = -number; 2543 } 2544 fCurrencyChoice->format(number, affix, pos); 2545 } else { 2546 // We only arrive here if the currency choice 2547 // format in the locale data is INVALID. 2548 affix += currencyUChars; 2549 } 2550 } 2551 continue; 2552 } 2553 affix += UnicodeString(s, len); 2554 } 2555 } else { 2556 if(intl) { 2557 affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 2558 } else { 2559 affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); 2560 } 2561 } 2562 break; 2563 } 2564 case kPatternPercent: 2565 affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 2566 break; 2567 case kPatternPerMill: 2568 affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 2569 break; 2570 case kPatternPlus: 2571 affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 2572 break; 2573 case kPatternMinus: 2574 affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 2575 break; 2576 default: 2577 affix.append(c); 2578 break; 2579 } 2580 } 2581 else { 2582 affix.append(c); 2583 } 2584 } 2585} 2586 2587/** 2588 * Append an affix to the given StringBuffer. 2589 * @param buf buffer to append to 2590 * @param isNegative 2591 * @param isPrefix 2592 */ 2593int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, 2594 UBool isNegative, UBool isPrefix) const { 2595 if (fCurrencyChoice != 0) { 2596 const UnicodeString* affixPat; 2597 if (isPrefix) { 2598 affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern; 2599 } else { 2600 affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern; 2601 } 2602 if (affixPat) { 2603 UnicodeString affixBuf; 2604 expandAffix(*affixPat, affixBuf, number, TRUE); 2605 buf.append(affixBuf); 2606 return affixBuf.length(); 2607 } 2608 // else someone called a function that reset the pattern. 2609 } 2610 2611 const UnicodeString* affix; 2612 if (isPrefix) { 2613 affix = isNegative ? &fNegativePrefix : &fPositivePrefix; 2614 } else { 2615 affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix; 2616 } 2617 buf.append(*affix); 2618 return affix->length(); 2619} 2620 2621/** 2622 * Appends an affix pattern to the given StringBuffer, quoting special 2623 * characters as needed. Uses the internal affix pattern, if that exists, 2624 * or the literal affix, if the internal affix pattern is null. The 2625 * appended string will generate the same affix pattern (or literal affix) 2626 * when passed to toPattern(). 2627 * 2628 * @param appendTo the affix string is appended to this 2629 * @param affixPattern a pattern such as fPosPrefixPattern; may be null 2630 * @param expAffix a corresponding expanded affix, such as fPositivePrefix. 2631 * Ignored unless affixPattern is null. If affixPattern is null, then 2632 * expAffix is appended as a literal affix. 2633 * @param localized true if the appended pattern should contain localized 2634 * pattern characters; otherwise, non-localized pattern chars are appended 2635 */ 2636void DecimalFormat::appendAffixPattern(UnicodeString& appendTo, 2637 const UnicodeString* affixPattern, 2638 const UnicodeString& expAffix, 2639 UBool localized) const { 2640 if (affixPattern == 0) { 2641 appendAffixPattern(appendTo, expAffix, localized); 2642 } else { 2643 int i; 2644 for (int pos=0; pos<affixPattern->length(); pos=i) { 2645 i = affixPattern->indexOf(kQuote, pos); 2646 if (i < 0) { 2647 UnicodeString s; 2648 affixPattern->extractBetween(pos, affixPattern->length(), s); 2649 appendAffixPattern(appendTo, s, localized); 2650 break; 2651 } 2652 if (i > pos) { 2653 UnicodeString s; 2654 affixPattern->extractBetween(pos, i, s); 2655 appendAffixPattern(appendTo, s, localized); 2656 } 2657 UChar32 c = affixPattern->char32At(++i); 2658 ++i; 2659 if (c == kQuote) { 2660 appendTo.append(c).append(c); 2661 // Fall through and append another kQuote below 2662 } else if (c == kCurrencySign && 2663 i<affixPattern->length() && 2664 affixPattern->char32At(i) == kCurrencySign) { 2665 ++i; 2666 appendTo.append(c).append(c); 2667 } else if (localized) { 2668 switch (c) { 2669 case kPatternPercent: 2670 appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 2671 break; 2672 case kPatternPerMill: 2673 appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 2674 break; 2675 case kPatternPlus: 2676 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 2677 break; 2678 case kPatternMinus: 2679 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 2680 break; 2681 default: 2682 appendTo.append(c); 2683 } 2684 } else { 2685 appendTo.append(c); 2686 } 2687 } 2688 } 2689} 2690 2691/** 2692 * Append an affix to the given StringBuffer, using quotes if 2693 * there are special characters. Single quotes themselves must be 2694 * escaped in either case. 2695 */ 2696void 2697DecimalFormat::appendAffixPattern(UnicodeString& appendTo, 2698 const UnicodeString& affix, 2699 UBool localized) const { 2700 UBool needQuote; 2701 if(localized) { 2702 needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0 2703 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0 2704 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0 2705 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0 2706 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0 2707 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0 2708 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0 2709 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0 2710 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0 2711 || affix.indexOf(kCurrencySign) >= 0; 2712 } 2713 else { 2714 needQuote = affix.indexOf(kPatternZeroDigit) >= 0 2715 || affix.indexOf(kPatternGroupingSeparator) >= 0 2716 || affix.indexOf(kPatternDecimalSeparator) >= 0 2717 || affix.indexOf(kPatternPercent) >= 0 2718 || affix.indexOf(kPatternPerMill) >= 0 2719 || affix.indexOf(kPatternDigit) >= 0 2720 || affix.indexOf(kPatternSeparator) >= 0 2721 || affix.indexOf(kPatternExponent) >= 0 2722 || affix.indexOf(kPatternPlus) >= 0 2723 || affix.indexOf(kPatternMinus) >= 0 2724 || affix.indexOf(kCurrencySign) >= 0; 2725 } 2726 if (needQuote) 2727 appendTo += (UChar)0x0027 /*'\''*/; 2728 if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0) 2729 appendTo += affix; 2730 else { 2731 for (int32_t j = 0; j < affix.length(); ) { 2732 UChar32 c = affix.char32At(j); 2733 j += U16_LENGTH(c); 2734 appendTo += c; 2735 if (c == 0x0027 /*'\''*/) 2736 appendTo += c; 2737 } 2738 } 2739 if (needQuote) 2740 appendTo += (UChar)0x0027 /*'\''*/; 2741} 2742 2743//------------------------------------------------------------------------------ 2744 2745UnicodeString& 2746DecimalFormat::toPattern(UnicodeString& result, UBool localized) const 2747{ 2748 result.remove(); 2749 UChar32 zero, sigDigit = kPatternSignificantDigit; 2750 UnicodeString digit, group; 2751 int32_t i; 2752 int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits 2753 UnicodeString roundingDigits; 2754 int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1; 2755 UnicodeString padSpec; 2756 UBool useSigDig = areSignificantDigitsUsed(); 2757 2758 if (localized) { 2759 digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)); 2760 group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)); 2761 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 2762 if (useSigDig) { 2763 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0); 2764 } 2765 } 2766 else { 2767 digit.append((UChar)kPatternDigit); 2768 group.append((UChar)kPatternGroupingSeparator); 2769 zero = (UChar32)kPatternZeroDigit; 2770 } 2771 if (fFormatWidth > 0) { 2772 if (localized) { 2773 padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol)); 2774 } 2775 else { 2776 padSpec.append((UChar)kPatternPadEscape); 2777 } 2778 padSpec.append(fPad); 2779 } 2780 if (fRoundingIncrement != NULL) { 2781 for(i=0; i<fRoundingIncrement->fCount; ++i) { 2782 roundingDigits.append((UChar)fRoundingIncrement->fDigits[i]); 2783 } 2784 roundingDecimalPos = fRoundingIncrement->fDecimalAt; 2785 } 2786 for (int32_t part=0; part<2; ++part) { 2787 if (padPos == kPadBeforePrefix) { 2788 result.append(padSpec); 2789 } 2790 appendAffixPattern(result, 2791 (part==0 ? fPosPrefixPattern : fNegPrefixPattern), 2792 (part==0 ? fPositivePrefix : fNegativePrefix), 2793 localized); 2794 if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) { 2795 result.append(padSpec); 2796 } 2797 int32_t sub0Start = result.length(); 2798 int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0; 2799 if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) { 2800 g += fGroupingSize2; 2801 } 2802 int32_t maxDig = 0, minDig = 0, maxSigDig = 0; 2803 if (useSigDig) { 2804 minDig = getMinimumSignificantDigits(); 2805 maxDig = maxSigDig = getMaximumSignificantDigits(); 2806 } else { 2807 minDig = getMinimumIntegerDigits(); 2808 maxDig = getMaximumIntegerDigits(); 2809 } 2810 if (fUseExponentialNotation) { 2811 if (maxDig > kMaxScientificIntegerDigits) { 2812 maxDig = 1; 2813 } 2814 } else if (useSigDig) { 2815 maxDig = _max(maxDig, g+1); 2816 } else { 2817 maxDig = _max(_max(g, getMinimumIntegerDigits()), 2818 roundingDecimalPos) + 1; 2819 } 2820 for (i = maxDig; i > 0; --i) { 2821 if (!fUseExponentialNotation && i<maxDig && 2822 isGroupingPosition(i)) { 2823 result.append(group); 2824 } 2825 if (useSigDig) { 2826 // #@,@### (maxSigDig == 5, minSigDig == 2) 2827 // 65 4321 (1-based pos, count from the right) 2828 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig) 2829 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig 2830 if (maxSigDig >= i && i > (maxSigDig - minDig)) { 2831 result.append(sigDigit); 2832 } else { 2833 result.append(digit); 2834 } 2835 } else { 2836 if (! roundingDigits.isEmpty()) { 2837 int32_t pos = roundingDecimalPos - i; 2838 if (pos >= 0 && pos < roundingDigits.length()) { 2839 result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero)); 2840 continue; 2841 } 2842 } 2843 if (i<=minDig) { 2844 result.append(zero); 2845 } else { 2846 result.append(digit); 2847 } 2848 } 2849 } 2850 if (!useSigDig) { 2851 if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) { 2852 if (localized) { 2853 result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 2854 } 2855 else { 2856 result.append((UChar)kPatternDecimalSeparator); 2857 } 2858 } 2859 int32_t pos = roundingDecimalPos; 2860 for (i = 0; i < getMaximumFractionDigits(); ++i) { 2861 if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) { 2862 if (pos < 0) { 2863 result.append(zero); 2864 } 2865 else { 2866 result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero)); 2867 } 2868 ++pos; 2869 continue; 2870 } 2871 if (i<getMinimumFractionDigits()) { 2872 result.append(zero); 2873 } 2874 else { 2875 result.append(digit); 2876 } 2877 } 2878 } 2879 if (fUseExponentialNotation) { 2880 if (localized) { 2881 result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); 2882 } 2883 else { 2884 result.append((UChar)kPatternExponent); 2885 } 2886 if (fExponentSignAlwaysShown) { 2887 if (localized) { 2888 result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 2889 } 2890 else { 2891 result.append((UChar)kPatternPlus); 2892 } 2893 } 2894 for (i=0; i<fMinExponentDigits; ++i) { 2895 result.append(zero); 2896 } 2897 } 2898 if (! padSpec.isEmpty() && !fUseExponentialNotation) { 2899 int32_t add = fFormatWidth - result.length() + sub0Start 2900 - ((part == 0) 2901 ? fPositivePrefix.length() + fPositiveSuffix.length() 2902 : fNegativePrefix.length() + fNegativeSuffix.length()); 2903 while (add > 0) { 2904 result.insert(sub0Start, digit); 2905 ++maxDig; 2906 --add; 2907 // Only add a grouping separator if we have at least 2908 // 2 additional characters to be added, so we don't 2909 // end up with ",###". 2910 if (add>1 && isGroupingPosition(maxDig)) { 2911 result.insert(sub0Start, group); 2912 --add; 2913 } 2914 } 2915 } 2916 if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) { 2917 result.append(padSpec); 2918 } 2919 if (part == 0) { 2920 appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized); 2921 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { 2922 result.append(padSpec); 2923 } 2924 UBool isDefault = FALSE; 2925 if ((fNegSuffixPattern == fPosSuffixPattern && // both null 2926 fNegativeSuffix == fPositiveSuffix) 2927 || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 && 2928 *fNegSuffixPattern == *fPosSuffixPattern)) 2929 { 2930 if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL) 2931 { 2932 int32_t length = fPosPrefixPattern->length(); 2933 isDefault = fNegPrefixPattern->length() == (length+2) && 2934 (*fNegPrefixPattern)[(int32_t)0] == kQuote && 2935 (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus && 2936 fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0; 2937 } 2938 if (!isDefault && 2939 fNegPrefixPattern == NULL && fPosPrefixPattern == NULL) 2940 { 2941 int32_t length = fPositivePrefix.length(); 2942 isDefault = fNegativePrefix.length() == (length+1) && 2943 fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 && 2944 fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0; 2945 } 2946 } 2947 if (isDefault) { 2948 break; // Don't output default negative subpattern 2949 } else { 2950 if (localized) { 2951 result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol); 2952 } 2953 else { 2954 result.append((UChar)kPatternSeparator); 2955 } 2956 } 2957 } else { 2958 appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized); 2959 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { 2960 result.append(padSpec); 2961 } 2962 } 2963 } 2964 2965 return result; 2966} 2967 2968//------------------------------------------------------------------------------ 2969 2970void 2971DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) 2972{ 2973 UParseError parseError; 2974 applyPattern(pattern, FALSE, parseError, status); 2975} 2976 2977//------------------------------------------------------------------------------ 2978 2979void 2980DecimalFormat::applyPattern(const UnicodeString& pattern, 2981 UParseError& parseError, 2982 UErrorCode& status) 2983{ 2984 applyPattern(pattern, FALSE, parseError, status); 2985} 2986//------------------------------------------------------------------------------ 2987 2988void 2989DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status) 2990{ 2991 UParseError parseError; 2992 applyPattern(pattern, TRUE,parseError,status); 2993} 2994 2995//------------------------------------------------------------------------------ 2996 2997void 2998DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, 2999 UParseError& parseError, 3000 UErrorCode& status) 3001{ 3002 applyPattern(pattern, TRUE,parseError,status); 3003} 3004 3005//------------------------------------------------------------------------------ 3006 3007void 3008DecimalFormat::applyPattern(const UnicodeString& pattern, 3009 UBool localized, 3010 UParseError& parseError, 3011 UErrorCode& status) 3012{ 3013 if (U_FAILURE(status)) 3014 { 3015 return; 3016 } 3017 // Clear error struct 3018 parseError.offset = -1; 3019 parseError.preContext[0] = parseError.postContext[0] = (UChar)0; 3020 3021 // Set the significant pattern symbols 3022 UChar32 zeroDigit = kPatternZeroDigit; // '0' 3023 UChar32 sigDigit = kPatternSignificantDigit; // '@' 3024 UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator); 3025 UnicodeString decimalSeparator ((UChar)kPatternDecimalSeparator); 3026 UnicodeString percent ((UChar)kPatternPercent); 3027 UnicodeString perMill ((UChar)kPatternPerMill); 3028 UnicodeString digit ((UChar)kPatternDigit); // '#' 3029 UnicodeString separator ((UChar)kPatternSeparator); 3030 UnicodeString exponent ((UChar)kPatternExponent); 3031 UnicodeString plus ((UChar)kPatternPlus); 3032 UnicodeString minus ((UChar)kPatternMinus); 3033 UnicodeString padEscape ((UChar)kPatternPadEscape); 3034 // Substitute with the localized symbols if necessary 3035 if (localized) { 3036 zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 3037 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0); 3038 groupingSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)); 3039 decimalSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)); 3040 percent. remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)); 3041 perMill. remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)); 3042 digit. remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)); 3043 separator. remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)); 3044 exponent. remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol)); 3045 plus. remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)); 3046 minus. remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)); 3047 padEscape. remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol)); 3048 } 3049 UChar nineDigit = (UChar)(zeroDigit + 9); 3050 int32_t digitLen = digit.length(); 3051 int32_t groupSepLen = groupingSeparator.length(); 3052 int32_t decimalSepLen = decimalSeparator.length(); 3053 3054 int32_t pos = 0; 3055 int32_t patLen = pattern.length(); 3056 // Part 0 is the positive pattern. Part 1, if present, is the negative 3057 // pattern. 3058 for (int32_t part=0; part<2 && pos<patLen; ++part) { 3059 // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 3060 // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is 3061 // between the prefix and suffix, and consists of pattern 3062 // characters. In the prefix and suffix, percent, perMill, and 3063 // currency symbols are recognized and translated. 3064 int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0; 3065 3066 // It's important that we don't change any fields of this object 3067 // prematurely. We set the following variables for the multiplier, 3068 // grouping, etc., and then only change the actual object fields if 3069 // everything parses correctly. This also lets us register 3070 // the data from part 0 and ignore the part 1, except for the 3071 // prefix and suffix. 3072 UnicodeString prefix; 3073 UnicodeString suffix; 3074 int32_t decimalPos = -1; 3075 int32_t multiplier = 1; 3076 int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0; 3077 int8_t groupingCount = -1; 3078 int8_t groupingCount2 = -1; 3079 int32_t padPos = -1; 3080 UChar32 padChar = 0; 3081 int32_t roundingPos = -1; 3082 DigitList roundingInc; 3083 int8_t expDigits = -1; 3084 UBool expSignAlways = FALSE; 3085 UBool isCurrency = FALSE; 3086 3087 // The affix is either the prefix or the suffix. 3088 UnicodeString* affix = &prefix; 3089 3090 int32_t start = pos; 3091 UBool isPartDone = FALSE; 3092 UChar32 ch; 3093 3094 for (; !isPartDone && pos < patLen; ) { 3095 // Todo: account for surrogate pairs 3096 ch = pattern.char32At(pos); 3097 switch (subpart) { 3098 case 0: // Pattern proper subpart (between prefix & suffix) 3099 // Process the digits, decimal, and grouping characters. We 3100 // record five pieces of information. We expect the digits 3101 // to occur in the pattern ####00.00####, and we record the 3102 // number of left digits, zero (central) digits, and right 3103 // digits. The position of the last grouping character is 3104 // recorded (should be somewhere within the first two blocks 3105 // of characters), as is the position of the decimal point, 3106 // if any (should be in the zero digits). If there is no 3107 // decimal point, then there should be no right digits. 3108 if (pattern.compare(pos, digitLen, digit) == 0) { 3109 if (zeroDigitCount > 0 || sigDigitCount > 0) { 3110 ++digitRightCount; 3111 } else { 3112 ++digitLeftCount; 3113 } 3114 if (groupingCount >= 0 && decimalPos < 0) { 3115 ++groupingCount; 3116 } 3117 pos += digitLen; 3118 } else if ((ch >= zeroDigit && ch <= nineDigit) || 3119 ch == sigDigit) { 3120 if (digitRightCount > 0) { 3121 // Unexpected '0' 3122 debug("Unexpected '0'") 3123 status = U_UNEXPECTED_TOKEN; 3124 syntaxError(pattern,pos,parseError); 3125 return; 3126 } 3127 if (ch == sigDigit) { 3128 ++sigDigitCount; 3129 } else { 3130 ++zeroDigitCount; 3131 if (ch != zeroDigit && roundingPos < 0) { 3132 roundingPos = digitLeftCount + zeroDigitCount; 3133 } 3134 if (roundingPos >= 0) { 3135 roundingInc.append((char)(ch - zeroDigit + '0')); 3136 } 3137 } 3138 if (groupingCount >= 0 && decimalPos < 0) { 3139 ++groupingCount; 3140 } 3141 pos += U16_LENGTH(ch); 3142 } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) { 3143 if (decimalPos >= 0) { 3144 // Grouping separator after decimal 3145 debug("Grouping separator after decimal") 3146 status = U_UNEXPECTED_TOKEN; 3147 syntaxError(pattern,pos,parseError); 3148 return; 3149 } 3150 groupingCount2 = groupingCount; 3151 groupingCount = 0; 3152 pos += groupSepLen; 3153 } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) { 3154 if (decimalPos >= 0) { 3155 // Multiple decimal separators 3156 debug("Multiple decimal separators") 3157 status = U_MULTIPLE_DECIMAL_SEPARATORS; 3158 syntaxError(pattern,pos,parseError); 3159 return; 3160 } 3161 // Intentionally incorporate the digitRightCount, 3162 // even though it is illegal for this to be > 0 3163 // at this point. We check pattern syntax below. 3164 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount; 3165 pos += decimalSepLen; 3166 } else { 3167 if (pattern.compare(pos, exponent.length(), exponent) == 0) { 3168 if (expDigits >= 0) { 3169 // Multiple exponential symbols 3170 debug("Multiple exponential symbols") 3171 status = U_MULTIPLE_EXPONENTIAL_SYMBOLS; 3172 syntaxError(pattern,pos,parseError); 3173 return; 3174 } 3175 if (groupingCount >= 0) { 3176 // Grouping separator in exponential pattern 3177 debug("Grouping separator in exponential pattern") 3178 status = U_MALFORMED_EXPONENTIAL_PATTERN; 3179 syntaxError(pattern,pos,parseError); 3180 return; 3181 } 3182 pos += exponent.length(); 3183 // Check for positive prefix 3184 if (pos < patLen 3185 && pattern.compare(pos, plus.length(), plus) == 0) { 3186 expSignAlways = TRUE; 3187 pos += plus.length(); 3188 } 3189 // Use lookahead to parse out the exponential part of the 3190 // pattern, then jump into suffix subpart. 3191 expDigits = 0; 3192 while (pos < patLen && 3193 pattern.char32At(pos) == zeroDigit) { 3194 ++expDigits; 3195 pos += U16_LENGTH(zeroDigit); 3196 } 3197 3198 // 1. Require at least one mantissa pattern digit 3199 // 2. Disallow "#+ @" in mantissa 3200 // 3. Require at least one exponent pattern digit 3201 if (((digitLeftCount + zeroDigitCount) < 1 && 3202 (sigDigitCount + digitRightCount) < 1) || 3203 (sigDigitCount > 0 && digitLeftCount > 0) || 3204 expDigits < 1) { 3205 // Malformed exponential pattern 3206 debug("Malformed exponential pattern") 3207 status = U_MALFORMED_EXPONENTIAL_PATTERN; 3208 syntaxError(pattern,pos,parseError); 3209 return; 3210 } 3211 } 3212 // Transition to suffix subpart 3213 subpart = 2; // suffix subpart 3214 affix = &suffix; 3215 sub0Limit = pos; 3216 continue; 3217 } 3218 break; 3219 case 1: // Prefix subpart 3220 case 2: // Suffix subpart 3221 // Process the prefix / suffix characters 3222 // Process unquoted characters seen in prefix or suffix 3223 // subpart. 3224 3225 // Several syntax characters implicitly begins the 3226 // next subpart if we are in the prefix; otherwise 3227 // they are illegal if unquoted. 3228 if (!pattern.compare(pos, digitLen, digit) || 3229 !pattern.compare(pos, groupSepLen, groupingSeparator) || 3230 !pattern.compare(pos, decimalSepLen, decimalSeparator) || 3231 (ch >= zeroDigit && ch <= nineDigit) || 3232 ch == sigDigit) { 3233 if (subpart == 1) { // prefix subpart 3234 subpart = 0; // pattern proper subpart 3235 sub0Start = pos; // Reprocess this character 3236 continue; 3237 } else { 3238 status = U_UNQUOTED_SPECIAL; 3239 syntaxError(pattern,pos,parseError); 3240 return; 3241 } 3242 } else if (ch == kCurrencySign) { 3243 affix->append(kQuote); // Encode currency 3244 // Use lookahead to determine if the currency sign is 3245 // doubled or not. 3246 U_ASSERT(U16_LENGTH(kCurrencySign) == 1); 3247 if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) { 3248 affix->append(kCurrencySign); 3249 ++pos; // Skip over the doubled character 3250 } 3251 isCurrency = TRUE; 3252 // Fall through to append(ch) 3253 } else if (ch == kQuote) { 3254 // A quote outside quotes indicates either the opening 3255 // quote or two quotes, which is a quote literal. That is, 3256 // we have the first quote in 'do' or o''clock. 3257 U_ASSERT(U16_LENGTH(kQuote) == 1); 3258 ++pos; 3259 if (pos < pattern.length() && pattern[pos] == kQuote) { 3260 affix->append(kQuote); // Encode quote 3261 // Fall through to append(ch) 3262 } else { 3263 subpart += 2; // open quote 3264 continue; 3265 } 3266 } else if (pattern.compare(pos, separator.length(), separator) == 0) { 3267 // Don't allow separators in the prefix, and don't allow 3268 // separators in the second pattern (part == 1). 3269 if (subpart == 1 || part == 1) { 3270 // Unexpected separator 3271 debug("Unexpected separator") 3272 status = U_UNEXPECTED_TOKEN; 3273 syntaxError(pattern,pos,parseError); 3274 return; 3275 } 3276 sub2Limit = pos; 3277 isPartDone = TRUE; // Go to next part 3278 pos += separator.length(); 3279 break; 3280 } else if (pattern.compare(pos, percent.length(), percent) == 0) { 3281 // Next handle characters which are appended directly. 3282 if (multiplier != 1) { 3283 // Too many percent/perMill characters 3284 debug("Too many percent characters") 3285 status = U_MULTIPLE_PERCENT_SYMBOLS; 3286 syntaxError(pattern,pos,parseError); 3287 return; 3288 } 3289 affix->append(kQuote); // Encode percent/perMill 3290 affix->append(kPatternPercent); // Use unlocalized pattern char 3291 multiplier = 100; 3292 pos += percent.length(); 3293 break; 3294 } else if (pattern.compare(pos, perMill.length(), perMill) == 0) { 3295 // Next handle characters which are appended directly. 3296 if (multiplier != 1) { 3297 // Too many percent/perMill characters 3298 debug("Too many perMill characters") 3299 status = U_MULTIPLE_PERMILL_SYMBOLS; 3300 syntaxError(pattern,pos,parseError); 3301 return; 3302 } 3303 affix->append(kQuote); // Encode percent/perMill 3304 affix->append(kPatternPerMill); // Use unlocalized pattern char 3305 multiplier = 1000; 3306 pos += perMill.length(); 3307 break; 3308 } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) { 3309 if (padPos >= 0 || // Multiple pad specifiers 3310 (pos+1) == pattern.length()) { // Nothing after padEscape 3311 debug("Multiple pad specifiers") 3312 status = U_MULTIPLE_PAD_SPECIFIERS; 3313 syntaxError(pattern,pos,parseError); 3314 return; 3315 } 3316 padPos = pos; 3317 pos += padEscape.length(); 3318 padChar = pattern.char32At(pos); 3319 pos += U16_LENGTH(padChar); 3320 break; 3321 } else if (pattern.compare(pos, minus.length(), minus) == 0) { 3322 affix->append(kQuote); // Encode minus 3323 affix->append(kPatternMinus); 3324 pos += minus.length(); 3325 break; 3326 } else if (pattern.compare(pos, plus.length(), plus) == 0) { 3327 affix->append(kQuote); // Encode plus 3328 affix->append(kPatternPlus); 3329 pos += plus.length(); 3330 break; 3331 } 3332 // Unquoted, non-special characters fall through to here, as 3333 // well as other code which needs to append something to the 3334 // affix. 3335 affix->append(ch); 3336 pos += U16_LENGTH(ch); 3337 break; 3338 case 3: // Prefix subpart, in quote 3339 case 4: // Suffix subpart, in quote 3340 // A quote within quotes indicates either the closing 3341 // quote or two quotes, which is a quote literal. That is, 3342 // we have the second quote in 'do' or 'don''t'. 3343 if (ch == kQuote) { 3344 ++pos; 3345 if (pos < pattern.length() && pattern[pos] == kQuote) { 3346 affix->append(kQuote); // Encode quote 3347 // Fall through to append(ch) 3348 } else { 3349 subpart -= 2; // close quote 3350 continue; 3351 } 3352 } 3353 affix->append(ch); 3354 pos += U16_LENGTH(ch); 3355 break; 3356 } 3357 } 3358 3359 if (sub0Limit == 0) { 3360 sub0Limit = pattern.length(); 3361 } 3362 3363 if (sub2Limit == 0) { 3364 sub2Limit = pattern.length(); 3365 } 3366 3367 /* Handle patterns with no '0' pattern character. These patterns 3368 * are legal, but must be recodified to make sense. "##.###" -> 3369 * "#0.###". ".###" -> ".0##". 3370 * 3371 * We allow patterns of the form "####" to produce a zeroDigitCount 3372 * of zero (got that?); although this seems like it might make it 3373 * possible for format() to produce empty strings, format() checks 3374 * for this condition and outputs a zero digit in this situation. 3375 * Having a zeroDigitCount of zero yields a minimum integer digits 3376 * of zero, which allows proper round-trip patterns. We don't want 3377 * "#" to become "#0" when toPattern() is called (even though that's 3378 * what it really is, semantically). 3379 */ 3380 if (zeroDigitCount == 0 && sigDigitCount == 0 && 3381 digitLeftCount > 0 && decimalPos >= 0) { 3382 // Handle "###.###" and "###." and ".###" 3383 int n = decimalPos; 3384 if (n == 0) 3385 ++n; // Handle ".###" 3386 digitRightCount = digitLeftCount - n; 3387 digitLeftCount = n - 1; 3388 zeroDigitCount = 1; 3389 } 3390 3391 // Do syntax checking on the digits, decimal points, and quotes. 3392 if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) || 3393 (decimalPos >= 0 && 3394 (sigDigitCount > 0 || 3395 decimalPos < digitLeftCount || 3396 decimalPos > (digitLeftCount + zeroDigitCount))) || 3397 groupingCount == 0 || groupingCount2 == 0 || 3398 (sigDigitCount > 0 && zeroDigitCount > 0) || 3399 subpart > 2) 3400 { // subpart > 2 == unmatched quote 3401 debug("Syntax error") 3402 status = U_PATTERN_SYNTAX_ERROR; 3403 syntaxError(pattern,pos,parseError); 3404 return; 3405 } 3406 3407 // Make sure pad is at legal position before or after affix. 3408 if (padPos >= 0) { 3409 if (padPos == start) { 3410 padPos = kPadBeforePrefix; 3411 } else if (padPos+2 == sub0Start) { 3412 padPos = kPadAfterPrefix; 3413 } else if (padPos == sub0Limit) { 3414 padPos = kPadBeforeSuffix; 3415 } else if (padPos+2 == sub2Limit) { 3416 padPos = kPadAfterSuffix; 3417 } else { 3418 // Illegal pad position 3419 debug("Illegal pad position") 3420 status = U_ILLEGAL_PAD_POSITION; 3421 syntaxError(pattern,pos,parseError); 3422 return; 3423 } 3424 } 3425 3426 if (part == 0) { 3427 delete fPosPrefixPattern; 3428 delete fPosSuffixPattern; 3429 delete fNegPrefixPattern; 3430 delete fNegSuffixPattern; 3431 fPosPrefixPattern = new UnicodeString(prefix); 3432 /* test for NULL */ 3433 if (fPosPrefixPattern == 0) { 3434 status = U_MEMORY_ALLOCATION_ERROR; 3435 return; 3436 } 3437 fPosSuffixPattern = new UnicodeString(suffix); 3438 /* test for NULL */ 3439 if (fPosSuffixPattern == 0) { 3440 status = U_MEMORY_ALLOCATION_ERROR; 3441 delete fPosPrefixPattern; 3442 return; 3443 } 3444 fNegPrefixPattern = 0; 3445 fNegSuffixPattern = 0; 3446 3447 fUseExponentialNotation = (expDigits >= 0); 3448 if (fUseExponentialNotation) { 3449 fMinExponentDigits = expDigits; 3450 } 3451 fExponentSignAlwaysShown = expSignAlways; 3452 fIsCurrencyFormat = isCurrency; 3453 int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount; 3454 // The effectiveDecimalPos is the position the decimal is at or 3455 // would be at if there is no decimal. Note that if 3456 // decimalPos<0, then digitTotalCount == digitLeftCount + 3457 // zeroDigitCount. 3458 int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount; 3459 UBool isSigDig = (sigDigitCount > 0); 3460 setSignificantDigitsUsed(isSigDig); 3461 if (isSigDig) { 3462 setMinimumSignificantDigits(sigDigitCount); 3463 setMaximumSignificantDigits(sigDigitCount + digitRightCount); 3464 } else { 3465 int32_t minInt = effectiveDecimalPos - digitLeftCount; 3466 setMinimumIntegerDigits(minInt); 3467 setMaximumIntegerDigits(fUseExponentialNotation 3468 ? digitLeftCount + getMinimumIntegerDigits() 3469 : kDoubleIntegerDigits); 3470 setMaximumFractionDigits(decimalPos >= 0 3471 ? (digitTotalCount - decimalPos) : 0); 3472 setMinimumFractionDigits(decimalPos >= 0 3473 ? (digitLeftCount + zeroDigitCount - decimalPos) : 0); 3474 } 3475 setGroupingUsed(groupingCount > 0); 3476 fGroupingSize = (groupingCount > 0) ? groupingCount : 0; 3477 fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount) 3478 ? groupingCount2 : 0; 3479 fMultiplier = multiplier; 3480 setDecimalSeparatorAlwaysShown(decimalPos == 0 3481 || decimalPos == digitTotalCount); 3482 if (padPos >= 0) { 3483 fPadPosition = (EPadPosition) padPos; 3484 // To compute the format width, first set up sub0Limit - 3485 // sub0Start. Add in prefix/suffix length later. 3486 3487 // fFormatWidth = prefix.length() + suffix.length() + 3488 // sub0Limit - sub0Start; 3489 fFormatWidth = sub0Limit - sub0Start; 3490 fPad = padChar; 3491 } else { 3492 fFormatWidth = 0; 3493 } 3494 if (roundingPos >= 0) { 3495 roundingInc.fDecimalAt = effectiveDecimalPos - roundingPos; 3496 if (fRoundingIncrement != NULL) { 3497 *fRoundingIncrement = roundingInc; 3498 } else { 3499 fRoundingIncrement = new DigitList(roundingInc); 3500 /* test for NULL */ 3501 if (fRoundingIncrement == 0) { 3502 status = U_MEMORY_ALLOCATION_ERROR; 3503 delete fPosPrefixPattern; 3504 delete fPosSuffixPattern; 3505 return; 3506 } 3507 } 3508 fRoundingDouble = fRoundingIncrement->getDouble(); 3509 fRoundingMode = kRoundHalfEven; 3510 } else { 3511 setRoundingIncrement(0.0); 3512 } 3513 } else { 3514 fNegPrefixPattern = new UnicodeString(prefix); 3515 /* test for NULL */ 3516 if (fNegPrefixPattern == 0) { 3517 status = U_MEMORY_ALLOCATION_ERROR; 3518 return; 3519 } 3520 fNegSuffixPattern = new UnicodeString(suffix); 3521 /* test for NULL */ 3522 if (fNegSuffixPattern == 0) { 3523 delete fNegPrefixPattern; 3524 status = U_MEMORY_ALLOCATION_ERROR; 3525 return; 3526 } 3527 } 3528 } 3529 3530 if (pattern.length() == 0) { 3531 delete fNegPrefixPattern; 3532 delete fNegSuffixPattern; 3533 fNegPrefixPattern = NULL; 3534 fNegSuffixPattern = NULL; 3535 if (fPosPrefixPattern != NULL) { 3536 fPosPrefixPattern->remove(); 3537 } else { 3538 fPosPrefixPattern = new UnicodeString(); 3539 /* test for NULL */ 3540 if (fPosPrefixPattern == 0) { 3541 status = U_MEMORY_ALLOCATION_ERROR; 3542 return; 3543 } 3544 } 3545 if (fPosSuffixPattern != NULL) { 3546 fPosSuffixPattern->remove(); 3547 } else { 3548 fPosSuffixPattern = new UnicodeString(); 3549 /* test for NULL */ 3550 if (fPosSuffixPattern == 0) { 3551 delete fPosPrefixPattern; 3552 status = U_MEMORY_ALLOCATION_ERROR; 3553 return; 3554 } 3555 } 3556 3557 setMinimumIntegerDigits(0); 3558 setMaximumIntegerDigits(kDoubleIntegerDigits); 3559 setMinimumFractionDigits(0); 3560 setMaximumFractionDigits(kDoubleFractionDigits); 3561 3562 fUseExponentialNotation = FALSE; 3563 fIsCurrencyFormat = FALSE; 3564 setGroupingUsed(FALSE); 3565 fGroupingSize = 0; 3566 fGroupingSize2 = 0; 3567 fMultiplier = 1; 3568 setDecimalSeparatorAlwaysShown(FALSE); 3569 fFormatWidth = 0; 3570 setRoundingIncrement(0.0); 3571 } 3572 3573 // If there was no negative pattern, or if the negative pattern is 3574 // identical to the positive pattern, then prepend the minus sign to the 3575 // positive pattern to form the negative pattern. 3576 if (fNegPrefixPattern == NULL || 3577 (*fNegPrefixPattern == *fPosPrefixPattern 3578 && *fNegSuffixPattern == *fPosSuffixPattern)) { 3579 _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern); 3580 if (fNegPrefixPattern == NULL) { 3581 fNegPrefixPattern = new UnicodeString(); 3582 /* test for NULL */ 3583 if (fNegPrefixPattern == 0) { 3584 status = U_MEMORY_ALLOCATION_ERROR; 3585 return; 3586 } 3587 } else { 3588 fNegPrefixPattern->remove(); 3589 } 3590 fNegPrefixPattern->append(kQuote).append(kPatternMinus) 3591 .append(*fPosPrefixPattern); 3592 } 3593#ifdef FMT_DEBUG 3594 UnicodeString s; 3595 s.append("\"").append(pattern).append("\"->"); 3596 debugout(s); 3597#endif 3598 expandAffixes(); 3599 if (fFormatWidth > 0) { 3600 // Finish computing format width (see above) 3601 fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length(); 3602 } 3603} 3604 3605/** 3606 * Sets the maximum number of digits allowed in the integer portion of a 3607 * number. This override limits the integer digit count to 309. 3608 * @see NumberFormat#setMaximumIntegerDigits 3609 */ 3610void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { 3611 NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits)); 3612} 3613 3614/** 3615 * Sets the minimum number of digits allowed in the integer portion of a 3616 * number. This override limits the integer digit count to 309. 3617 * @see NumberFormat#setMinimumIntegerDigits 3618 */ 3619void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { 3620 NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits)); 3621} 3622 3623/** 3624 * Sets the maximum number of digits allowed in the fraction portion of a 3625 * number. This override limits the fraction digit count to 340. 3626 * @see NumberFormat#setMaximumFractionDigits 3627 */ 3628void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { 3629 NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits)); 3630} 3631 3632/** 3633 * Sets the minimum number of digits allowed in the fraction portion of a 3634 * number. This override limits the fraction digit count to 340. 3635 * @see NumberFormat#setMinimumFractionDigits 3636 */ 3637void DecimalFormat::setMinimumFractionDigits(int32_t newValue) { 3638 NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits)); 3639} 3640 3641int32_t DecimalFormat::getMinimumSignificantDigits() const { 3642 return fMinSignificantDigits; 3643} 3644 3645int32_t DecimalFormat::getMaximumSignificantDigits() const { 3646 return fMaxSignificantDigits; 3647} 3648 3649void DecimalFormat::setMinimumSignificantDigits(int32_t min) { 3650 if (min < 1) { 3651 min = 1; 3652 } 3653 // pin max sig dig to >= min 3654 int32_t max = _max(fMaxSignificantDigits, min); 3655 fMinSignificantDigits = min; 3656 fMaxSignificantDigits = max; 3657} 3658 3659void DecimalFormat::setMaximumSignificantDigits(int32_t max) { 3660 if (max < 1) { 3661 max = 1; 3662 } 3663 // pin min sig dig to 1..max 3664 U_ASSERT(fMinSignificantDigits >= 1); 3665 int32_t min = _min(fMinSignificantDigits, max); 3666 fMinSignificantDigits = min; 3667 fMaxSignificantDigits = max; 3668} 3669 3670UBool DecimalFormat::areSignificantDigitsUsed() const { 3671 return fUseSignificantDigits; 3672} 3673 3674void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) { 3675 fUseSignificantDigits = useSignificantDigits; 3676} 3677 3678void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) { 3679 // If we are a currency format, then modify our affixes to 3680 // encode the currency symbol for the given currency in our 3681 // locale, and adjust the decimal digits and rounding for the 3682 // given currency. 3683 3684 // Note: The code is ordered so that this object is *not changed* 3685 // until we are sure we are going to succeed. 3686 3687 // NULL or empty currency is *legal* and indicates no currency. 3688 UBool isCurr = (theCurrency && *theCurrency); 3689 3690 double rounding = 0.0; 3691 int32_t frac = 0; 3692 if (fIsCurrencyFormat && isCurr) { 3693 rounding = ucurr_getRoundingIncrement(theCurrency, &ec); 3694 frac = ucurr_getDefaultFractionDigits(theCurrency, &ec); 3695 } 3696 3697 NumberFormat::setCurrency(theCurrency, ec); 3698 if (U_FAILURE(ec)) return; 3699 3700 if (fIsCurrencyFormat) { 3701 // NULL or empty currency is *legal* and indicates no currency. 3702 if (isCurr) { 3703 setRoundingIncrement(rounding); 3704 setMinimumFractionDigits(frac); 3705 setMaximumFractionDigits(frac); 3706 } 3707 expandAffixes(); 3708 } 3709} 3710 3711// Deprecated variant with no UErrorCode parameter 3712void DecimalFormat::setCurrency(const UChar* theCurrency) { 3713 UErrorCode ec = U_ZERO_ERROR; 3714 setCurrency(theCurrency, ec); 3715} 3716 3717void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& /*ec*/) const { 3718 const UChar* c = getCurrency(); 3719 if (*c == 0) { 3720 const UnicodeString &intl = 3721 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 3722 c = intl.getBuffer(); // ok for intl to go out of scope 3723 } 3724 u_strncpy(result, c, 3); 3725 result[3] = 0; 3726} 3727 3728/** 3729 * Return the number of fraction digits to display, or the total 3730 * number of digits for significant digit formats and exponential 3731 * formats. 3732 */ 3733int32_t 3734DecimalFormat::precision(UBool isIntegral) const { 3735 if (areSignificantDigitsUsed()) { 3736 return getMaximumSignificantDigits(); 3737 } else if (fUseExponentialNotation) { 3738 return getMinimumIntegerDigits() + getMaximumFractionDigits(); 3739 } else { 3740 return isIntegral ? 0 : getMaximumFractionDigits(); 3741 } 3742} 3743 3744U_NAMESPACE_END 3745 3746#endif /* #if !UCONFIG_NO_FORMATTING */ 3747 3748//eof 3749