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