1 /* 2 ******************************************************************************* 3 * Copyright (C) 1997-2011, 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 "fphdlimp.h" 45 #include "unicode/decimfmt.h" 46 #include "unicode/choicfmt.h" 47 #include "unicode/ucurr.h" 48 #include "unicode/ustring.h" 49 #include "unicode/dcfmtsym.h" 50 #include "unicode/ures.h" 51 #include "unicode/uchar.h" 52 #include "unicode/uniset.h" 53 #include "unicode/curramt.h" 54 #include "unicode/currpinf.h" 55 #include "unicode/plurrule.h" 56 #include "uresimp.h" 57 #include "ucurrimp.h" 58 #include "charstr.h" 59 #include "cmemory.h" 60 #include "patternprops.h" 61 #include "digitlst.h" 62 #include "cstring.h" 63 #include "umutex.h" 64 #include "uassert.h" 65 #include "putilimp.h" 66 #include <math.h> 67 #include "hash.h" 68 #include "decfmtst.h" 69 70 71 U_NAMESPACE_BEGIN 72 73 /* For currency parsing purose, 74 * Need to remember all prefix patterns and suffix patterns of 75 * every currency format pattern, 76 * including the pattern of default currecny style 77 * and plural currency style. And the patterns are set through applyPattern. 78 */ 79 struct AffixPatternsForCurrency : public UMemory { 80 // negative prefix pattern 81 UnicodeString negPrefixPatternForCurrency; 82 // negative suffix pattern 83 UnicodeString negSuffixPatternForCurrency; 84 // positive prefix pattern 85 UnicodeString posPrefixPatternForCurrency; 86 // positive suffix pattern 87 UnicodeString posSuffixPatternForCurrency; 88 int8_t patternType; 89 90 AffixPatternsForCurrency(const UnicodeString& negPrefix, 91 const UnicodeString& negSuffix, 92 const UnicodeString& posPrefix, 93 const UnicodeString& posSuffix, 94 int8_t type) { 95 negPrefixPatternForCurrency = negPrefix; 96 negSuffixPatternForCurrency = negSuffix; 97 posPrefixPatternForCurrency = posPrefix; 98 posSuffixPatternForCurrency = posSuffix; 99 patternType = type; 100 } 101 }; 102 103 /* affix for currency formatting when the currency sign in the pattern 104 * equals to 3, such as the pattern contains 3 currency sign or 105 * the formatter style is currency plural format style. 106 */ 107 struct AffixesForCurrency : public UMemory { 108 // negative prefix 109 UnicodeString negPrefixForCurrency; 110 // negative suffix 111 UnicodeString negSuffixForCurrency; 112 // positive prefix 113 UnicodeString posPrefixForCurrency; 114 // positive suffix 115 UnicodeString posSuffixForCurrency; 116 117 int32_t formatWidth; 118 119 AffixesForCurrency(const UnicodeString& negPrefix, 120 const UnicodeString& negSuffix, 121 const UnicodeString& posPrefix, 122 const UnicodeString& posSuffix) { 123 negPrefixForCurrency = negPrefix; 124 negSuffixForCurrency = negSuffix; 125 posPrefixForCurrency = posPrefix; 126 posSuffixForCurrency = posSuffix; 127 } 128 }; 129 130 U_CDECL_BEGIN 131 132 /** 133 * @internal ICU 4.2 134 */ 135 static UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2); 136 137 /** 138 * @internal ICU 4.2 139 */ 140 static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2); 141 142 143 static UBool 144 U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2) { 145 const AffixesForCurrency* affix_1 = 146 (AffixesForCurrency*)val1.pointer; 147 const AffixesForCurrency* affix_2 = 148 (AffixesForCurrency*)val2.pointer; 149 return affix_1->negPrefixForCurrency == affix_2->negPrefixForCurrency && 150 affix_1->negSuffixForCurrency == affix_2->negSuffixForCurrency && 151 affix_1->posPrefixForCurrency == affix_2->posPrefixForCurrency && 152 affix_1->posSuffixForCurrency == affix_2->posSuffixForCurrency; 153 } 154 155 156 static UBool 157 U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) { 158 const AffixPatternsForCurrency* affix_1 = 159 (AffixPatternsForCurrency*)val1.pointer; 160 const AffixPatternsForCurrency* affix_2 = 161 (AffixPatternsForCurrency*)val2.pointer; 162 return affix_1->negPrefixPatternForCurrency == 163 affix_2->negPrefixPatternForCurrency && 164 affix_1->negSuffixPatternForCurrency == 165 affix_2->negSuffixPatternForCurrency && 166 affix_1->posPrefixPatternForCurrency == 167 affix_2->posPrefixPatternForCurrency && 168 affix_1->posSuffixPatternForCurrency == 169 affix_2->posSuffixPatternForCurrency && 170 affix_1->patternType == affix_2->patternType; 171 } 172 173 U_CDECL_END 174 175 176 //#define FMT_DEBUG 177 178 #ifdef FMT_DEBUG 179 #include <stdio.h> 180 static void debugout(UnicodeString s) { 181 char buf[2000]; 182 s.extract((int32_t) 0, s.length(), buf); 183 printf("%s\n", buf); 184 } 185 #define debug(x) printf("%s\n", x); 186 #else 187 #define debugout(x) 188 #define debug(x) 189 #endif 190 191 192 193 // ***************************************************************************** 194 // class DecimalFormat 195 // ***************************************************************************** 196 197 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat) 198 199 // Constants for characters used in programmatic (unlocalized) patterns. 200 #define kPatternZeroDigit ((UChar)0x0030) /*'0'*/ 201 #define kPatternSignificantDigit ((UChar)0x0040) /*'@'*/ 202 #define kPatternGroupingSeparator ((UChar)0x002C) /*','*/ 203 #define kPatternDecimalSeparator ((UChar)0x002E) /*'.'*/ 204 #define kPatternPerMill ((UChar)0x2030) 205 #define kPatternPercent ((UChar)0x0025) /*'%'*/ 206 #define kPatternDigit ((UChar)0x0023) /*'#'*/ 207 #define kPatternSeparator ((UChar)0x003B) /*';'*/ 208 #define kPatternExponent ((UChar)0x0045) /*'E'*/ 209 #define kPatternPlus ((UChar)0x002B) /*'+'*/ 210 #define kPatternMinus ((UChar)0x002D) /*'-'*/ 211 #define kPatternPadEscape ((UChar)0x002A) /*'*'*/ 212 #define kQuote ((UChar)0x0027) /*'\''*/ 213 /** 214 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It 215 * is used in patterns and substitued with either the currency symbol, 216 * or if it is doubled, with the international currency symbol. If the 217 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is 218 * replaced with the monetary decimal separator. 219 */ 220 #define kCurrencySign ((UChar)0x00A4) 221 #define kDefaultPad ((UChar)0x0020) /* */ 222 223 const int32_t DecimalFormat::kDoubleIntegerDigits = 309; 224 const int32_t DecimalFormat::kDoubleFractionDigits = 340; 225 226 const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8; 227 228 /** 229 * These are the tags we expect to see in normal resource bundle files associated 230 * with a locale. 231 */ 232 const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used 233 static const char fgNumberElements[]="NumberElements"; 234 static const char fgLatn[]="latn"; 235 static const char fgPatterns[]="patterns"; 236 static const char fgDecimalFormat[]="decimalFormat"; 237 static const char fgCurrencyFormat[]="currencyFormat"; 238 static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0}; 239 240 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; } 241 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; } 242 243 //------------------------------------------------------------------------------ 244 // Constructs a DecimalFormat instance in the default locale. 245 246 DecimalFormat::DecimalFormat(UErrorCode& status) { 247 init(); 248 UParseError parseError; 249 construct(status, parseError); 250 } 251 252 //------------------------------------------------------------------------------ 253 // Constructs a DecimalFormat instance with the specified number format 254 // pattern in the default locale. 255 256 DecimalFormat::DecimalFormat(const UnicodeString& pattern, 257 UErrorCode& status) { 258 init(); 259 UParseError parseError; 260 construct(status, parseError, &pattern); 261 } 262 263 //------------------------------------------------------------------------------ 264 // Constructs a DecimalFormat instance with the specified number format 265 // pattern and the number format symbols in the default locale. The 266 // created instance owns the symbols. 267 268 DecimalFormat::DecimalFormat(const UnicodeString& pattern, 269 DecimalFormatSymbols* symbolsToAdopt, 270 UErrorCode& status) { 271 init(); 272 UParseError parseError; 273 if (symbolsToAdopt == NULL) 274 status = U_ILLEGAL_ARGUMENT_ERROR; 275 construct(status, parseError, &pattern, symbolsToAdopt); 276 } 277 278 DecimalFormat::DecimalFormat( const UnicodeString& pattern, 279 DecimalFormatSymbols* symbolsToAdopt, 280 UParseError& parseErr, 281 UErrorCode& status) { 282 init(); 283 if (symbolsToAdopt == NULL) 284 status = U_ILLEGAL_ARGUMENT_ERROR; 285 construct(status,parseErr, &pattern, symbolsToAdopt); 286 } 287 288 //------------------------------------------------------------------------------ 289 // Constructs a DecimalFormat instance with the specified number format 290 // pattern and the number format symbols in the default locale. The 291 // created instance owns the clone of the symbols. 292 293 DecimalFormat::DecimalFormat(const UnicodeString& pattern, 294 const DecimalFormatSymbols& symbols, 295 UErrorCode& status) { 296 init(); 297 UParseError parseError; 298 construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols)); 299 } 300 301 //------------------------------------------------------------------------------ 302 // Constructs a DecimalFormat instance with the specified number format 303 // pattern, the number format symbols, and the number format style. 304 // The created instance owns the clone of the symbols. 305 306 DecimalFormat::DecimalFormat(const UnicodeString& pattern, 307 DecimalFormatSymbols* symbolsToAdopt, 308 UNumberFormatStyle style, 309 UErrorCode& status) { 310 init(); 311 fStyle = style; 312 UParseError parseError; 313 construct(status, parseError, &pattern, symbolsToAdopt); 314 } 315 316 //----------------------------------------------------------------------------- 317 // Common DecimalFormat initialization. 318 // Put all fields of an uninitialized object into a known state. 319 // Common code, shared by all constructors. 320 void 321 DecimalFormat::init() { 322 fPosPrefixPattern = 0; 323 fPosSuffixPattern = 0; 324 fNegPrefixPattern = 0; 325 fNegSuffixPattern = 0; 326 fCurrencyChoice = 0; 327 fMultiplier = NULL; 328 fGroupingSize = 0; 329 fGroupingSize2 = 0; 330 fDecimalSeparatorAlwaysShown = FALSE; 331 fSymbols = NULL; 332 fUseSignificantDigits = FALSE; 333 fMinSignificantDigits = 1; 334 fMaxSignificantDigits = 6; 335 fUseExponentialNotation = FALSE; 336 fMinExponentDigits = 0; 337 fExponentSignAlwaysShown = FALSE; 338 fRoundingIncrement = 0; 339 fRoundingMode = kRoundHalfEven; 340 fPad = 0; 341 fFormatWidth = 0; 342 fPadPosition = kPadBeforePrefix; 343 fStyle = UNUM_DECIMAL; 344 fCurrencySignCount = 0; 345 fAffixPatternsForCurrency = NULL; 346 fAffixesForCurrency = NULL; 347 fPluralAffixesForCurrency = NULL; 348 fCurrencyPluralInfo = NULL; 349 } 350 351 //------------------------------------------------------------------------------ 352 // Constructs a DecimalFormat instance with the specified number format 353 // pattern and the number format symbols in the desired locale. The 354 // created instance owns the symbols. 355 356 void 357 DecimalFormat::construct(UErrorCode& status, 358 UParseError& parseErr, 359 const UnicodeString* pattern, 360 DecimalFormatSymbols* symbolsToAdopt) 361 { 362 fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!! 363 fRoundingIncrement = NULL; 364 fRoundingMode = kRoundHalfEven; 365 fPad = kPatternPadEscape; 366 fPadPosition = kPadBeforePrefix; 367 if (U_FAILURE(status)) 368 return; 369 370 fPosPrefixPattern = fPosSuffixPattern = NULL; 371 fNegPrefixPattern = fNegSuffixPattern = NULL; 372 setMultiplier(1); 373 fGroupingSize = 3; 374 fGroupingSize2 = 0; 375 fDecimalSeparatorAlwaysShown = FALSE; 376 fUseExponentialNotation = FALSE; 377 fMinExponentDigits = 0; 378 379 if (fSymbols == NULL) 380 { 381 fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status); 382 /* test for NULL */ 383 if (fSymbols == 0) { 384 status = U_MEMORY_ALLOCATION_ERROR; 385 return; 386 } 387 } 388 389 UnicodeString str; 390 // Uses the default locale's number format pattern if there isn't 391 // one specified. 392 if (pattern == NULL) 393 { 394 int32_t len = 0; 395 UResourceBundle *resource = ures_open(NULL, Locale::getDefault().getName(), &status); 396 397 resource = ures_getByKeyWithFallback(resource, fgNumberElements, resource, &status); 398 // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn". 399 resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &status); 400 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &status); 401 const UChar *resStr = ures_getStringByKeyWithFallback(resource, fgDecimalFormat, &len, &status); 402 str.setTo(TRUE, resStr, len); 403 pattern = &str; 404 ures_close(resource); 405 } 406 407 if (U_FAILURE(status)) 408 { 409 return; 410 } 411 412 if (pattern->indexOf((UChar)kCurrencySign) >= 0) { 413 // If it looks like we are going to use a currency pattern 414 // then do the time consuming lookup. 415 setCurrencyForSymbols(); 416 } else { 417 setCurrencyInternally(NULL, status); 418 } 419 420 const UnicodeString* patternUsed; 421 UnicodeString currencyPluralPatternForOther; 422 // apply pattern 423 if (fStyle == UNUM_CURRENCY_PLURAL) { 424 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status); 425 if (U_FAILURE(status)) { 426 return; 427 } 428 429 // the pattern used in format is not fixed until formatting, 430 // in which, the number is known and 431 // will be used to pick the right pattern based on plural count. 432 // Here, set the pattern as the pattern of plural count == "other". 433 // For most locale, the patterns are probably the same for all 434 // plural count. If not, the right pattern need to be re-applied 435 // during format. 436 fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5), currencyPluralPatternForOther); 437 patternUsed = ¤cyPluralPatternForOther; 438 // TODO: not needed? 439 setCurrencyForSymbols(); 440 441 } else { 442 patternUsed = pattern; 443 } 444 445 if (patternUsed->indexOf(kCurrencySign) != -1) { 446 // initialize for currency, not only for plural format, 447 // but also for mix parsing 448 if (fCurrencyPluralInfo == NULL) { 449 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status); 450 if (U_FAILURE(status)) { 451 return; 452 } 453 } 454 // need it for mix parsing 455 setupCurrencyAffixPatterns(status); 456 // expanded affixes for plural names 457 if (patternUsed->indexOf(fgTripleCurrencySign, 3, 0) != -1) { 458 setupCurrencyAffixes(*patternUsed, TRUE, TRUE, status); 459 } 460 } 461 462 applyPatternWithoutExpandAffix(*patternUsed,FALSE, parseErr, status); 463 464 // expand affixes 465 if (fCurrencySignCount != fgCurrencySignCountInPluralFormat) { 466 expandAffixAdjustWidth(NULL); 467 } 468 469 // If it was a currency format, apply the appropriate rounding by 470 // resetting the currency. NOTE: this copies fCurrency on top of itself. 471 if (fCurrencySignCount > fgCurrencySignCountZero) { 472 setCurrencyInternally(getCurrency(), status); 473 } 474 } 475 476 477 void 478 DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { 479 if (U_FAILURE(status)) { 480 return; 481 } 482 UParseError parseErr; 483 fAffixPatternsForCurrency = initHashForAffixPattern(status); 484 if (U_FAILURE(status)) { 485 return; 486 } 487 488 // Save the default currency patterns of this locale. 489 // Here, chose onlyApplyPatternWithoutExpandAffix without 490 // expanding the affix patterns into affixes. 491 UnicodeString currencyPattern; 492 UErrorCode error = U_ZERO_ERROR; 493 494 UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(), &error); 495 resource = ures_getByKeyWithFallback(resource, fgNumberElements, resource, &error); 496 // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn". 497 resource = ures_getByKeyWithFallback(resource, fgLatn, resource, &error); 498 resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error); 499 int32_t patLen = 0; 500 const UChar *patResStr = ures_getStringByKeyWithFallback(resource, fgCurrencyFormat, &patLen, &error); 501 ures_close(resource); 502 503 if (U_SUCCESS(error)) { 504 applyPatternWithoutExpandAffix(UnicodeString(patResStr, patLen), false, 505 parseErr, status); 506 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( 507 *fNegPrefixPattern, 508 *fNegSuffixPattern, 509 *fPosPrefixPattern, 510 *fPosSuffixPattern, 511 UCURR_SYMBOL_NAME); 512 fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, status); 513 } 514 515 // save the unique currency plural patterns of this locale. 516 Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern; 517 const UHashElement* element = NULL; 518 int32_t pos = -1; 519 Hashtable pluralPatternSet; 520 while ((element = pluralPtn->nextElement(pos)) != NULL) { 521 const UHashTok valueTok = element->value; 522 const UnicodeString* value = (UnicodeString*)valueTok.pointer; 523 const UHashTok keyTok = element->key; 524 const UnicodeString* key = (UnicodeString*)keyTok.pointer; 525 if (pluralPatternSet.geti(*value) != 1) { 526 pluralPatternSet.puti(*value, 1, status); 527 applyPatternWithoutExpandAffix(*value, false, parseErr, status); 528 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( 529 *fNegPrefixPattern, 530 *fNegSuffixPattern, 531 *fPosPrefixPattern, 532 *fPosSuffixPattern, 533 UCURR_LONG_NAME); 534 fAffixPatternsForCurrency->put(*key, affixPtn, status); 535 } 536 } 537 } 538 539 540 void 541 DecimalFormat::setupCurrencyAffixes(const UnicodeString& pattern, 542 UBool setupForCurrentPattern, 543 UBool setupForPluralPattern, 544 UErrorCode& status) { 545 if (U_FAILURE(status)) { 546 return; 547 } 548 UParseError parseErr; 549 if (setupForCurrentPattern) { 550 if (fAffixesForCurrency) { 551 deleteHashForAffix(fAffixesForCurrency); 552 } 553 fAffixesForCurrency = initHashForAffix(status); 554 if (U_SUCCESS(status)) { 555 applyPatternWithoutExpandAffix(pattern, false, parseErr, status); 556 const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules(); 557 StringEnumeration* keywords = pluralRules->getKeywords(status); 558 if (U_SUCCESS(status)) { 559 const UnicodeString* pluralCount; 560 while ((pluralCount = keywords->snext(status)) != NULL) { 561 if ( U_SUCCESS(status) ) { 562 expandAffixAdjustWidth(pluralCount); 563 AffixesForCurrency* affix = new AffixesForCurrency( 564 fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix); 565 fAffixesForCurrency->put(*pluralCount, affix, status); 566 } 567 } 568 } 569 delete keywords; 570 } 571 } 572 573 if (U_FAILURE(status)) { 574 return; 575 } 576 577 if (setupForPluralPattern) { 578 if (fPluralAffixesForCurrency) { 579 deleteHashForAffix(fPluralAffixesForCurrency); 580 } 581 fPluralAffixesForCurrency = initHashForAffix(status); 582 if (U_SUCCESS(status)) { 583 const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules(); 584 StringEnumeration* keywords = pluralRules->getKeywords(status); 585 if (U_SUCCESS(status)) { 586 const UnicodeString* pluralCount; 587 while ((pluralCount = keywords->snext(status)) != NULL) { 588 if ( U_SUCCESS(status) ) { 589 UnicodeString ptn; 590 fCurrencyPluralInfo->getCurrencyPluralPattern(*pluralCount, ptn); 591 applyPatternInternally(*pluralCount, ptn, false, parseErr, status); 592 AffixesForCurrency* affix = new AffixesForCurrency( 593 fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix); 594 fPluralAffixesForCurrency->put(*pluralCount, affix, status); 595 } 596 } 597 } 598 delete keywords; 599 } 600 } 601 } 602 603 604 //------------------------------------------------------------------------------ 605 606 DecimalFormat::~DecimalFormat() 607 { 608 delete fPosPrefixPattern; 609 delete fPosSuffixPattern; 610 delete fNegPrefixPattern; 611 delete fNegSuffixPattern; 612 delete fCurrencyChoice; 613 delete fMultiplier; 614 delete fSymbols; 615 delete fRoundingIncrement; 616 deleteHashForAffixPattern(); 617 deleteHashForAffix(fAffixesForCurrency); 618 deleteHashForAffix(fPluralAffixesForCurrency); 619 delete fCurrencyPluralInfo; 620 } 621 622 //------------------------------------------------------------------------------ 623 // copy constructor 624 625 DecimalFormat::DecimalFormat(const DecimalFormat &source) : 626 NumberFormat(source) { 627 init(); 628 *this = source; 629 } 630 631 //------------------------------------------------------------------------------ 632 // assignment operator 633 634 static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) { 635 if (source == NULL) { 636 delete *pdest; 637 *pdest = NULL; 638 } else if (*pdest == NULL) { 639 *pdest = new UnicodeString(*source); 640 } else { 641 **pdest = *source; 642 } 643 } 644 645 DecimalFormat& 646 DecimalFormat::operator=(const DecimalFormat& rhs) 647 { 648 if(this != &rhs) { 649 NumberFormat::operator=(rhs); 650 fPositivePrefix = rhs.fPositivePrefix; 651 fPositiveSuffix = rhs.fPositiveSuffix; 652 fNegativePrefix = rhs.fNegativePrefix; 653 fNegativeSuffix = rhs.fNegativeSuffix; 654 _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern); 655 _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern); 656 _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern); 657 _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern); 658 if (rhs.fCurrencyChoice == 0) { 659 delete fCurrencyChoice; 660 fCurrencyChoice = 0; 661 } else { 662 fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone(); 663 } 664 setRoundingIncrement(rhs.getRoundingIncrement()); 665 fRoundingMode = rhs.fRoundingMode; 666 setMultiplier(rhs.getMultiplier()); 667 fGroupingSize = rhs.fGroupingSize; 668 fGroupingSize2 = rhs.fGroupingSize2; 669 fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown; 670 if(fSymbols == NULL) { 671 fSymbols = new DecimalFormatSymbols(*rhs.fSymbols); 672 } else { 673 *fSymbols = *rhs.fSymbols; 674 } 675 fUseExponentialNotation = rhs.fUseExponentialNotation; 676 fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown; 677 /*Bertrand A. D. Update 98.03.17*/ 678 fCurrencySignCount = rhs.fCurrencySignCount; 679 /*end of Update*/ 680 fMinExponentDigits = rhs.fMinExponentDigits; 681 682 /* sfb 990629 */ 683 fFormatWidth = rhs.fFormatWidth; 684 fPad = rhs.fPad; 685 fPadPosition = rhs.fPadPosition; 686 /* end sfb */ 687 fMinSignificantDigits = rhs.fMinSignificantDigits; 688 fMaxSignificantDigits = rhs.fMaxSignificantDigits; 689 fUseSignificantDigits = rhs.fUseSignificantDigits; 690 fFormatPattern = rhs.fFormatPattern; 691 fStyle = rhs.fStyle; 692 fCurrencySignCount = rhs.fCurrencySignCount; 693 if (rhs.fCurrencyPluralInfo) { 694 delete fCurrencyPluralInfo; 695 fCurrencyPluralInfo = rhs.fCurrencyPluralInfo->clone(); 696 } 697 if (rhs.fAffixPatternsForCurrency) { 698 UErrorCode status = U_ZERO_ERROR; 699 deleteHashForAffixPattern(); 700 fAffixPatternsForCurrency = initHashForAffixPattern(status); 701 copyHashForAffixPattern(rhs.fAffixPatternsForCurrency, 702 fAffixPatternsForCurrency, status); 703 } 704 if (rhs.fAffixesForCurrency) { 705 UErrorCode status = U_ZERO_ERROR; 706 deleteHashForAffix(fAffixesForCurrency); 707 fAffixesForCurrency = initHashForAffixPattern(status); 708 copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, status); 709 } 710 if (rhs.fPluralAffixesForCurrency) { 711 UErrorCode status = U_ZERO_ERROR; 712 deleteHashForAffix(fPluralAffixesForCurrency); 713 fPluralAffixesForCurrency = initHashForAffixPattern(status); 714 copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCurrency, status); 715 } 716 } 717 return *this; 718 } 719 720 //------------------------------------------------------------------------------ 721 722 UBool 723 DecimalFormat::operator==(const Format& that) const 724 { 725 if (this == &that) 726 return TRUE; 727 728 // NumberFormat::operator== guarantees this cast is safe 729 const DecimalFormat* other = (DecimalFormat*)&that; 730 731 #ifdef FMT_DEBUG 732 // This code makes it easy to determine why two format objects that should 733 // be equal aren't. 734 UBool first = TRUE; 735 if (!NumberFormat::operator==(that)) { 736 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 737 debug("NumberFormat::!="); 738 } else { 739 if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null 740 fPositivePrefix == other->fPositivePrefix) 741 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && 742 *fPosPrefixPattern == *other->fPosPrefixPattern))) { 743 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 744 debug("Pos Prefix !="); 745 } 746 if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null 747 fPositiveSuffix == other->fPositiveSuffix) 748 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && 749 *fPosSuffixPattern == *other->fPosSuffixPattern))) { 750 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 751 debug("Pos Suffix !="); 752 } 753 if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null 754 fNegativePrefix == other->fNegativePrefix) 755 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && 756 *fNegPrefixPattern == *other->fNegPrefixPattern))) { 757 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 758 debug("Neg Prefix "); 759 if (fNegPrefixPattern == NULL) { 760 debug("NULL("); 761 debugout(fNegativePrefix); 762 debug(")"); 763 } else { 764 debugout(*fNegPrefixPattern); 765 } 766 debug(" != "); 767 if (other->fNegPrefixPattern == NULL) { 768 debug("NULL("); 769 debugout(other->fNegativePrefix); 770 debug(")"); 771 } else { 772 debugout(*other->fNegPrefixPattern); 773 } 774 } 775 if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null 776 fNegativeSuffix == other->fNegativeSuffix) 777 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && 778 *fNegSuffixPattern == *other->fNegSuffixPattern))) { 779 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 780 debug("Neg Suffix "); 781 if (fNegSuffixPattern == NULL) { 782 debug("NULL("); 783 debugout(fNegativeSuffix); 784 debug(")"); 785 } else { 786 debugout(*fNegSuffixPattern); 787 } 788 debug(" != "); 789 if (other->fNegSuffixPattern == NULL) { 790 debug("NULL("); 791 debugout(other->fNegativeSuffix); 792 debug(")"); 793 } else { 794 debugout(*other->fNegSuffixPattern); 795 } 796 } 797 if (!((fRoundingIncrement == other->fRoundingIncrement) // both null 798 || (fRoundingIncrement != NULL && 799 other->fRoundingIncrement != NULL && 800 *fRoundingIncrement == *other->fRoundingIncrement))) { 801 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 802 debug("Rounding Increment !="); 803 } 804 if (getMultiplier() != other->getMultiplier()) { 805 if (first) { printf("[ "); first = FALSE; } 806 printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier()); 807 } 808 if (fGroupingSize != other->fGroupingSize) { 809 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 810 printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize); 811 } 812 if (fGroupingSize2 != other->fGroupingSize2) { 813 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 814 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2); 815 } 816 if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) { 817 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 818 printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown); 819 } 820 if (fUseExponentialNotation != other->fUseExponentialNotation) { 821 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 822 debug("Use Exp !="); 823 } 824 if (!(!fUseExponentialNotation || 825 fMinExponentDigits != other->fMinExponentDigits)) { 826 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 827 debug("Exp Digits !="); 828 } 829 if (*fSymbols != *(other->fSymbols)) { 830 if (first) { printf("[ "); first = FALSE; } else { printf(", "); } 831 debug("Symbols !="); 832 } 833 // TODO Add debug stuff for significant digits here 834 if (fUseSignificantDigits != other->fUseSignificantDigits) { 835 debug("fUseSignificantDigits !="); 836 } 837 if (fUseSignificantDigits && 838 fMinSignificantDigits != other->fMinSignificantDigits) { 839 debug("fMinSignificantDigits !="); 840 } 841 if (fUseSignificantDigits && 842 fMaxSignificantDigits != other->fMaxSignificantDigits) { 843 debug("fMaxSignificantDigits !="); 844 } 845 846 if (!first) { printf(" ]"); } 847 if (fCurrencySignCount != other->fCurrencySignCount) { 848 debug("fCurrencySignCount !="); 849 } 850 if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) { 851 debug("fCurrencyPluralInfo == "); 852 if (fCurrencyPluralInfo == NULL) { 853 debug("fCurrencyPluralInfo == NULL"); 854 } 855 } 856 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && 857 *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) { 858 debug("fCurrencyPluralInfo !="); 859 } 860 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL || 861 fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) { 862 debug("fCurrencyPluralInfo one NULL, the other not"); 863 } 864 if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) { 865 debug("fCurrencyPluralInfo == "); 866 } 867 } 868 #endif 869 870 return (NumberFormat::operator==(that) && 871 ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ? 872 (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) : 873 (((fPosPrefixPattern == other->fPosPrefixPattern && // both null 874 fPositivePrefix == other->fPositivePrefix) 875 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && 876 *fPosPrefixPattern == *other->fPosPrefixPattern)) && 877 ((fPosSuffixPattern == other->fPosSuffixPattern && // both null 878 fPositiveSuffix == other->fPositiveSuffix) 879 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && 880 *fPosSuffixPattern == *other->fPosSuffixPattern)) && 881 ((fNegPrefixPattern == other->fNegPrefixPattern && // both null 882 fNegativePrefix == other->fNegativePrefix) 883 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && 884 *fNegPrefixPattern == *other->fNegPrefixPattern)) && 885 ((fNegSuffixPattern == other->fNegSuffixPattern && // both null 886 fNegativeSuffix == other->fNegativeSuffix) 887 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && 888 *fNegSuffixPattern == *other->fNegSuffixPattern)))) && 889 ((fRoundingIncrement == other->fRoundingIncrement) // both null 890 || (fRoundingIncrement != NULL && 891 other->fRoundingIncrement != NULL && 892 *fRoundingIncrement == *other->fRoundingIncrement)) && 893 getMultiplier() == other->getMultiplier() && 894 fGroupingSize == other->fGroupingSize && 895 fGroupingSize2 == other->fGroupingSize2 && 896 fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown && 897 fUseExponentialNotation == other->fUseExponentialNotation && 898 (!fUseExponentialNotation || 899 fMinExponentDigits == other->fMinExponentDigits) && 900 *fSymbols == *(other->fSymbols) && 901 fUseSignificantDigits == other->fUseSignificantDigits && 902 (!fUseSignificantDigits || 903 (fMinSignificantDigits == other->fMinSignificantDigits && 904 fMaxSignificantDigits == other->fMaxSignificantDigits)) && 905 fCurrencySignCount == other->fCurrencySignCount && 906 ((fCurrencyPluralInfo == other->fCurrencyPluralInfo && 907 fCurrencyPluralInfo == NULL) || 908 (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && 909 *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo)))); 910 } 911 912 //------------------------------------------------------------------------------ 913 914 Format* 915 DecimalFormat::clone() const 916 { 917 return new DecimalFormat(*this); 918 } 919 920 //------------------------------------------------------------------------------ 921 922 UnicodeString& 923 DecimalFormat::format(int32_t number, 924 UnicodeString& appendTo, 925 FieldPosition& fieldPosition) const 926 { 927 return format((int64_t)number, appendTo, fieldPosition); 928 } 929 930 UnicodeString& 931 DecimalFormat::format(int32_t number, 932 UnicodeString& appendTo, 933 FieldPositionIterator* posIter, 934 UErrorCode& status) const 935 { 936 return format((int64_t)number, appendTo, posIter, status); 937 } 938 939 //------------------------------------------------------------------------------ 940 941 UnicodeString& 942 DecimalFormat::format(int64_t number, 943 UnicodeString& appendTo, 944 FieldPosition& fieldPosition) const 945 { 946 FieldPositionOnlyHandler handler(fieldPosition); 947 return _format(number, appendTo, handler); 948 } 949 950 UnicodeString& 951 DecimalFormat::format(int64_t number, 952 UnicodeString& appendTo, 953 FieldPositionIterator* posIter, 954 UErrorCode& status) const 955 { 956 FieldPositionIteratorHandler handler(posIter, status); 957 return _format(number, appendTo, handler); 958 } 959 960 UnicodeString& 961 DecimalFormat::_format(int64_t number, 962 UnicodeString& appendTo, 963 FieldPositionHandler& handler) const 964 { 965 UErrorCode status = U_ZERO_ERROR; 966 DigitList digits; 967 digits.set(number); 968 return _format(digits, appendTo, handler, status); 969 } 970 971 //------------------------------------------------------------------------------ 972 973 UnicodeString& 974 DecimalFormat::format( double number, 975 UnicodeString& appendTo, 976 FieldPosition& fieldPosition) const 977 { 978 FieldPositionOnlyHandler handler(fieldPosition); 979 return _format(number, appendTo, handler); 980 } 981 982 UnicodeString& 983 DecimalFormat::format( double number, 984 UnicodeString& appendTo, 985 FieldPositionIterator* posIter, 986 UErrorCode& status) const 987 { 988 FieldPositionIteratorHandler handler(posIter, status); 989 return _format(number, appendTo, handler); 990 } 991 992 UnicodeString& 993 DecimalFormat::_format( double number, 994 UnicodeString& appendTo, 995 FieldPositionHandler& handler) const 996 { 997 // Special case for NaN, sets the begin and end index to be the 998 // the string length of localized name of NaN. 999 // TODO: let NaNs go through DigitList. 1000 if (uprv_isNaN(number)) 1001 { 1002 int begin = appendTo.length(); 1003 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); 1004 1005 handler.addAttribute(kIntegerField, begin, appendTo.length()); 1006 1007 addPadding(appendTo, handler, 0, 0); 1008 return appendTo; 1009 } 1010 1011 UErrorCode status = U_ZERO_ERROR; 1012 DigitList digits; 1013 digits.set(number); 1014 _format(digits, appendTo, handler, status); 1015 // No way to return status from here. 1016 return appendTo; 1017 } 1018 1019 //------------------------------------------------------------------------------ 1020 1021 1022 UnicodeString& 1023 DecimalFormat::format(const StringPiece &number, 1024 UnicodeString &toAppendTo, 1025 FieldPositionIterator *posIter, 1026 UErrorCode &status) const 1027 { 1028 DigitList dnum; 1029 dnum.set(number, status); 1030 if (U_FAILURE(status)) { 1031 return toAppendTo; 1032 } 1033 FieldPositionIteratorHandler handler(posIter, status); 1034 _format(dnum, toAppendTo, handler, status); 1035 return toAppendTo; 1036 } 1037 1038 1039 UnicodeString& 1040 DecimalFormat::format(const DigitList &number, 1041 UnicodeString &appendTo, 1042 FieldPositionIterator *posIter, 1043 UErrorCode &status) const { 1044 FieldPositionIteratorHandler handler(posIter, status); 1045 _format(number, appendTo, handler, status); 1046 return appendTo; 1047 } 1048 1049 1050 1051 UnicodeString& 1052 DecimalFormat::format(const DigitList &number, 1053 UnicodeString& appendTo, 1054 FieldPosition& pos, 1055 UErrorCode &status) const { 1056 FieldPositionOnlyHandler handler(pos); 1057 _format(number, appendTo, handler, status); 1058 return appendTo; 1059 } 1060 1061 1062 1063 UnicodeString& 1064 DecimalFormat::_format(const DigitList &number, 1065 UnicodeString& appendTo, 1066 FieldPositionHandler& handler, 1067 UErrorCode &status) const 1068 { 1069 // Special case for NaN, sets the begin and end index to be the 1070 // the string length of localized name of NaN. 1071 if (number.isNaN()) 1072 { 1073 int begin = appendTo.length(); 1074 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); 1075 1076 handler.addAttribute(kIntegerField, begin, appendTo.length()); 1077 1078 addPadding(appendTo, handler, 0, 0); 1079 return appendTo; 1080 } 1081 1082 // Do this BEFORE checking to see if value is infinite or negative! Sets the 1083 // begin and end index to be length of the string composed of 1084 // localized name of Infinite and the positive/negative localized 1085 // signs. 1086 1087 DigitList adjustedNum(number); // Copy, so we do not alter the original. 1088 adjustedNum.setRoundingMode(fRoundingMode); 1089 if (fMultiplier != NULL) { 1090 adjustedNum.mult(*fMultiplier, status); 1091 } 1092 1093 /* 1094 * Note: sign is important for zero as well as non-zero numbers. 1095 * Proper detection of -0.0 is needed to deal with the 1096 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98. 1097 */ 1098 UBool isNegative = !adjustedNum.isPositive(); 1099 1100 // Apply rounding after multiplier 1101 1102 adjustedNum.fContext.status &= ~DEC_Inexact; 1103 if (fRoundingIncrement != NULL) { 1104 adjustedNum.div(*fRoundingIncrement, status); 1105 adjustedNum.toIntegralValue(); 1106 adjustedNum.mult(*fRoundingIncrement, status); 1107 adjustedNum.trim(); 1108 } 1109 if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) { 1110 status = U_FORMAT_INEXACT_ERROR; 1111 return appendTo; 1112 } 1113 1114 1115 // Special case for INFINITE, 1116 if (adjustedNum.isInfinite()) { 1117 int32_t prefixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, TRUE); 1118 1119 int begin = appendTo.length(); 1120 appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); 1121 1122 handler.addAttribute(kIntegerField, begin, appendTo.length()); 1123 1124 int32_t suffixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, FALSE); 1125 1126 addPadding(appendTo, handler, prefixLen, suffixLen); 1127 return appendTo; 1128 } 1129 1130 if (fUseExponentialNotation || areSignificantDigitsUsed()) { 1131 int32_t sigDigits = precision(); 1132 if (sigDigits > 0) { 1133 adjustedNum.round(sigDigits); 1134 } 1135 } else { 1136 // Fixed point format. Round to a set number of fraction digits. 1137 int32_t numFractionDigits = precision(); 1138 adjustedNum.roundFixedPoint(numFractionDigits); 1139 } 1140 if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) { 1141 status = U_FORMAT_INEXACT_ERROR; 1142 return appendTo; 1143 } 1144 1145 return subformat(appendTo, handler, adjustedNum, FALSE); 1146 } 1147 1148 1149 UnicodeString& 1150 DecimalFormat::format( const Formattable& obj, 1151 UnicodeString& appendTo, 1152 FieldPosition& fieldPosition, 1153 UErrorCode& status) const 1154 { 1155 return NumberFormat::format(obj, appendTo, fieldPosition, status); 1156 } 1157 1158 /** 1159 * Return true if a grouping separator belongs at the given 1160 * position, based on whether grouping is in use and the values of 1161 * the primary and secondary grouping interval. 1162 * @param pos the number of integer digits to the right of 1163 * the current position. Zero indicates the position after the 1164 * rightmost integer digit. 1165 * @return true if a grouping character belongs at the current 1166 * position. 1167 */ 1168 UBool DecimalFormat::isGroupingPosition(int32_t pos) const { 1169 UBool result = FALSE; 1170 if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) { 1171 if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) { 1172 result = ((pos - fGroupingSize) % fGroupingSize2) == 0; 1173 } else { 1174 result = pos % fGroupingSize == 0; 1175 } 1176 } 1177 return result; 1178 } 1179 1180 //------------------------------------------------------------------------------ 1181 1182 /** 1183 * Complete the formatting of a finite number. On entry, the DigitList must 1184 * be filled in with the correct digits. 1185 */ 1186 UnicodeString& 1187 DecimalFormat::subformat(UnicodeString& appendTo, 1188 FieldPositionHandler& handler, 1189 DigitList& digits, 1190 UBool isInteger) const 1191 { 1192 // char zero = '0'; 1193 // DigitList returns digits as '0' thru '9', so we will need to 1194 // always need to subtract the character 0 to get the numeric value to use for indexing. 1195 1196 UChar32 localizedDigits[10]; 1197 localizedDigits[0] = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 1198 localizedDigits[1] = getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol).char32At(0); 1199 localizedDigits[2] = getConstSymbol(DecimalFormatSymbols::kTwoDigitSymbol).char32At(0); 1200 localizedDigits[3] = getConstSymbol(DecimalFormatSymbols::kThreeDigitSymbol).char32At(0); 1201 localizedDigits[4] = getConstSymbol(DecimalFormatSymbols::kFourDigitSymbol).char32At(0); 1202 localizedDigits[5] = getConstSymbol(DecimalFormatSymbols::kFiveDigitSymbol).char32At(0); 1203 localizedDigits[6] = getConstSymbol(DecimalFormatSymbols::kSixDigitSymbol).char32At(0); 1204 localizedDigits[7] = getConstSymbol(DecimalFormatSymbols::kSevenDigitSymbol).char32At(0); 1205 localizedDigits[8] = getConstSymbol(DecimalFormatSymbols::kEightDigitSymbol).char32At(0); 1206 localizedDigits[9] = getConstSymbol(DecimalFormatSymbols::kNineDigitSymbol).char32At(0); 1207 1208 const UnicodeString *grouping ; 1209 if(fCurrencySignCount > fgCurrencySignCountZero) { 1210 grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol); 1211 }else{ 1212 grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol); 1213 } 1214 const UnicodeString *decimal; 1215 if(fCurrencySignCount > fgCurrencySignCountZero) { 1216 decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); 1217 } else { 1218 decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 1219 } 1220 UBool useSigDig = areSignificantDigitsUsed(); 1221 int32_t maxIntDig = getMaximumIntegerDigits(); 1222 int32_t minIntDig = getMinimumIntegerDigits(); 1223 1224 // Appends the prefix. 1225 double doubleValue = digits.getDouble(); 1226 int32_t prefixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), TRUE); 1227 1228 if (fUseExponentialNotation) 1229 { 1230 int currentLength = appendTo.length(); 1231 int intBegin = currentLength; 1232 int intEnd = -1; 1233 int fracBegin = -1; 1234 1235 int32_t minFracDig = 0; 1236 if (useSigDig) { 1237 maxIntDig = minIntDig = 1; 1238 minFracDig = getMinimumSignificantDigits() - 1; 1239 } else { 1240 minFracDig = getMinimumFractionDigits(); 1241 if (maxIntDig > kMaxScientificIntegerDigits) { 1242 maxIntDig = 1; 1243 if (maxIntDig < minIntDig) { 1244 maxIntDig = minIntDig; 1245 } 1246 } 1247 if (maxIntDig > minIntDig) { 1248 minIntDig = 1; 1249 } 1250 } 1251 1252 // Minimum integer digits are handled in exponential format by 1253 // adjusting the exponent. For example, 0.01234 with 3 minimum 1254 // integer digits is "123.4E-4". 1255 1256 // Maximum integer digits are interpreted as indicating the 1257 // repeating range. This is useful for engineering notation, in 1258 // which the exponent is restricted to a multiple of 3. For 1259 // example, 0.01234 with 3 maximum integer digits is "12.34e-3". 1260 // If maximum integer digits are defined and are larger than 1261 // minimum integer digits, then minimum integer digits are 1262 // ignored. 1263 digits.reduce(); // Removes trailing zero digits. 1264 int32_t exponent = digits.getDecimalAt(); 1265 if (maxIntDig > 1 && maxIntDig != minIntDig) { 1266 // A exponent increment is defined; adjust to it. 1267 exponent = (exponent > 0) ? (exponent - 1) / maxIntDig 1268 : (exponent / maxIntDig) - 1; 1269 exponent *= maxIntDig; 1270 } else { 1271 // No exponent increment is defined; use minimum integer digits. 1272 // If none is specified, as in "#E0", generate 1 integer digit. 1273 exponent -= (minIntDig > 0 || minFracDig > 0) 1274 ? minIntDig : 1; 1275 } 1276 1277 // We now output a minimum number of digits, and more if there 1278 // are more digits, up to the maximum number of digits. We 1279 // place the decimal point after the "integer" digits, which 1280 // are the first (decimalAt - exponent) digits. 1281 int32_t minimumDigits = minIntDig + minFracDig; 1282 // The number of integer digits is handled specially if the number 1283 // is zero, since then there may be no digits. 1284 int32_t integerDigits = digits.isZero() ? minIntDig : 1285 digits.getDecimalAt() - exponent; 1286 int32_t totalDigits = digits.getCount(); 1287 if (minimumDigits > totalDigits) 1288 totalDigits = minimumDigits; 1289 if (integerDigits > totalDigits) 1290 totalDigits = integerDigits; 1291 1292 // totalDigits records total number of digits needs to be processed 1293 int32_t i; 1294 for (i=0; i<totalDigits; ++i) 1295 { 1296 if (i == integerDigits) 1297 { 1298 intEnd = appendTo.length(); 1299 handler.addAttribute(kIntegerField, intBegin, intEnd); 1300 1301 appendTo += *decimal; 1302 1303 fracBegin = appendTo.length(); 1304 handler.addAttribute(kDecimalSeparatorField, fracBegin - 1, fracBegin); 1305 } 1306 // Restores the digit character or pads the buffer with zeros. 1307 UChar32 c = (UChar32)((i < digits.getCount()) ? 1308 localizedDigits[digits.getDigitValue(i)] : 1309 localizedDigits[0]); 1310 appendTo += c; 1311 } 1312 1313 currentLength = appendTo.length(); 1314 1315 if (intEnd < 0) { 1316 handler.addAttribute(kIntegerField, intBegin, currentLength); 1317 } 1318 if (fracBegin > 0) { 1319 handler.addAttribute(kFractionField, fracBegin, currentLength); 1320 } 1321 1322 // The exponent is output using the pattern-specified minimum 1323 // exponent digits. There is no maximum limit to the exponent 1324 // digits, since truncating the exponent would appendTo in an 1325 // unacceptable inaccuracy. 1326 appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); 1327 1328 handler.addAttribute(kExponentSymbolField, currentLength, appendTo.length()); 1329 currentLength = appendTo.length(); 1330 1331 // For zero values, we force the exponent to zero. We 1332 // must do this here, and not earlier, because the value 1333 // is used to determine integer digit count above. 1334 if (digits.isZero()) 1335 exponent = 0; 1336 1337 if (exponent < 0) { 1338 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 1339 handler.addAttribute(kExponentSignField, currentLength, appendTo.length()); 1340 } else if (fExponentSignAlwaysShown) { 1341 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 1342 handler.addAttribute(kExponentSignField, currentLength, appendTo.length()); 1343 } 1344 1345 currentLength = appendTo.length(); 1346 1347 DigitList expDigits; 1348 expDigits.set(exponent); 1349 { 1350 int expDig = fMinExponentDigits; 1351 if (fUseExponentialNotation && expDig < 1) { 1352 expDig = 1; 1353 } 1354 for (i=expDigits.getDecimalAt(); i<expDig; ++i) 1355 appendTo += (localizedDigits[0]); 1356 } 1357 for (i=0; i<expDigits.getDecimalAt(); ++i) 1358 { 1359 UChar32 c = (UChar32)((i < expDigits.getCount()) ? 1360 localizedDigits[expDigits.getDigitValue(i)] : 1361 localizedDigits[0]); 1362 appendTo += c; 1363 } 1364 1365 handler.addAttribute(kExponentField, currentLength, appendTo.length()); 1366 } 1367 else // Not using exponential notation 1368 { 1369 int currentLength = appendTo.length(); 1370 int intBegin = currentLength; 1371 1372 int32_t sigCount = 0; 1373 int32_t minSigDig = getMinimumSignificantDigits(); 1374 int32_t maxSigDig = getMaximumSignificantDigits(); 1375 if (!useSigDig) { 1376 minSigDig = 0; 1377 maxSigDig = INT32_MAX; 1378 } 1379 1380 // Output the integer portion. Here 'count' is the total 1381 // number of integer digits we will display, including both 1382 // leading zeros required to satisfy getMinimumIntegerDigits, 1383 // and actual digits present in the number. 1384 int32_t count = useSigDig ? 1385 _max(1, digits.getDecimalAt()) : minIntDig; 1386 if (digits.getDecimalAt() > 0 && count < digits.getDecimalAt()) { 1387 count = digits.getDecimalAt(); 1388 } 1389 1390 // Handle the case where getMaximumIntegerDigits() is smaller 1391 // than the real number of integer digits. If this is so, we 1392 // output the least significant max integer digits. For example, 1393 // the value 1997 printed with 2 max integer digits is just "97". 1394 1395 int32_t digitIndex = 0; // Index into digitList.fDigits[] 1396 if (count > maxIntDig && maxIntDig >= 0) { 1397 count = maxIntDig; 1398 digitIndex = digits.getDecimalAt() - count; 1399 } 1400 1401 int32_t sizeBeforeIntegerPart = appendTo.length(); 1402 1403 int32_t i; 1404 for (i=count-1; i>=0; --i) 1405 { 1406 if (i < digits.getDecimalAt() && digitIndex < digits.getCount() && 1407 sigCount < maxSigDig) { 1408 // Output a real digit 1409 appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)]; 1410 ++sigCount; 1411 } 1412 else 1413 { 1414 // Output a zero (leading or trailing) 1415 appendTo += localizedDigits[0]; 1416 if (sigCount > 0) { 1417 ++sigCount; 1418 } 1419 } 1420 1421 // Output grouping separator if necessary. 1422 if (isGroupingPosition(i)) { 1423 currentLength = appendTo.length(); 1424 appendTo.append(*grouping); 1425 handler.addAttribute(kGroupingSeparatorField, currentLength, appendTo.length()); 1426 } 1427 } 1428 1429 // TODO(dlf): this looks like it was a bug, we marked the int field as ending 1430 // before the zero was generated. 1431 // Record field information for caller. 1432 // if (fieldPosition.getField() == NumberFormat::kIntegerField) 1433 // fieldPosition.setEndIndex(appendTo.length()); 1434 1435 // Determine whether or not there are any printable fractional 1436 // digits. If we've used up the digits we know there aren't. 1437 UBool fractionPresent = (!isInteger && digitIndex < digits.getCount()) || 1438 (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0)); 1439 1440 // If there is no fraction present, and we haven't printed any 1441 // integer digits, then print a zero. Otherwise we won't print 1442 // _any_ digits, and we won't be able to parse this string. 1443 if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart) 1444 appendTo += localizedDigits[0]; 1445 1446 currentLength = appendTo.length(); 1447 handler.addAttribute(kIntegerField, intBegin, currentLength); 1448 1449 // Output the decimal separator if we always do so. 1450 if (fDecimalSeparatorAlwaysShown || fractionPresent) { 1451 appendTo += *decimal; 1452 handler.addAttribute(kDecimalSeparatorField, currentLength, appendTo.length()); 1453 currentLength = appendTo.length(); 1454 } 1455 1456 int fracBegin = currentLength; 1457 1458 count = useSigDig ? INT32_MAX : getMaximumFractionDigits(); 1459 if (useSigDig && (sigCount == maxSigDig || 1460 (sigCount >= minSigDig && digitIndex == digits.getCount()))) { 1461 count = 0; 1462 } 1463 1464 for (i=0; i < count; ++i) { 1465 // Here is where we escape from the loop. We escape 1466 // if we've output the maximum fraction digits 1467 // (specified in the for expression above). We also 1468 // stop when we've output the minimum digits and 1469 // either: we have an integer, so there is no 1470 // fractional stuff to display, or we're out of 1471 // significant digits. 1472 if (!useSigDig && i >= getMinimumFractionDigits() && 1473 (isInteger || digitIndex >= digits.getCount())) { 1474 break; 1475 } 1476 1477 // Output leading fractional zeros. These are zeros 1478 // that come after the decimal but before any 1479 // significant digits. These are only output if 1480 // abs(number being formatted) < 1.0. 1481 if (-1-i > (digits.getDecimalAt()-1)) { 1482 appendTo += localizedDigits[0]; 1483 continue; 1484 } 1485 1486 // Output a digit, if we have any precision left, or a 1487 // zero if we don't. We don't want to output noise digits. 1488 if (!isInteger && digitIndex < digits.getCount()) { 1489 appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)]; 1490 } else { 1491 appendTo += localizedDigits[0]; 1492 } 1493 1494 // If we reach the maximum number of significant 1495 // digits, or if we output all the real digits and 1496 // reach the minimum, then we are done. 1497 ++sigCount; 1498 if (useSigDig && 1499 (sigCount == maxSigDig || 1500 (digitIndex == digits.getCount() && sigCount >= minSigDig))) { 1501 break; 1502 } 1503 } 1504 1505 handler.addAttribute(kFractionField, fracBegin, appendTo.length()); 1506 } 1507 1508 int32_t suffixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), FALSE); 1509 1510 addPadding(appendTo, handler, prefixLen, suffixLen); 1511 return appendTo; 1512 } 1513 1514 /** 1515 * Inserts the character fPad as needed to expand result to fFormatWidth. 1516 * @param result the string to be padded 1517 */ 1518 void DecimalFormat::addPadding(UnicodeString& appendTo, 1519 FieldPositionHandler& handler, 1520 int32_t prefixLen, 1521 int32_t suffixLen) const 1522 { 1523 if (fFormatWidth > 0) { 1524 int32_t len = fFormatWidth - appendTo.length(); 1525 if (len > 0) { 1526 UnicodeString padding; 1527 for (int32_t i=0; i<len; ++i) { 1528 padding += fPad; 1529 } 1530 switch (fPadPosition) { 1531 case kPadAfterPrefix: 1532 appendTo.insert(prefixLen, padding); 1533 break; 1534 case kPadBeforePrefix: 1535 appendTo.insert(0, padding); 1536 break; 1537 case kPadBeforeSuffix: 1538 appendTo.insert(appendTo.length() - suffixLen, padding); 1539 break; 1540 case kPadAfterSuffix: 1541 appendTo += padding; 1542 break; 1543 } 1544 if (fPadPosition == kPadBeforePrefix || fPadPosition == kPadAfterPrefix) { 1545 handler.shiftLast(len); 1546 } 1547 } 1548 } 1549 } 1550 1551 //------------------------------------------------------------------------------ 1552 1553 void 1554 DecimalFormat::parse(const UnicodeString& text, 1555 Formattable& result, 1556 UErrorCode& status) const 1557 { 1558 NumberFormat::parse(text, result, status); 1559 } 1560 1561 void 1562 DecimalFormat::parse(const UnicodeString& text, 1563 Formattable& result, 1564 ParsePosition& parsePosition) const { 1565 parse(text, result, parsePosition, FALSE); 1566 } 1567 1568 Formattable& DecimalFormat::parseCurrency(const UnicodeString& text, 1569 Formattable& result, 1570 ParsePosition& pos) const { 1571 parse(text, result, pos, TRUE); 1572 return result; 1573 } 1574 1575 /** 1576 * Parses the given text as either a number or a currency amount. 1577 * @param text the string to parse 1578 * @param result output parameter for the result 1579 * @param parsePosition input-output position; on input, the 1580 * position within text to match; must have 0 <= pos.getIndex() < 1581 * text.length(); on output, the position after the last matched 1582 * character. If the parse fails, the position in unchanged upon 1583 * output. 1584 * @param parseCurrency if true, a currency amount is parsed; 1585 * otherwise a Number is parsed 1586 */ 1587 void DecimalFormat::parse(const UnicodeString& text, 1588 Formattable& result, 1589 ParsePosition& parsePosition, 1590 UBool parseCurrency) const { 1591 int32_t backup; 1592 int32_t i = backup = parsePosition.getIndex(); 1593 1594 // clear any old contents in the result. In particular, clears any DigitList 1595 // that it may be holding. 1596 result.setLong(0); 1597 1598 // Handle NaN as a special case: 1599 1600 // Skip padding characters, if around prefix 1601 if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix || 1602 fPadPosition == kPadAfterPrefix)) { 1603 i = skipPadding(text, i); 1604 } 1605 1606 if (isLenient()) { 1607 // skip any leading whitespace 1608 i = backup = skipUWhiteSpace(text, i); 1609 } 1610 1611 // If the text is composed of the representation of NaN, returns NaN.length 1612 const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol); 1613 int32_t nanLen = (text.compare(i, nan->length(), *nan) 1614 ? 0 : nan->length()); 1615 if (nanLen) { 1616 i += nanLen; 1617 if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix || 1618 fPadPosition == kPadAfterSuffix)) { 1619 i = skipPadding(text, i); 1620 } 1621 parsePosition.setIndex(i); 1622 result.setDouble(uprv_getNaN()); 1623 return; 1624 } 1625 1626 // NaN parse failed; start over 1627 i = backup; 1628 parsePosition.setIndex(i); 1629 1630 // status is used to record whether a number is infinite. 1631 UBool status[fgStatusLength]; 1632 UChar curbuf[4]; 1633 UChar* currency = parseCurrency ? curbuf : NULL; 1634 DigitList *digits = new DigitList; 1635 if (digits == NULL) { 1636 return; // no way to report error from here. 1637 } 1638 1639 if (fCurrencySignCount > fgCurrencySignCountZero) { 1640 if (!parseForCurrency(text, parsePosition, *digits, 1641 status, currency)) { 1642 delete digits; 1643 return; 1644 } 1645 } else { 1646 if (!subparse(text, 1647 fNegPrefixPattern, fNegSuffixPattern, 1648 fPosPrefixPattern, fPosSuffixPattern, 1649 FALSE, UCURR_SYMBOL_NAME, 1650 parsePosition, *digits, status, currency)) { 1651 parsePosition.setIndex(backup); 1652 delete digits; 1653 return; 1654 } 1655 } 1656 1657 // Handle infinity 1658 if (status[fgStatusInfinite]) { 1659 double inf = uprv_getInfinity(); 1660 result.setDouble(digits->isPositive() ? inf : -inf); 1661 delete digits; // TODO: set the dl to infinity, and let it fall into the code below. 1662 } 1663 1664 else { 1665 1666 if (fMultiplier != NULL) { 1667 UErrorCode ec = U_ZERO_ERROR; 1668 digits->div(*fMultiplier, ec); 1669 } 1670 1671 // Negative zero special case: 1672 // if parsing integerOnly, change to +0, which goes into an int32 in a Formattable. 1673 // if not parsing integerOnly, leave as -0, which a double can represent. 1674 if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) { 1675 digits->setPositive(TRUE); 1676 } 1677 result.adoptDigitList(digits); 1678 } 1679 1680 if (parseCurrency) { 1681 UErrorCode ec = U_ZERO_ERROR; 1682 Formattable n(result); 1683 result.adoptObject(new CurrencyAmount(n, curbuf, ec)); 1684 U_ASSERT(U_SUCCESS(ec)); // should always succeed 1685 } 1686 } 1687 1688 1689 1690 UBool 1691 DecimalFormat::parseForCurrency(const UnicodeString& text, 1692 ParsePosition& parsePosition, 1693 DigitList& digits, 1694 UBool* status, 1695 UChar* currency) const { 1696 int origPos = parsePosition.getIndex(); 1697 int maxPosIndex = origPos; 1698 int maxErrorPos = -1; 1699 // First, parse against current pattern. 1700 // Since current pattern could be set by applyPattern(), 1701 // it could be an arbitrary pattern, and it may not be the one 1702 // defined in current locale. 1703 UBool tmpStatus[fgStatusLength]; 1704 ParsePosition tmpPos(origPos); 1705 DigitList tmpDigitList; 1706 UBool found; 1707 if (fStyle == UNUM_CURRENCY_PLURAL) { 1708 found = subparse(text, 1709 fNegPrefixPattern, fNegSuffixPattern, 1710 fPosPrefixPattern, fPosSuffixPattern, 1711 TRUE, UCURR_LONG_NAME, 1712 tmpPos, tmpDigitList, tmpStatus, currency); 1713 } else { 1714 found = subparse(text, 1715 fNegPrefixPattern, fNegSuffixPattern, 1716 fPosPrefixPattern, fPosSuffixPattern, 1717 TRUE, UCURR_SYMBOL_NAME, 1718 tmpPos, tmpDigitList, tmpStatus, currency); 1719 } 1720 if (found) { 1721 if (tmpPos.getIndex() > maxPosIndex) { 1722 maxPosIndex = tmpPos.getIndex(); 1723 for (int32_t i = 0; i < fgStatusLength; ++i) { 1724 status[i] = tmpStatus[i]; 1725 } 1726 digits = tmpDigitList; 1727 } 1728 } else { 1729 maxErrorPos = tmpPos.getErrorIndex(); 1730 } 1731 // Then, parse against affix patterns. 1732 // Those are currency patterns and currency plural patterns. 1733 int32_t pos = -1; 1734 const UHashElement* element = NULL; 1735 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { 1736 const UHashTok valueTok = element->value; 1737 const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)valueTok.pointer; 1738 UBool tmpStatus[fgStatusLength]; 1739 ParsePosition tmpPos(origPos); 1740 DigitList tmpDigitList; 1741 UBool result = subparse(text, 1742 &affixPtn->negPrefixPatternForCurrency, 1743 &affixPtn->negSuffixPatternForCurrency, 1744 &affixPtn->posPrefixPatternForCurrency, 1745 &affixPtn->posSuffixPatternForCurrency, 1746 TRUE, affixPtn->patternType, 1747 tmpPos, tmpDigitList, tmpStatus, currency); 1748 if (result) { 1749 found = true; 1750 if (tmpPos.getIndex() > maxPosIndex) { 1751 maxPosIndex = tmpPos.getIndex(); 1752 for (int32_t i = 0; i < fgStatusLength; ++i) { 1753 status[i] = tmpStatus[i]; 1754 } 1755 digits = tmpDigitList; 1756 } 1757 } else { 1758 maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ? 1759 tmpPos.getErrorIndex() : maxErrorPos; 1760 } 1761 } 1762 // Finally, parse against simple affix to find the match. 1763 // For example, in TestMonster suite, 1764 // if the to-be-parsed text is "-\u00A40,00". 1765 // complexAffixCompare will not find match, 1766 // since there is no ISO code matches "\u00A4", 1767 // and the parse stops at "\u00A4". 1768 // We will just use simple affix comparison (look for exact match) 1769 // to pass it. 1770 UBool tmpStatus_2[fgStatusLength]; 1771 ParsePosition tmpPos_2(origPos); 1772 DigitList tmpDigitList_2; 1773 // set currencySignCount to 0 so that compareAffix function will 1774 // fall to compareSimpleAffix path, not compareComplexAffix path. 1775 // ?? TODO: is it right? need "false"? 1776 UBool result = subparse(text, 1777 &fNegativePrefix, &fNegativeSuffix, 1778 &fPositivePrefix, &fPositiveSuffix, 1779 FALSE, UCURR_SYMBOL_NAME, 1780 tmpPos_2, tmpDigitList_2, tmpStatus_2, 1781 currency); 1782 if (result) { 1783 if (tmpPos_2.getIndex() > maxPosIndex) { 1784 maxPosIndex = tmpPos_2.getIndex(); 1785 for (int32_t i = 0; i < fgStatusLength; ++i) { 1786 status[i] = tmpStatus_2[i]; 1787 } 1788 digits = tmpDigitList_2; 1789 } 1790 found = true; 1791 } else { 1792 maxErrorPos = (tmpPos_2.getErrorIndex() > maxErrorPos) ? 1793 tmpPos_2.getErrorIndex() : maxErrorPos; 1794 } 1795 1796 if (!found) { 1797 //parsePosition.setIndex(origPos); 1798 parsePosition.setErrorIndex(maxErrorPos); 1799 } else { 1800 parsePosition.setIndex(maxPosIndex); 1801 parsePosition.setErrorIndex(-1); 1802 } 1803 return found; 1804 } 1805 1806 1807 /** 1808 * Parse the given text into a number. The text is parsed beginning at 1809 * parsePosition, until an unparseable character is seen. 1810 * @param text the string to parse. 1811 * @param negPrefix negative prefix. 1812 * @param negSuffix negative suffix. 1813 * @param posPrefix positive prefix. 1814 * @param posSuffix positive suffix. 1815 * @param currencyParsing whether it is currency parsing or not. 1816 * @param type the currency type to parse against, LONG_NAME only or not. 1817 * @param parsePosition The position at which to being parsing. Upon 1818 * return, the first unparsed character. 1819 * @param digits the DigitList to set to the parsed value. 1820 * @param status output param containing boolean status flags indicating 1821 * whether the value was infinite and whether it was positive. 1822 * @param currency return value for parsed currency, for generic 1823 * currency parsing mode, or NULL for normal parsing. In generic 1824 * currency parsing mode, any currency is parsed, not just the 1825 * currency that this formatter is set to. 1826 */ 1827 UBool DecimalFormat::subparse(const UnicodeString& text, 1828 const UnicodeString* negPrefix, 1829 const UnicodeString* negSuffix, 1830 const UnicodeString* posPrefix, 1831 const UnicodeString* posSuffix, 1832 UBool currencyParsing, 1833 int8_t type, 1834 ParsePosition& parsePosition, 1835 DigitList& digits, UBool* status, 1836 UChar* currency) const 1837 { 1838 // The parsing process builds up the number as char string, in the neutral format that 1839 // will be acceptable to the decNumber library, then at the end passes that string 1840 // off for conversion to a decNumber. 1841 UErrorCode err = U_ZERO_ERROR; 1842 CharString parsedNum; 1843 digits.setToZero(); 1844 1845 int32_t position = parsePosition.getIndex(); 1846 int32_t oldStart = position; 1847 UBool strictParse = !isLenient(); 1848 1849 // Match padding before prefix 1850 if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) { 1851 position = skipPadding(text, position); 1852 } 1853 1854 // Match positive and negative prefixes; prefer longest match. 1855 int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, currencyParsing, type, currency); 1856 int32_t negMatch = compareAffix(text, position, TRUE, TRUE, negPrefix, currencyParsing, type, currency); 1857 if (posMatch >= 0 && negMatch >= 0) { 1858 if (posMatch > negMatch) { 1859 negMatch = -1; 1860 } else if (negMatch > posMatch) { 1861 posMatch = -1; 1862 } 1863 } 1864 if (posMatch >= 0) { 1865 position += posMatch; 1866 parsedNum.append('+', err); 1867 } else if (negMatch >= 0) { 1868 position += negMatch; 1869 parsedNum.append('-', err); 1870 } else if (strictParse){ 1871 parsePosition.setErrorIndex(position); 1872 return FALSE; 1873 } 1874 1875 // Match padding before prefix 1876 if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) { 1877 position = skipPadding(text, position); 1878 } 1879 1880 if (! strictParse) { 1881 position = skipUWhiteSpace(text, position); 1882 } 1883 1884 // process digits or Inf, find decimal position 1885 const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); 1886 int32_t infLen = (text.compare(position, inf->length(), *inf) 1887 ? 0 : inf->length()); 1888 position += infLen; // infLen is non-zero when it does equal to infinity 1889 status[fgStatusInfinite] = infLen != 0; 1890 1891 if (infLen != 0) { 1892 parsedNum.append("Infinity", err); 1893 } else { 1894 // We now have a string of digits, possibly with grouping symbols, 1895 // and decimal points. We want to process these into a DigitList. 1896 // We don't want to put a bunch of leading zeros into the DigitList 1897 // though, so we keep track of the location of the decimal point, 1898 // put only significant digits into the DigitList, and adjust the 1899 // exponent as needed. 1900 1901 UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 1902 1903 UBool strictFail = FALSE; // did we exit with a strict parse failure? 1904 int32_t lastGroup = -1; // where did we last see a grouping separator? 1905 int32_t digitStart = position; 1906 int32_t gs2 = fGroupingSize2 == 0 ? fGroupingSize : fGroupingSize2; 1907 1908 const UnicodeString *decimalString; 1909 if (fCurrencySignCount > fgCurrencySignCountZero) { 1910 decimalString = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); 1911 } else { 1912 decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 1913 } 1914 UChar32 decimalChar = decimalString->char32At(0); 1915 1916 const UnicodeString *groupingString = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol); 1917 UChar32 groupingChar = groupingString->char32At(0); 1918 UBool sawDecimal = FALSE; 1919 UChar32 sawDecimalChar = 0xFFFF; 1920 UBool sawGrouping = FALSE; 1921 UChar32 sawGroupingChar = 0xFFFF; 1922 UBool sawDigit = FALSE; 1923 int32_t backup = -1; 1924 int32_t digit; 1925 int32_t textLength = text.length(); // One less pointer to follow 1926 int32_t decimalStringLength = decimalString->length(); 1927 int32_t decimalCharLength = U16_LENGTH(decimalChar); 1928 int32_t groupingStringLength = groupingString->length(); 1929 int32_t groupingCharLength = U16_LENGTH(groupingChar); 1930 1931 // equivalent grouping and decimal support 1932 const UnicodeSet *decimalSet = NULL; 1933 const UnicodeSet *groupingSet = NULL; 1934 1935 if (decimalCharLength == decimalStringLength) { 1936 decimalSet = DecimalFormatStaticSets::getSimilarDecimals(decimalChar, strictParse); 1937 } 1938 1939 if (groupingCharLength == groupingStringLength) { 1940 if (strictParse) { 1941 groupingSet = DecimalFormatStaticSets::gStaticSets->fStrictDefaultGroupingSeparators; 1942 } else { 1943 groupingSet = DecimalFormatStaticSets::gStaticSets->fDefaultGroupingSeparators; 1944 } 1945 } 1946 1947 // We need to test groupingChar and decimalChar separately from groupingSet and decimalSet, if the sets are even initialized. 1948 // If sawDecimal is TRUE, only consider sawDecimalChar and NOT decimalSet 1949 // If a character matches decimalSet, don't consider it to be a member of the groupingSet. 1950 1951 // We have to track digitCount ourselves, because digits.fCount will 1952 // pin when the maximum allowable digits is reached. 1953 int32_t digitCount = 0; 1954 int32_t integerDigitCount = 0; 1955 1956 for (; position < textLength; ) 1957 { 1958 UChar32 ch = text.char32At(position); 1959 1960 /* We recognize all digit ranges, not only the Latin digit range 1961 * '0'..'9'. We do so by using the Character.digit() method, 1962 * which converts a valid Unicode digit to the range 0..9. 1963 * 1964 * The character 'ch' may be a digit. If so, place its value 1965 * from 0 to 9 in 'digit'. First try using the locale digit, 1966 * which may or MAY NOT be a standard Unicode digit range. If 1967 * this fails, try using the standard Unicode digit ranges by 1968 * calling Character.digit(). If this also fails, digit will 1969 * have a value outside the range 0..9. 1970 */ 1971 digit = ch - zero; 1972 if (digit < 0 || digit > 9) 1973 { 1974 digit = u_charDigitValue(ch); 1975 } 1976 1977 // As a last resort, look through the localized digits if the zero digit 1978 // is not a "standard" Unicode digit. 1979 if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) { 1980 digit = 0; 1981 if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) { 1982 break; 1983 } 1984 for (digit = 1 ; digit < 10 ; digit++ ) { 1985 if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) { 1986 break; 1987 } 1988 } 1989 } 1990 1991 if (digit >= 0 && digit <= 9) 1992 { 1993 if (strictParse && backup != -1) { 1994 // comma followed by digit, so group before comma is a 1995 // secondary group. If there was a group separator 1996 // before that, the group must == the secondary group 1997 // length, else it can be <= the the secondary group 1998 // length. 1999 if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) || 2000 (lastGroup == -1 && position - digitStart - 1 > gs2)) { 2001 strictFail = TRUE; 2002 break; 2003 } 2004 2005 lastGroup = backup; 2006 } 2007 2008 // Cancel out backup setting (see grouping handler below) 2009 backup = -1; 2010 sawDigit = TRUE; 2011 2012 // Note: this will append leading zeros 2013 parsedNum.append((char)(digit + '0'), err); 2014 2015 // count any digit that's not a leading zero 2016 if (digit > 0 || digitCount > 0 || sawDecimal) { 2017 digitCount += 1; 2018 2019 // count any integer digit that's not a leading zero 2020 if (! sawDecimal) { 2021 integerDigitCount += 1; 2022 } 2023 } 2024 2025 position += U16_LENGTH(ch); 2026 } 2027 else if (groupingStringLength > 0 && 2028 matchGrouping(groupingChar, sawGrouping, sawGroupingChar, groupingSet, 2029 decimalChar, decimalSet, 2030 ch) && isGroupingUsed()) 2031 { 2032 if (sawDecimal) { 2033 break; 2034 } 2035 2036 if (strictParse) { 2037 if ((!sawDigit || backup != -1)) { 2038 // leading group, or two group separators in a row 2039 strictFail = TRUE; 2040 break; 2041 } 2042 } 2043 2044 // Ignore grouping characters, if we are using them, but require 2045 // that they be followed by a digit. Otherwise we backup and 2046 // reprocess them. 2047 backup = position; 2048 position += groupingStringLength; 2049 sawGrouping=TRUE; 2050 // Once we see a grouping character, we only accept that grouping character from then on. 2051 sawGroupingChar=ch; 2052 } 2053 else if (matchDecimal(decimalChar,sawDecimal,sawDecimalChar, decimalSet, ch)) 2054 { 2055 if (strictParse) { 2056 if (backup != -1 || 2057 (lastGroup != -1 && position - lastGroup != fGroupingSize + 1)) { 2058 strictFail = TRUE; 2059 break; 2060 } 2061 } 2062 2063 // If we're only parsing integers, or if we ALREADY saw the 2064 // decimal, then don't parse this one. 2065 if (isParseIntegerOnly() || sawDecimal) { 2066 break; 2067 } 2068 2069 parsedNum.append('.', err); 2070 position += decimalStringLength; 2071 sawDecimal = TRUE; 2072 // Once we see a decimal character, we only accept that decimal character from then on. 2073 sawDecimalChar=ch; 2074 // decimalSet is considered to consist of (ch,ch) 2075 } 2076 else { 2077 const UnicodeString *tmp; 2078 tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); 2079 if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit 2080 { 2081 // Parse sign, if present 2082 int32_t pos = position + tmp->length(); 2083 char exponentSign = '+'; 2084 2085 if (pos < textLength) 2086 { 2087 tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 2088 if (!text.compare(pos, tmp->length(), *tmp)) 2089 { 2090 pos += tmp->length(); 2091 } 2092 else { 2093 tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 2094 if (!text.compare(pos, tmp->length(), *tmp)) 2095 { 2096 exponentSign = '-'; 2097 pos += tmp->length(); 2098 } 2099 } 2100 } 2101 2102 UBool sawExponentDigit = FALSE; 2103 while (pos < textLength) { 2104 ch = text[(int32_t)pos]; 2105 digit = ch - zero; 2106 2107 if (digit < 0 || digit > 9) { 2108 digit = u_charDigitValue(ch); 2109 } 2110 if (0 <= digit && digit <= 9) { 2111 if (!sawExponentDigit) { 2112 parsedNum.append('E', err); 2113 parsedNum.append(exponentSign, err); 2114 sawExponentDigit = TRUE; 2115 } 2116 ++pos; 2117 parsedNum.append((char)(digit + '0'), err); 2118 } else { 2119 break; 2120 } 2121 } 2122 2123 if (sawExponentDigit) { 2124 position = pos; // Advance past the exponent 2125 } 2126 2127 break; // Whether we fail or succeed, we exit this loop 2128 } 2129 else { 2130 break; 2131 } 2132 } 2133 } 2134 2135 if (backup != -1) 2136 { 2137 position = backup; 2138 } 2139 2140 if (strictParse && !sawDecimal) { 2141 if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) { 2142 strictFail = TRUE; 2143 } 2144 } 2145 2146 if (strictFail) { 2147 // only set with strictParse and a grouping separator error 2148 2149 parsePosition.setIndex(oldStart); 2150 parsePosition.setErrorIndex(position); 2151 return FALSE; 2152 } 2153 2154 // If there was no decimal point we have an integer 2155 2156 // If none of the text string was recognized. For example, parse 2157 // "x" with pattern "#0.00" (return index and error index both 0) 2158 // parse "$" with pattern "$#0.00". (return index 0 and error index 2159 // 1). 2160 if (!sawDigit && digitCount == 0) { 2161 parsePosition.setIndex(oldStart); 2162 parsePosition.setErrorIndex(oldStart); 2163 return FALSE; 2164 } 2165 } 2166 2167 // Match padding before suffix 2168 if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) { 2169 position = skipPadding(text, position); 2170 } 2171 2172 int32_t posSuffixMatch = -1, negSuffixMatch = -1; 2173 2174 // Match positive and negative suffixes; prefer longest match. 2175 if (posMatch >= 0 || (!strictParse && negMatch < 0)) { 2176 posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, currencyParsing, type, currency); 2177 } 2178 if (negMatch >= 0) { 2179 negSuffixMatch = compareAffix(text, position, TRUE, FALSE, negSuffix, currencyParsing, type, currency); 2180 } 2181 if (posSuffixMatch >= 0 && negSuffixMatch >= 0) { 2182 if (posSuffixMatch > negSuffixMatch) { 2183 negSuffixMatch = -1; 2184 } else if (negSuffixMatch > posSuffixMatch) { 2185 posSuffixMatch = -1; 2186 } 2187 } 2188 2189 // Fail if neither or both 2190 if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) { 2191 parsePosition.setErrorIndex(position); 2192 return FALSE; 2193 } 2194 2195 position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0)); 2196 2197 // Match padding before suffix 2198 if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) { 2199 position = skipPadding(text, position); 2200 } 2201 2202 parsePosition.setIndex(position); 2203 2204 parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0 && negSuffixMatch < 0)) ? '+' : '-'; 2205 2206 if(parsePosition.getIndex() == oldStart) 2207 { 2208 parsePosition.setErrorIndex(position); 2209 return FALSE; 2210 } 2211 digits.set(parsedNum.toStringPiece(), err); 2212 2213 if (U_FAILURE(err)) { 2214 parsePosition.setErrorIndex(position); 2215 return FALSE; 2216 } 2217 return TRUE; 2218 } 2219 2220 /** 2221 * Starting at position, advance past a run of pad characters, if any. 2222 * Return the index of the first character after position that is not a pad 2223 * character. Result is >= position. 2224 */ 2225 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const { 2226 int32_t padLen = U16_LENGTH(fPad); 2227 while (position < text.length() && 2228 text.char32At(position) == fPad) { 2229 position += padLen; 2230 } 2231 return position; 2232 } 2233 2234 /** 2235 * Return the length matched by the given affix, or -1 if none. 2236 * Runs of white space in the affix, match runs of white space in 2237 * the input. Pattern white space and input white space are 2238 * determined differently; see code. 2239 * @param text input text 2240 * @param pos offset into input at which to begin matching 2241 * @param isNegative 2242 * @param isPrefix 2243 * @param affixPat affix pattern used for currency affix comparison. 2244 * @param currencyParsing whether it is currency parsing or not 2245 * @param type the currency type to parse against, LONG_NAME only or not. 2246 * @param currency return value for parsed currency, for generic 2247 * currency parsing mode, or null for normal parsing. In generic 2248 * currency parsing mode, any currency is parsed, not just the 2249 * currency that this formatter is set to. 2250 * @return length of input that matches, or -1 if match failure 2251 */ 2252 int32_t DecimalFormat::compareAffix(const UnicodeString& text, 2253 int32_t pos, 2254 UBool isNegative, 2255 UBool isPrefix, 2256 const UnicodeString* affixPat, 2257 UBool currencyParsing, 2258 int8_t type, 2259 UChar* currency) const 2260 { 2261 const UnicodeString *patternToCompare; 2262 if (fCurrencyChoice != NULL || currency != NULL || 2263 (fCurrencySignCount > fgCurrencySignCountZero && currencyParsing)) { 2264 2265 if (affixPat != NULL) { 2266 return compareComplexAffix(*affixPat, text, pos, type, currency); 2267 } 2268 } 2269 2270 if (isNegative) { 2271 if (isPrefix) { 2272 patternToCompare = &fNegativePrefix; 2273 } 2274 else { 2275 patternToCompare = &fNegativeSuffix; 2276 } 2277 } 2278 else { 2279 if (isPrefix) { 2280 patternToCompare = &fPositivePrefix; 2281 } 2282 else { 2283 patternToCompare = &fPositiveSuffix; 2284 } 2285 } 2286 return compareSimpleAffix(*patternToCompare, text, pos, isLenient()); 2287 } 2288 2289 /** 2290 * Return the length matched by the given affix, or -1 if none. 2291 * Runs of white space in the affix, match runs of white space in 2292 * the input. Pattern white space and input white space are 2293 * determined differently; see code. 2294 * @param affix pattern string, taken as a literal 2295 * @param input input text 2296 * @param pos offset into input at which to begin matching 2297 * @return length of input that matches, or -1 if match failure 2298 */ 2299 int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix, 2300 const UnicodeString& input, 2301 int32_t pos, 2302 UBool lenient) { 2303 UErrorCode status = U_ZERO_ERROR; 2304 int32_t start = pos; 2305 UChar32 affixChar = affix.char32At(0); 2306 int32_t affixLength = affix.length(); 2307 int32_t inputLength = input.length(); 2308 int32_t affixCharLength = U16_LENGTH(affixChar); 2309 UnicodeSet *affixSet; 2310 2311 DecimalFormatStaticSets::initSets(&status); 2312 2313 if (!lenient) { 2314 affixSet = DecimalFormatStaticSets::gStaticSets->fStrictDashEquivalents; 2315 2316 // If the affix is exactly one character long and that character 2317 // is in the dash set and the very next input character is also 2318 // in the dash set, return a match. 2319 if (affixCharLength == affixLength && affixSet->contains(affixChar)) { 2320 if (affixSet->contains(input.char32At(pos))) { 2321 return 1; 2322 } 2323 } 2324 2325 for (int32_t i = 0; i < affixLength; ) { 2326 UChar32 c = affix.char32At(i); 2327 int32_t len = U16_LENGTH(c); 2328 if (PatternProps::isWhiteSpace(c)) { 2329 // We may have a pattern like: \u200F \u0020 2330 // and input text like: \u200F \u0020 2331 // Note that U+200F and U+0020 are Pattern_White_Space but only 2332 // U+0020 is UWhiteSpace. So we have to first do a direct 2333 // match of the run of Pattern_White_Space in the pattern, 2334 // then match any extra characters. 2335 UBool literalMatch = FALSE; 2336 while (pos < inputLength && 2337 input.char32At(pos) == c) { 2338 literalMatch = TRUE; 2339 i += len; 2340 pos += len; 2341 if (i == affixLength) { 2342 break; 2343 } 2344 c = affix.char32At(i); 2345 len = U16_LENGTH(c); 2346 if (!PatternProps::isWhiteSpace(c)) { 2347 break; 2348 } 2349 } 2350 2351 // Advance over run in pattern 2352 i = skipPatternWhiteSpace(affix, i); 2353 2354 // Advance over run in input text 2355 // Must see at least one white space char in input, 2356 // unless we've already matched some characters literally. 2357 int32_t s = pos; 2358 pos = skipUWhiteSpace(input, pos); 2359 if (pos == s && !literalMatch) { 2360 return -1; 2361 } 2362 2363 // If we skip UWhiteSpace in the input text, we need to skip it in the pattern. 2364 // Otherwise, the previous lines may have skipped over text (such as U+00A0) that 2365 // is also in the affix. 2366 i = skipUWhiteSpace(affix, i); 2367 } else { 2368 if (pos < inputLength && 2369 input.char32At(pos) == c) { 2370 i += len; 2371 pos += len; 2372 } else { 2373 return -1; 2374 } 2375 } 2376 } 2377 } else { 2378 UBool match = FALSE; 2379 2380 affixSet = DecimalFormatStaticSets::gStaticSets->fDashEquivalents; 2381 2382 if (affixCharLength == affixLength && affixSet->contains(affixChar)) { 2383 pos = skipUWhiteSpace(input, pos); 2384 2385 if (affixSet->contains(input.char32At(pos))) { 2386 return pos - start + 1; 2387 } 2388 } 2389 2390 for (int32_t i = 0; i < affixLength; ) 2391 { 2392 //i = skipRuleWhiteSpace(affix, i); 2393 i = skipUWhiteSpace(affix, i); 2394 pos = skipUWhiteSpace(input, pos); 2395 2396 if (i >= affixLength || pos >= inputLength) { 2397 break; 2398 } 2399 2400 UChar32 c = affix.char32At(i); 2401 int32_t len = U16_LENGTH(c); 2402 2403 if (input.char32At(pos) != c) { 2404 return -1; 2405 } 2406 2407 match = TRUE; 2408 i += len; 2409 pos += len; 2410 } 2411 2412 if (affixLength > 0 && ! match) { 2413 return -1; 2414 } 2415 } 2416 return pos - start; 2417 } 2418 2419 /** 2420 * Skip over a run of zero or more Pattern_White_Space characters at 2421 * pos in text. 2422 */ 2423 int32_t DecimalFormat::skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) { 2424 const UChar* s = text.getBuffer(); 2425 return (int32_t)(PatternProps::skipWhiteSpace(s + pos, text.length() - pos) - s); 2426 } 2427 2428 /** 2429 * Skip over a run of zero or more isUWhiteSpace() characters at pos 2430 * in text. 2431 */ 2432 int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) { 2433 while (pos < text.length()) { 2434 UChar32 c = text.char32At(pos); 2435 if (!u_isUWhiteSpace(c)) { 2436 break; 2437 } 2438 pos += U16_LENGTH(c); 2439 } 2440 return pos; 2441 } 2442 2443 /** 2444 * Return the length matched by the given affix, or -1 if none. 2445 * @param affixPat pattern string 2446 * @param input input text 2447 * @param pos offset into input at which to begin matching 2448 * @param type the currency type to parse against, LONG_NAME only or not. 2449 * @param currency return value for parsed currency, for generic 2450 * currency parsing mode, or null for normal parsing. In generic 2451 * currency parsing mode, any currency is parsed, not just the 2452 * currency that this formatter is set to. 2453 * @return length of input that matches, or -1 if match failure 2454 */ 2455 int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat, 2456 const UnicodeString& text, 2457 int32_t pos, 2458 int8_t type, 2459 UChar* currency) const 2460 { 2461 int32_t start = pos; 2462 U_ASSERT(currency != NULL || 2463 (fCurrencyChoice != NULL && *getCurrency() != 0) || 2464 fCurrencySignCount > fgCurrencySignCountZero); 2465 2466 for (int32_t i=0; 2467 i<affixPat.length() && pos >= 0; ) { 2468 UChar32 c = affixPat.char32At(i); 2469 i += U16_LENGTH(c); 2470 2471 if (c == kQuote) { 2472 U_ASSERT(i <= affixPat.length()); 2473 c = affixPat.char32At(i); 2474 i += U16_LENGTH(c); 2475 2476 const UnicodeString* affix = NULL; 2477 2478 switch (c) { 2479 case kCurrencySign: { 2480 // since the currency names in choice format is saved 2481 // the same way as other currency names, 2482 // do not need to do currency choice parsing here. 2483 // the general currency parsing parse against all names, 2484 // including names in choice format. 2485 UBool intl = i<affixPat.length() && 2486 affixPat.char32At(i) == kCurrencySign; 2487 if (intl) { 2488 ++i; 2489 } 2490 UBool plural = i<affixPat.length() && 2491 affixPat.char32At(i) == kCurrencySign; 2492 if (plural) { 2493 ++i; 2494 intl = FALSE; 2495 } 2496 // Parse generic currency -- anything for which we 2497 // have a display name, or any 3-letter ISO code. 2498 // Try to parse display name for our locale; first 2499 // determine our locale. 2500 const char* loc = fCurrencyPluralInfo->getLocale().getName(); 2501 ParsePosition ppos(pos); 2502 UChar curr[4]; 2503 UErrorCode ec = U_ZERO_ERROR; 2504 // Delegate parse of display name => ISO code to Currency 2505 uprv_parseCurrency(loc, text, ppos, type, curr, ec); 2506 2507 // If parse succeeds, populate currency[0] 2508 if (U_SUCCESS(ec) && ppos.getIndex() != pos) { 2509 if (currency) { 2510 u_strcpy(currency, curr); 2511 } else { 2512 // The formatter is currency-style but the client has not requested 2513 // the value of the parsed currency. In this case, if that value does 2514 // not match the formatter's current value, then the parse fails. 2515 UChar effectiveCurr[4]; 2516 getEffectiveCurrency(effectiveCurr, ec); 2517 if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,4) != 0 ) { 2518 pos = -1; 2519 continue; 2520 } 2521 } 2522 pos = ppos.getIndex(); 2523 } else if (!isLenient()){ 2524 pos = -1; 2525 } 2526 continue; 2527 } 2528 case kPatternPercent: 2529 affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 2530 break; 2531 case kPatternPerMill: 2532 affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 2533 break; 2534 case kPatternPlus: 2535 affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 2536 break; 2537 case kPatternMinus: 2538 affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 2539 break; 2540 default: 2541 // fall through to affix!=0 test, which will fail 2542 break; 2543 } 2544 2545 if (affix != NULL) { 2546 pos = match(text, pos, *affix); 2547 continue; 2548 } 2549 } 2550 2551 pos = match(text, pos, c); 2552 if (PatternProps::isWhiteSpace(c)) { 2553 i = skipPatternWhiteSpace(affixPat, i); 2554 } 2555 } 2556 return pos - start; 2557 } 2558 2559 /** 2560 * Match a single character at text[pos] and return the index of the 2561 * next character upon success. Return -1 on failure. If 2562 * ch is a Pattern_White_Space then match a run of white space in text. 2563 */ 2564 int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) { 2565 if (PatternProps::isWhiteSpace(ch)) { 2566 // Advance over run of white space in input text 2567 // Must see at least one white space char in input 2568 int32_t s = pos; 2569 pos = skipPatternWhiteSpace(text, pos); 2570 if (pos == s) { 2571 return -1; 2572 } 2573 return pos; 2574 } 2575 return (pos >= 0 && text.char32At(pos) == ch) ? 2576 (pos + U16_LENGTH(ch)) : -1; 2577 } 2578 2579 /** 2580 * Match a string at text[pos] and return the index of the next 2581 * character upon success. Return -1 on failure. Match a run of 2582 * white space in str with a run of white space in text. 2583 */ 2584 int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) { 2585 for (int32_t i=0; i<str.length() && pos >= 0; ) { 2586 UChar32 ch = str.char32At(i); 2587 i += U16_LENGTH(ch); 2588 if (PatternProps::isWhiteSpace(ch)) { 2589 i = skipPatternWhiteSpace(str, i); 2590 } 2591 pos = match(text, pos, ch); 2592 } 2593 return pos; 2594 } 2595 2596 UBool DecimalFormat::matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol, 2597 UnicodeSet *sset, UChar32 schar) 2598 { 2599 if (sset != NULL) { 2600 return sset->contains(schar); 2601 } 2602 2603 return text.compare(position, length, symbol) == 0; 2604 } 2605 2606 UBool DecimalFormat::matchDecimal(UChar32 symbolChar, 2607 UBool sawDecimal, UChar32 sawDecimalChar, 2608 const UnicodeSet *sset, UChar32 schar) { 2609 if(sawDecimal) { 2610 return schar==sawDecimalChar; 2611 } else if(schar==symbolChar) { 2612 return TRUE; 2613 } else if(sset!=NULL) { 2614 return sset->contains(schar); 2615 } else { 2616 return FALSE; 2617 } 2618 } 2619 2620 UBool DecimalFormat::matchGrouping(UChar32 groupingChar, 2621 UBool sawGrouping, UChar32 sawGroupingChar, 2622 const UnicodeSet *sset, 2623 UChar32 decimalChar, const UnicodeSet *decimalSet, 2624 UChar32 schar) { 2625 if(sawGrouping) { 2626 return schar==sawGroupingChar; // previously found 2627 } else if(schar==groupingChar) { 2628 return TRUE; // char from symbols 2629 } else if(sset!=NULL) { 2630 return sset->contains(schar) && // in groupingSet but... 2631 ((decimalSet==NULL) || !decimalSet->contains(schar)); // Exclude decimalSet from groupingSet 2632 } else { 2633 return FALSE; 2634 } 2635 } 2636 2637 2638 2639 //------------------------------------------------------------------------------ 2640 // Gets the pointer to the localized decimal format symbols 2641 2642 const DecimalFormatSymbols* 2643 DecimalFormat::getDecimalFormatSymbols() const 2644 { 2645 return fSymbols; 2646 } 2647 2648 //------------------------------------------------------------------------------ 2649 // De-owning the current localized symbols and adopt the new symbols. 2650 2651 void 2652 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) 2653 { 2654 if (symbolsToAdopt == NULL) { 2655 return; // do not allow caller to set fSymbols to NULL 2656 } 2657 2658 UBool sameSymbols = FALSE; 2659 if (fSymbols != NULL) { 2660 sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == 2661 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) && 2662 getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == 2663 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 2664 delete fSymbols; 2665 } 2666 2667 fSymbols = symbolsToAdopt; 2668 if (!sameSymbols) { 2669 // If the currency symbols are the same, there is no need to recalculate. 2670 setCurrencyForSymbols(); 2671 } 2672 expandAffixes(NULL); 2673 } 2674 //------------------------------------------------------------------------------ 2675 // Setting the symbols is equlivalent to adopting a newly created localized 2676 // symbols. 2677 2678 void 2679 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) 2680 { 2681 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); 2682 } 2683 2684 2685 const CurrencyPluralInfo* 2686 DecimalFormat::getCurrencyPluralInfo(void) const 2687 { 2688 return fCurrencyPluralInfo; 2689 } 2690 2691 2692 void 2693 DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) 2694 { 2695 if (toAdopt != NULL) { 2696 delete fCurrencyPluralInfo; 2697 fCurrencyPluralInfo = toAdopt; 2698 // re-set currency affix patterns and currency affixes. 2699 if (fCurrencySignCount > fgCurrencySignCountZero) { 2700 UErrorCode status = U_ZERO_ERROR; 2701 if (fAffixPatternsForCurrency) { 2702 deleteHashForAffixPattern(); 2703 } 2704 setupCurrencyAffixPatterns(status); 2705 if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) { 2706 // only setup the affixes of the plural pattern. 2707 setupCurrencyAffixes(fFormatPattern, FALSE, TRUE, status); 2708 } 2709 } 2710 } 2711 } 2712 2713 void 2714 DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) 2715 { 2716 adoptCurrencyPluralInfo(info.clone()); 2717 } 2718 2719 2720 /** 2721 * Update the currency object to match the symbols. This method 2722 * is used only when the caller has passed in a symbols object 2723 * that may not be the default object for its locale. 2724 */ 2725 void 2726 DecimalFormat::setCurrencyForSymbols() { 2727 /*Bug 4212072 2728 Update the affix strings accroding to symbols in order to keep 2729 the affix strings up to date. 2730 [Richard/GCL] 2731 */ 2732 2733 // With the introduction of the Currency object, the currency 2734 // symbols in the DFS object are ignored. For backward 2735 // compatibility, we check any explicitly set DFS object. If it 2736 // is a default symbols object for its locale, we change the 2737 // currency object to one for that locale. If it is custom, 2738 // we set the currency to null. 2739 UErrorCode ec = U_ZERO_ERROR; 2740 const UChar* c = NULL; 2741 const char* loc = fSymbols->getLocale().getName(); 2742 UChar intlCurrencySymbol[4]; 2743 ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec); 2744 UnicodeString currencySymbol; 2745 2746 uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec); 2747 if (U_SUCCESS(ec) 2748 && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol 2749 && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == UnicodeString(intlCurrencySymbol)) 2750 { 2751 // Trap an error in mapping locale to currency. If we can't 2752 // map, then don't fail and set the currency to "". 2753 c = intlCurrencySymbol; 2754 } 2755 ec = U_ZERO_ERROR; // reset local error code! 2756 setCurrencyInternally(c, ec); 2757 } 2758 2759 2760 //------------------------------------------------------------------------------ 2761 // Gets the positive prefix of the number pattern. 2762 2763 UnicodeString& 2764 DecimalFormat::getPositivePrefix(UnicodeString& result) const 2765 { 2766 result = fPositivePrefix; 2767 return result; 2768 } 2769 2770 //------------------------------------------------------------------------------ 2771 // Sets the positive prefix of the number pattern. 2772 2773 void 2774 DecimalFormat::setPositivePrefix(const UnicodeString& newValue) 2775 { 2776 fPositivePrefix = newValue; 2777 delete fPosPrefixPattern; 2778 fPosPrefixPattern = 0; 2779 } 2780 2781 //------------------------------------------------------------------------------ 2782 // Gets the negative prefix of the number pattern. 2783 2784 UnicodeString& 2785 DecimalFormat::getNegativePrefix(UnicodeString& result) const 2786 { 2787 result = fNegativePrefix; 2788 return result; 2789 } 2790 2791 //------------------------------------------------------------------------------ 2792 // Gets the negative prefix of the number pattern. 2793 2794 void 2795 DecimalFormat::setNegativePrefix(const UnicodeString& newValue) 2796 { 2797 fNegativePrefix = newValue; 2798 delete fNegPrefixPattern; 2799 fNegPrefixPattern = 0; 2800 } 2801 2802 //------------------------------------------------------------------------------ 2803 // Gets the positive suffix of the number pattern. 2804 2805 UnicodeString& 2806 DecimalFormat::getPositiveSuffix(UnicodeString& result) const 2807 { 2808 result = fPositiveSuffix; 2809 return result; 2810 } 2811 2812 //------------------------------------------------------------------------------ 2813 // Sets the positive suffix of the number pattern. 2814 2815 void 2816 DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) 2817 { 2818 fPositiveSuffix = newValue; 2819 delete fPosSuffixPattern; 2820 fPosSuffixPattern = 0; 2821 } 2822 2823 //------------------------------------------------------------------------------ 2824 // Gets the negative suffix of the number pattern. 2825 2826 UnicodeString& 2827 DecimalFormat::getNegativeSuffix(UnicodeString& result) const 2828 { 2829 result = fNegativeSuffix; 2830 return result; 2831 } 2832 2833 //------------------------------------------------------------------------------ 2834 // Sets the negative suffix of the number pattern. 2835 2836 void 2837 DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) 2838 { 2839 fNegativeSuffix = newValue; 2840 delete fNegSuffixPattern; 2841 fNegSuffixPattern = 0; 2842 } 2843 2844 //------------------------------------------------------------------------------ 2845 // Gets the multiplier of the number pattern. 2846 // Multipliers are stored as decimal numbers (DigitLists) because that 2847 // is the most convenient for muliplying or dividing the numbers to be formatted. 2848 // A NULL multiplier implies one, and the scaling operations are skipped. 2849 2850 int32_t 2851 DecimalFormat::getMultiplier() const 2852 { 2853 if (fMultiplier == NULL) { 2854 return 1; 2855 } else { 2856 return fMultiplier->getLong(); 2857 } 2858 } 2859 2860 //------------------------------------------------------------------------------ 2861 // Sets the multiplier of the number pattern. 2862 void 2863 DecimalFormat::setMultiplier(int32_t newValue) 2864 { 2865 // if (newValue == 0) { 2866 // throw new IllegalArgumentException("Bad multiplier: " + newValue); 2867 // } 2868 if (newValue == 0) { 2869 newValue = 1; // one being the benign default value for a multiplier. 2870 } 2871 if (newValue == 1) { 2872 delete fMultiplier; 2873 fMultiplier = NULL; 2874 } else { 2875 if (fMultiplier == NULL) { 2876 fMultiplier = new DigitList; 2877 } 2878 if (fMultiplier != NULL) { 2879 fMultiplier->set(newValue); 2880 } 2881 } 2882 } 2883 2884 /** 2885 * Get the rounding increment. 2886 * @return A positive rounding increment, or 0.0 if rounding 2887 * is not in effect. 2888 * @see #setRoundingIncrement 2889 * @see #getRoundingMode 2890 * @see #setRoundingMode 2891 */ 2892 double DecimalFormat::getRoundingIncrement() const { 2893 if (fRoundingIncrement == NULL) { 2894 return 0.0; 2895 } else { 2896 return fRoundingIncrement->getDouble(); 2897 } 2898 } 2899 2900 /** 2901 * Set the rounding increment. This method also controls whether 2902 * rounding is enabled. 2903 * @param newValue A positive rounding increment, or 0.0 to disable rounding. 2904 * Negative increments are equivalent to 0.0. 2905 * @see #getRoundingIncrement 2906 * @see #getRoundingMode 2907 * @see #setRoundingMode 2908 */ 2909 void DecimalFormat::setRoundingIncrement(double newValue) { 2910 if (newValue > 0.0) { 2911 if (fRoundingIncrement == NULL) { 2912 fRoundingIncrement = new DigitList(); 2913 } 2914 if (fRoundingIncrement != NULL) { 2915 fRoundingIncrement->set(newValue); 2916 return; 2917 } 2918 } 2919 // These statements are executed if newValue is less than 0.0 2920 // or fRoundingIncrement could not be created. 2921 delete fRoundingIncrement; 2922 fRoundingIncrement = NULL; 2923 } 2924 2925 /** 2926 * Get the rounding mode. 2927 * @return A rounding mode 2928 * @see #setRoundingIncrement 2929 * @see #getRoundingIncrement 2930 * @see #setRoundingMode 2931 */ 2932 DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const { 2933 return fRoundingMode; 2934 } 2935 2936 /** 2937 * Set the rounding mode. This has no effect unless the rounding 2938 * increment is greater than zero. 2939 * @param roundingMode A rounding mode 2940 * @see #setRoundingIncrement 2941 * @see #getRoundingIncrement 2942 * @see #getRoundingMode 2943 */ 2944 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { 2945 fRoundingMode = roundingMode; 2946 } 2947 2948 /** 2949 * Get the width to which the output of <code>format()</code> is padded. 2950 * @return the format width, or zero if no padding is in effect 2951 * @see #setFormatWidth 2952 * @see #getPadCharacter 2953 * @see #setPadCharacter 2954 * @see #getPadPosition 2955 * @see #setPadPosition 2956 */ 2957 int32_t DecimalFormat::getFormatWidth() const { 2958 return fFormatWidth; 2959 } 2960 2961 /** 2962 * Set the width to which the output of <code>format()</code> is padded. 2963 * This method also controls whether padding is enabled. 2964 * @param width the width to which to pad the result of 2965 * <code>format()</code>, or zero to disable padding. A negative 2966 * width is equivalent to 0. 2967 * @see #getFormatWidth 2968 * @see #getPadCharacter 2969 * @see #setPadCharacter 2970 * @see #getPadPosition 2971 * @see #setPadPosition 2972 */ 2973 void DecimalFormat::setFormatWidth(int32_t width) { 2974 fFormatWidth = (width > 0) ? width : 0; 2975 } 2976 2977 UnicodeString DecimalFormat::getPadCharacterString() const { 2978 return UnicodeString(fPad); 2979 } 2980 2981 void DecimalFormat::setPadCharacter(const UnicodeString &padChar) { 2982 if (padChar.length() > 0) { 2983 fPad = padChar.char32At(0); 2984 } 2985 else { 2986 fPad = kDefaultPad; 2987 } 2988 } 2989 2990 /** 2991 * Get the position at which padding will take place. This is the location 2992 * at which padding will be inserted if the result of <code>format()</code> 2993 * is shorter than the format width. 2994 * @return the pad position, one of <code>kPadBeforePrefix</code>, 2995 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or 2996 * <code>kPadAfterSuffix</code>. 2997 * @see #setFormatWidth 2998 * @see #getFormatWidth 2999 * @see #setPadCharacter 3000 * @see #getPadCharacter 3001 * @see #setPadPosition 3002 * @see #kPadBeforePrefix 3003 * @see #kPadAfterPrefix 3004 * @see #kPadBeforeSuffix 3005 * @see #kPadAfterSuffix 3006 */ 3007 DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const { 3008 return fPadPosition; 3009 } 3010 3011 /** 3012 * <strong><font face=helvetica color=red>NEW</font></strong> 3013 * Set the position at which padding will take place. This is the location 3014 * at which padding will be inserted if the result of <code>format()</code> 3015 * is shorter than the format width. This has no effect unless padding is 3016 * enabled. 3017 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>, 3018 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or 3019 * <code>kPadAfterSuffix</code>. 3020 * @see #setFormatWidth 3021 * @see #getFormatWidth 3022 * @see #setPadCharacter 3023 * @see #getPadCharacter 3024 * @see #getPadPosition 3025 * @see #kPadBeforePrefix 3026 * @see #kPadAfterPrefix 3027 * @see #kPadBeforeSuffix 3028 * @see #kPadAfterSuffix 3029 */ 3030 void DecimalFormat::setPadPosition(EPadPosition padPos) { 3031 fPadPosition = padPos; 3032 } 3033 3034 /** 3035 * Return whether or not scientific notation is used. 3036 * @return TRUE if this object formats and parses scientific notation 3037 * @see #setScientificNotation 3038 * @see #getMinimumExponentDigits 3039 * @see #setMinimumExponentDigits 3040 * @see #isExponentSignAlwaysShown 3041 * @see #setExponentSignAlwaysShown 3042 */ 3043 UBool DecimalFormat::isScientificNotation() { 3044 return fUseExponentialNotation; 3045 } 3046 3047 /** 3048 * Set whether or not scientific notation is used. 3049 * @param useScientific TRUE if this object formats and parses scientific 3050 * notation 3051 * @see #isScientificNotation 3052 * @see #getMinimumExponentDigits 3053 * @see #setMinimumExponentDigits 3054 * @see #isExponentSignAlwaysShown 3055 * @see #setExponentSignAlwaysShown 3056 */ 3057 void DecimalFormat::setScientificNotation(UBool useScientific) { 3058 fUseExponentialNotation = useScientific; 3059 } 3060 3061 /** 3062 * Return the minimum exponent digits that will be shown. 3063 * @return the minimum exponent digits that will be shown 3064 * @see #setScientificNotation 3065 * @see #isScientificNotation 3066 * @see #setMinimumExponentDigits 3067 * @see #isExponentSignAlwaysShown 3068 * @see #setExponentSignAlwaysShown 3069 */ 3070 int8_t DecimalFormat::getMinimumExponentDigits() const { 3071 return fMinExponentDigits; 3072 } 3073 3074 /** 3075 * Set the minimum exponent digits that will be shown. This has no 3076 * effect unless scientific notation is in use. 3077 * @param minExpDig a value >= 1 indicating the fewest exponent digits 3078 * that will be shown. Values less than 1 will be treated as 1. 3079 * @see #setScientificNotation 3080 * @see #isScientificNotation 3081 * @see #getMinimumExponentDigits 3082 * @see #isExponentSignAlwaysShown 3083 * @see #setExponentSignAlwaysShown 3084 */ 3085 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { 3086 fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1); 3087 } 3088 3089 /** 3090 * Return whether the exponent sign is always shown. 3091 * @return TRUE if the exponent is always prefixed with either the 3092 * localized minus sign or the localized plus sign, false if only negative 3093 * exponents are prefixed with the localized minus sign. 3094 * @see #setScientificNotation 3095 * @see #isScientificNotation 3096 * @see #setMinimumExponentDigits 3097 * @see #getMinimumExponentDigits 3098 * @see #setExponentSignAlwaysShown 3099 */ 3100 UBool DecimalFormat::isExponentSignAlwaysShown() { 3101 return fExponentSignAlwaysShown; 3102 } 3103 3104 /** 3105 * Set whether the exponent sign is always shown. This has no effect 3106 * unless scientific notation is in use. 3107 * @param expSignAlways TRUE if the exponent is always prefixed with either 3108 * the localized minus sign or the localized plus sign, false if only 3109 * negative exponents are prefixed with the localized minus sign. 3110 * @see #setScientificNotation 3111 * @see #isScientificNotation 3112 * @see #setMinimumExponentDigits 3113 * @see #getMinimumExponentDigits 3114 * @see #isExponentSignAlwaysShown 3115 */ 3116 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { 3117 fExponentSignAlwaysShown = expSignAlways; 3118 } 3119 3120 //------------------------------------------------------------------------------ 3121 // Gets the grouping size of the number pattern. For example, thousand or 10 3122 // thousand groupings. 3123 3124 int32_t 3125 DecimalFormat::getGroupingSize() const 3126 { 3127 return fGroupingSize; 3128 } 3129 3130 //------------------------------------------------------------------------------ 3131 // Gets the grouping size of the number pattern. 3132 3133 void 3134 DecimalFormat::setGroupingSize(int32_t newValue) 3135 { 3136 fGroupingSize = newValue; 3137 } 3138 3139 //------------------------------------------------------------------------------ 3140 3141 int32_t 3142 DecimalFormat::getSecondaryGroupingSize() const 3143 { 3144 return fGroupingSize2; 3145 } 3146 3147 //------------------------------------------------------------------------------ 3148 3149 void 3150 DecimalFormat::setSecondaryGroupingSize(int32_t newValue) 3151 { 3152 fGroupingSize2 = newValue; 3153 } 3154 3155 //------------------------------------------------------------------------------ 3156 // Checks if to show the decimal separator. 3157 3158 UBool 3159 DecimalFormat::isDecimalSeparatorAlwaysShown() const 3160 { 3161 return fDecimalSeparatorAlwaysShown; 3162 } 3163 3164 //------------------------------------------------------------------------------ 3165 // Sets to always show the decimal separator. 3166 3167 void 3168 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) 3169 { 3170 fDecimalSeparatorAlwaysShown = newValue; 3171 } 3172 3173 //------------------------------------------------------------------------------ 3174 // Emits the pattern of this DecimalFormat instance. 3175 3176 UnicodeString& 3177 DecimalFormat::toPattern(UnicodeString& result) const 3178 { 3179 return toPattern(result, FALSE); 3180 } 3181 3182 //------------------------------------------------------------------------------ 3183 // Emits the localized pattern this DecimalFormat instance. 3184 3185 UnicodeString& 3186 DecimalFormat::toLocalizedPattern(UnicodeString& result) const 3187 { 3188 return toPattern(result, TRUE); 3189 } 3190 3191 //------------------------------------------------------------------------------ 3192 /** 3193 * Expand the affix pattern strings into the expanded affix strings. If any 3194 * affix pattern string is null, do not expand it. This method should be 3195 * called any time the symbols or the affix patterns change in order to keep 3196 * the expanded affix strings up to date. 3197 * This method also will be called before formatting if format currency 3198 * plural names, since the plural name is not a static one, it is 3199 * based on the currency plural count, the affix will be known only 3200 * after the currency plural count is know. 3201 * In which case, the parameter 3202 * 'pluralCount' will be a non-null currency plural count. 3203 * In all other cases, the 'pluralCount' is null, which means it is not needed. 3204 */ 3205 void DecimalFormat::expandAffixes(const UnicodeString* pluralCount) { 3206 FieldPositionHandler none; 3207 if (fPosPrefixPattern != 0) { 3208 expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, none, FALSE, pluralCount); 3209 } 3210 if (fPosSuffixPattern != 0) { 3211 expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, none, FALSE, pluralCount); 3212 } 3213 if (fNegPrefixPattern != 0) { 3214 expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, none, FALSE, pluralCount); 3215 } 3216 if (fNegSuffixPattern != 0) { 3217 expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, none, FALSE, pluralCount); 3218 } 3219 #ifdef FMT_DEBUG 3220 UnicodeString s; 3221 s.append("[") 3222 .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern) 3223 .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern) 3224 .append("]->[") 3225 .append(fPositivePrefix).append("|").append(fPositiveSuffix) 3226 .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix) 3227 .append("]\n"); 3228 debugout(s); 3229 #endif 3230 } 3231 3232 /** 3233 * Expand an affix pattern into an affix string. All characters in the 3234 * pattern are literal unless prefixed by kQuote. The following characters 3235 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 3236 * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote + 3237 * kCurrencySign + kCurrencySign), it is interpreted as an international 3238 * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as 3239 * currency plural long names, such as "US Dollars". 3240 * Any other character after a kQuote represents itself. 3241 * kQuote must be followed by another character; kQuote may not occur by 3242 * itself at the end of the pattern. 3243 * 3244 * This method is used in two distinct ways. First, it is used to expand 3245 * the stored affix patterns into actual affixes. For this usage, doFormat 3246 * must be false. Second, it is used to expand the stored affix patterns 3247 * given a specific number (doFormat == true), for those rare cases in 3248 * which a currency format references a ChoiceFormat (e.g., en_IN display 3249 * name for INR). The number itself is taken from digitList. 3250 * 3251 * When used in the first way, this method has a side effect: It sets 3252 * currencyChoice to a ChoiceFormat object, if the currency's display name 3253 * in this locale is a ChoiceFormat pattern (very rare). It only does this 3254 * if currencyChoice is null to start with. 3255 * 3256 * @param pattern the non-null, fPossibly empty pattern 3257 * @param affix string to receive the expanded equivalent of pattern. 3258 * Previous contents are deleted. 3259 * @param doFormat if false, then the pattern will be expanded, and if a 3260 * currency symbol is encountered that expands to a ChoiceFormat, the 3261 * currencyChoice member variable will be initialized if it is null. If 3262 * doFormat is true, then it is assumed that the currencyChoice has been 3263 * created, and it will be used to format the value in digitList. 3264 * @param pluralCount the plural count. It is only used for currency 3265 * plural format. In which case, it is the plural 3266 * count of the currency amount. For example, 3267 * in en_US, it is the singular "one", or the plural 3268 * "other". For all other cases, it is null, and 3269 * is not being used. 3270 */ 3271 void DecimalFormat::expandAffix(const UnicodeString& pattern, 3272 UnicodeString& affix, 3273 double number, 3274 FieldPositionHandler& handler, 3275 UBool doFormat, 3276 const UnicodeString* pluralCount) const { 3277 affix.remove(); 3278 for (int i=0; i<pattern.length(); ) { 3279 UChar32 c = pattern.char32At(i); 3280 i += U16_LENGTH(c); 3281 if (c == kQuote) { 3282 c = pattern.char32At(i); 3283 i += U16_LENGTH(c); 3284 int beginIdx = affix.length(); 3285 switch (c) { 3286 case kCurrencySign: { 3287 // As of ICU 2.2 we use the currency object, and 3288 // ignore the currency symbols in the DFS, unless 3289 // we have a null currency object. This occurs if 3290 // resurrecting a pre-2.2 object or if the user 3291 // sets a custom DFS. 3292 UBool intl = i<pattern.length() && 3293 pattern.char32At(i) == kCurrencySign; 3294 UBool plural = FALSE; 3295 if (intl) { 3296 ++i; 3297 plural = i<pattern.length() && 3298 pattern.char32At(i) == kCurrencySign; 3299 if (plural) { 3300 intl = FALSE; 3301 ++i; 3302 } 3303 } 3304 const UChar* currencyUChars = getCurrency(); 3305 if (currencyUChars[0] != 0) { 3306 UErrorCode ec = U_ZERO_ERROR; 3307 if (plural && pluralCount != NULL) { 3308 // plural name is only needed when pluralCount != null, 3309 // which means when formatting currency plural names. 3310 // For other cases, pluralCount == null, 3311 // and plural names are not needed. 3312 int32_t len; 3313 CharString pluralCountChar; 3314 pluralCountChar.appendInvariantChars(*pluralCount, ec); 3315 UBool isChoiceFormat; 3316 const UChar* s = ucurr_getPluralName(currencyUChars, 3317 fSymbols != NULL ? fSymbols->getLocale().getName() : 3318 Locale::getDefault().getName(), &isChoiceFormat, 3319 pluralCountChar.data(), &len, &ec); 3320 affix += UnicodeString(s, len); 3321 handler.addAttribute(kCurrencyField, beginIdx, affix.length()); 3322 } else if(intl) { 3323 affix.append(currencyUChars, -1); 3324 handler.addAttribute(kCurrencyField, beginIdx, affix.length()); 3325 } else { 3326 int32_t len; 3327 UBool isChoiceFormat; 3328 // If fSymbols is NULL, use default locale 3329 const UChar* s = ucurr_getName(currencyUChars, 3330 fSymbols != NULL ? fSymbols->getLocale().getName() : Locale::getDefault().getName(), 3331 UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec); 3332 if (isChoiceFormat) { 3333 // Two modes here: If doFormat is false, we set up 3334 // currencyChoice. If doFormat is true, we use the 3335 // previously created currencyChoice to format the 3336 // value in digitList. 3337 if (!doFormat) { 3338 // If the currency is handled by a ChoiceFormat, 3339 // then we're not going to use the expanded 3340 // patterns. Instantiate the ChoiceFormat and 3341 // return. 3342 if (fCurrencyChoice == NULL) { 3343 // TODO Replace double-check with proper thread-safe code 3344 ChoiceFormat* fmt = new ChoiceFormat(UnicodeString(s), ec); 3345 if (U_SUCCESS(ec)) { 3346 umtx_lock(NULL); 3347 if (fCurrencyChoice == NULL) { 3348 // Cast away const 3349 ((DecimalFormat*)this)->fCurrencyChoice = fmt; 3350 fmt = NULL; 3351 } 3352 umtx_unlock(NULL); 3353 delete fmt; 3354 } 3355 } 3356 // We could almost return null or "" here, since the 3357 // expanded affixes are almost not used at all 3358 // in this situation. However, one method -- 3359 // toPattern() -- still does use the expanded 3360 // affixes, in order to set up a padding 3361 // pattern. We use the CURRENCY_SIGN as a 3362 // placeholder. 3363 affix.append(kCurrencySign); 3364 } else { 3365 if (fCurrencyChoice != NULL) { 3366 FieldPosition pos(0); // ignored 3367 if (number < 0) { 3368 number = -number; 3369 } 3370 fCurrencyChoice->format(number, affix, pos); 3371 } else { 3372 // We only arrive here if the currency choice 3373 // format in the locale data is INVALID. 3374 affix.append(currencyUChars, -1); 3375 handler.addAttribute(kCurrencyField, beginIdx, affix.length()); 3376 } 3377 } 3378 continue; 3379 } 3380 affix += UnicodeString(s, len); 3381 handler.addAttribute(kCurrencyField, beginIdx, affix.length()); 3382 } 3383 } else { 3384 if(intl) { 3385 affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 3386 } else { 3387 affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); 3388 } 3389 handler.addAttribute(kCurrencyField, beginIdx, affix.length()); 3390 } 3391 break; 3392 } 3393 case kPatternPercent: 3394 affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 3395 handler.addAttribute(kPercentField, beginIdx, affix.length()); 3396 break; 3397 case kPatternPerMill: 3398 affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 3399 handler.addAttribute(kPermillField, beginIdx, affix.length()); 3400 break; 3401 case kPatternPlus: 3402 affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 3403 handler.addAttribute(kSignField, beginIdx, affix.length()); 3404 break; 3405 case kPatternMinus: 3406 affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 3407 handler.addAttribute(kSignField, beginIdx, affix.length()); 3408 break; 3409 default: 3410 affix.append(c); 3411 break; 3412 } 3413 } 3414 else { 3415 affix.append(c); 3416 } 3417 } 3418 } 3419 3420 /** 3421 * Append an affix to the given StringBuffer. 3422 * @param buf buffer to append to 3423 * @param isNegative 3424 * @param isPrefix 3425 */ 3426 int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, 3427 FieldPositionHandler& handler, 3428 UBool isNegative, UBool isPrefix) const { 3429 // plural format precedes choice format 3430 if (fCurrencyChoice != 0 && 3431 fCurrencySignCount != fgCurrencySignCountInPluralFormat) { 3432 const UnicodeString* affixPat; 3433 if (isPrefix) { 3434 affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern; 3435 } else { 3436 affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern; 3437 } 3438 if (affixPat) { 3439 UnicodeString affixBuf; 3440 expandAffix(*affixPat, affixBuf, number, handler, TRUE, NULL); 3441 buf.append(affixBuf); 3442 return affixBuf.length(); 3443 } 3444 // else someone called a function that reset the pattern. 3445 } 3446 3447 const UnicodeString* affix; 3448 if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) { 3449 UnicodeString pluralCount = fCurrencyPluralInfo->getPluralRules()->select(number); 3450 AffixesForCurrency* oneSet; 3451 if (fStyle == UNUM_CURRENCY_PLURAL) { 3452 oneSet = (AffixesForCurrency*)fPluralAffixesForCurrency->get(pluralCount); 3453 } else { 3454 oneSet = (AffixesForCurrency*)fAffixesForCurrency->get(pluralCount); 3455 } 3456 if (isPrefix) { 3457 affix = isNegative ? &oneSet->negPrefixForCurrency : 3458 &oneSet->posPrefixForCurrency; 3459 } else { 3460 affix = isNegative ? &oneSet->negSuffixForCurrency : 3461 &oneSet->posSuffixForCurrency; 3462 } 3463 } else { 3464 if (isPrefix) { 3465 affix = isNegative ? &fNegativePrefix : &fPositivePrefix; 3466 } else { 3467 affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix; 3468 } 3469 } 3470 3471 int32_t begin = (int) buf.length(); 3472 3473 buf.append(*affix); 3474 3475 if (handler.isRecording()) { 3476 int32_t offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol)); 3477 if (offset > -1) { 3478 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); 3479 handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length()); 3480 } 3481 3482 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); 3483 if (offset > -1) { 3484 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 3485 handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length()); 3486 } 3487 3488 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)); 3489 if (offset > -1) { 3490 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 3491 handler.addAttribute(kSignField, begin + offset, begin + offset + aff.length()); 3492 } 3493 3494 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)); 3495 if (offset > -1) { 3496 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 3497 handler.addAttribute(kPercentField, begin + offset, begin + offset + aff.length()); 3498 } 3499 3500 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)); 3501 if (offset > -1) { 3502 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 3503 handler.addAttribute(kPermillField, begin + offset, begin + offset + aff.length()); 3504 } 3505 } 3506 return affix->length(); 3507 } 3508 3509 /** 3510 * Appends an affix pattern to the given StringBuffer, quoting special 3511 * characters as needed. Uses the internal affix pattern, if that exists, 3512 * or the literal affix, if the internal affix pattern is null. The 3513 * appended string will generate the same affix pattern (or literal affix) 3514 * when passed to toPattern(). 3515 * 3516 * @param appendTo the affix string is appended to this 3517 * @param affixPattern a pattern such as fPosPrefixPattern; may be null 3518 * @param expAffix a corresponding expanded affix, such as fPositivePrefix. 3519 * Ignored unless affixPattern is null. If affixPattern is null, then 3520 * expAffix is appended as a literal affix. 3521 * @param localized true if the appended pattern should contain localized 3522 * pattern characters; otherwise, non-localized pattern chars are appended 3523 */ 3524 void DecimalFormat::appendAffixPattern(UnicodeString& appendTo, 3525 const UnicodeString* affixPattern, 3526 const UnicodeString& expAffix, 3527 UBool localized) const { 3528 if (affixPattern == 0) { 3529 appendAffixPattern(appendTo, expAffix, localized); 3530 } else { 3531 int i; 3532 for (int pos=0; pos<affixPattern->length(); pos=i) { 3533 i = affixPattern->indexOf(kQuote, pos); 3534 if (i < 0) { 3535 UnicodeString s; 3536 affixPattern->extractBetween(pos, affixPattern->length(), s); 3537 appendAffixPattern(appendTo, s, localized); 3538 break; 3539 } 3540 if (i > pos) { 3541 UnicodeString s; 3542 affixPattern->extractBetween(pos, i, s); 3543 appendAffixPattern(appendTo, s, localized); 3544 } 3545 UChar32 c = affixPattern->char32At(++i); 3546 ++i; 3547 if (c == kQuote) { 3548 appendTo.append(c).append(c); 3549 // Fall through and append another kQuote below 3550 } else if (c == kCurrencySign && 3551 i<affixPattern->length() && 3552 affixPattern->char32At(i) == kCurrencySign) { 3553 ++i; 3554 appendTo.append(c).append(c); 3555 } else if (localized) { 3556 switch (c) { 3557 case kPatternPercent: 3558 appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); 3559 break; 3560 case kPatternPerMill: 3561 appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); 3562 break; 3563 case kPatternPlus: 3564 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 3565 break; 3566 case kPatternMinus: 3567 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); 3568 break; 3569 default: 3570 appendTo.append(c); 3571 } 3572 } else { 3573 appendTo.append(c); 3574 } 3575 } 3576 } 3577 } 3578 3579 /** 3580 * Append an affix to the given StringBuffer, using quotes if 3581 * there are special characters. Single quotes themselves must be 3582 * escaped in either case. 3583 */ 3584 void 3585 DecimalFormat::appendAffixPattern(UnicodeString& appendTo, 3586 const UnicodeString& affix, 3587 UBool localized) const { 3588 UBool needQuote; 3589 if(localized) { 3590 needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0 3591 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0 3592 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0 3593 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0 3594 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0 3595 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0 3596 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0 3597 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0 3598 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0 3599 || affix.indexOf(kCurrencySign) >= 0; 3600 } 3601 else { 3602 needQuote = affix.indexOf(kPatternZeroDigit) >= 0 3603 || affix.indexOf(kPatternGroupingSeparator) >= 0 3604 || affix.indexOf(kPatternDecimalSeparator) >= 0 3605 || affix.indexOf(kPatternPercent) >= 0 3606 || affix.indexOf(kPatternPerMill) >= 0 3607 || affix.indexOf(kPatternDigit) >= 0 3608 || affix.indexOf(kPatternSeparator) >= 0 3609 || affix.indexOf(kPatternExponent) >= 0 3610 || affix.indexOf(kPatternPlus) >= 0 3611 || affix.indexOf(kPatternMinus) >= 0 3612 || affix.indexOf(kCurrencySign) >= 0; 3613 } 3614 if (needQuote) 3615 appendTo += (UChar)0x0027 /*'\''*/; 3616 if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0) 3617 appendTo += affix; 3618 else { 3619 for (int32_t j = 0; j < affix.length(); ) { 3620 UChar32 c = affix.char32At(j); 3621 j += U16_LENGTH(c); 3622 appendTo += c; 3623 if (c == 0x0027 /*'\''*/) 3624 appendTo += c; 3625 } 3626 } 3627 if (needQuote) 3628 appendTo += (UChar)0x0027 /*'\''*/; 3629 } 3630 3631 //------------------------------------------------------------------------------ 3632 3633 UnicodeString& 3634 DecimalFormat::toPattern(UnicodeString& result, UBool localized) const 3635 { 3636 if (fStyle == UNUM_CURRENCY_PLURAL) { 3637 // the prefix or suffix pattern might not be defined yet, 3638 // so they can not be synthesized, 3639 // instead, get them directly. 3640 // but it might not be the actual pattern used in formatting. 3641 // the actual pattern used in formatting depends on the 3642 // formatted number's plural count. 3643 result = fFormatPattern; 3644 return result; 3645 } 3646 result.remove(); 3647 UChar32 zero, sigDigit = kPatternSignificantDigit; 3648 UnicodeString digit, group; 3649 int32_t i; 3650 int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits 3651 UnicodeString roundingDigits; 3652 int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1; 3653 UnicodeString padSpec; 3654 UBool useSigDig = areSignificantDigitsUsed(); 3655 3656 if (localized) { 3657 digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)); 3658 group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)); 3659 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 3660 if (useSigDig) { 3661 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0); 3662 } 3663 } 3664 else { 3665 digit.append((UChar)kPatternDigit); 3666 group.append((UChar)kPatternGroupingSeparator); 3667 zero = (UChar32)kPatternZeroDigit; 3668 } 3669 if (fFormatWidth > 0) { 3670 if (localized) { 3671 padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol)); 3672 } 3673 else { 3674 padSpec.append((UChar)kPatternPadEscape); 3675 } 3676 padSpec.append(fPad); 3677 } 3678 if (fRoundingIncrement != NULL) { 3679 for(i=0; i<fRoundingIncrement->getCount(); ++i) { 3680 roundingDigits.append(zero+(fRoundingIncrement->getDigitValue(i))); // Convert to Unicode digit 3681 } 3682 roundingDecimalPos = fRoundingIncrement->getDecimalAt(); 3683 } 3684 for (int32_t part=0; part<2; ++part) { 3685 if (padPos == kPadBeforePrefix) { 3686 result.append(padSpec); 3687 } 3688 appendAffixPattern(result, 3689 (part==0 ? fPosPrefixPattern : fNegPrefixPattern), 3690 (part==0 ? fPositivePrefix : fNegativePrefix), 3691 localized); 3692 if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) { 3693 result.append(padSpec); 3694 } 3695 int32_t sub0Start = result.length(); 3696 int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0; 3697 if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) { 3698 g += fGroupingSize2; 3699 } 3700 int32_t maxDig = 0, minDig = 0, maxSigDig = 0; 3701 if (useSigDig) { 3702 minDig = getMinimumSignificantDigits(); 3703 maxDig = maxSigDig = getMaximumSignificantDigits(); 3704 } else { 3705 minDig = getMinimumIntegerDigits(); 3706 maxDig = getMaximumIntegerDigits(); 3707 } 3708 if (fUseExponentialNotation) { 3709 if (maxDig > kMaxScientificIntegerDigits) { 3710 maxDig = 1; 3711 } 3712 } else if (useSigDig) { 3713 maxDig = _max(maxDig, g+1); 3714 } else { 3715 maxDig = _max(_max(g, getMinimumIntegerDigits()), 3716 roundingDecimalPos) + 1; 3717 } 3718 for (i = maxDig; i > 0; --i) { 3719 if (!fUseExponentialNotation && i<maxDig && 3720 isGroupingPosition(i)) { 3721 result.append(group); 3722 } 3723 if (useSigDig) { 3724 // #@,@### (maxSigDig == 5, minSigDig == 2) 3725 // 65 4321 (1-based pos, count from the right) 3726 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig) 3727 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig 3728 if (maxSigDig >= i && i > (maxSigDig - minDig)) { 3729 result.append(sigDigit); 3730 } else { 3731 result.append(digit); 3732 } 3733 } else { 3734 if (! roundingDigits.isEmpty()) { 3735 int32_t pos = roundingDecimalPos - i; 3736 if (pos >= 0 && pos < roundingDigits.length()) { 3737 result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero)); 3738 continue; 3739 } 3740 } 3741 if (i<=minDig) { 3742 result.append(zero); 3743 } else { 3744 result.append(digit); 3745 } 3746 } 3747 } 3748 if (!useSigDig) { 3749 if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) { 3750 if (localized) { 3751 result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); 3752 } 3753 else { 3754 result.append((UChar)kPatternDecimalSeparator); 3755 } 3756 } 3757 int32_t pos = roundingDecimalPos; 3758 for (i = 0; i < getMaximumFractionDigits(); ++i) { 3759 if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) { 3760 if (pos < 0) { 3761 result.append(zero); 3762 } 3763 else { 3764 result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero)); 3765 } 3766 ++pos; 3767 continue; 3768 } 3769 if (i<getMinimumFractionDigits()) { 3770 result.append(zero); 3771 } 3772 else { 3773 result.append(digit); 3774 } 3775 } 3776 } 3777 if (fUseExponentialNotation) { 3778 if (localized) { 3779 result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); 3780 } 3781 else { 3782 result.append((UChar)kPatternExponent); 3783 } 3784 if (fExponentSignAlwaysShown) { 3785 if (localized) { 3786 result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); 3787 } 3788 else { 3789 result.append((UChar)kPatternPlus); 3790 } 3791 } 3792 for (i=0; i<fMinExponentDigits; ++i) { 3793 result.append(zero); 3794 } 3795 } 3796 if (! padSpec.isEmpty() && !fUseExponentialNotation) { 3797 int32_t add = fFormatWidth - result.length() + sub0Start 3798 - ((part == 0) 3799 ? fPositivePrefix.length() + fPositiveSuffix.length() 3800 : fNegativePrefix.length() + fNegativeSuffix.length()); 3801 while (add > 0) { 3802 result.insert(sub0Start, digit); 3803 ++maxDig; 3804 --add; 3805 // Only add a grouping separator if we have at least 3806 // 2 additional characters to be added, so we don't 3807 // end up with ",###". 3808 if (add>1 && isGroupingPosition(maxDig)) { 3809 result.insert(sub0Start, group); 3810 --add; 3811 } 3812 } 3813 } 3814 if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) { 3815 result.append(padSpec); 3816 } 3817 if (part == 0) { 3818 appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized); 3819 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { 3820 result.append(padSpec); 3821 } 3822 UBool isDefault = FALSE; 3823 if ((fNegSuffixPattern == fPosSuffixPattern && // both null 3824 fNegativeSuffix == fPositiveSuffix) 3825 || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 && 3826 *fNegSuffixPattern == *fPosSuffixPattern)) 3827 { 3828 if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL) 3829 { 3830 int32_t length = fPosPrefixPattern->length(); 3831 isDefault = fNegPrefixPattern->length() == (length+2) && 3832 (*fNegPrefixPattern)[(int32_t)0] == kQuote && 3833 (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus && 3834 fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0; 3835 } 3836 if (!isDefault && 3837 fNegPrefixPattern == NULL && fPosPrefixPattern == NULL) 3838 { 3839 int32_t length = fPositivePrefix.length(); 3840 isDefault = fNegativePrefix.length() == (length+1) && 3841 fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 && 3842 fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0; 3843 } 3844 } 3845 if (isDefault) { 3846 break; // Don't output default negative subpattern 3847 } else { 3848 if (localized) { 3849 result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol); 3850 } 3851 else { 3852 result.append((UChar)kPatternSeparator); 3853 } 3854 } 3855 } else { 3856 appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized); 3857 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { 3858 result.append(padSpec); 3859 } 3860 } 3861 } 3862 3863 return result; 3864 } 3865 3866 //------------------------------------------------------------------------------ 3867 3868 void 3869 DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) 3870 { 3871 UParseError parseError; 3872 applyPattern(pattern, FALSE, parseError, status); 3873 } 3874 3875 //------------------------------------------------------------------------------ 3876 3877 void 3878 DecimalFormat::applyPattern(const UnicodeString& pattern, 3879 UParseError& parseError, 3880 UErrorCode& status) 3881 { 3882 applyPattern(pattern, FALSE, parseError, status); 3883 } 3884 //------------------------------------------------------------------------------ 3885 3886 void 3887 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status) 3888 { 3889 UParseError parseError; 3890 applyPattern(pattern, TRUE,parseError,status); 3891 } 3892 3893 //------------------------------------------------------------------------------ 3894 3895 void 3896 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, 3897 UParseError& parseError, 3898 UErrorCode& status) 3899 { 3900 applyPattern(pattern, TRUE,parseError,status); 3901 } 3902 3903 //------------------------------------------------------------------------------ 3904 3905 void 3906 DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern, 3907 UBool localized, 3908 UParseError& parseError, 3909 UErrorCode& status) 3910 { 3911 if (U_FAILURE(status)) 3912 { 3913 return; 3914 } 3915 // Clear error struct 3916 parseError.offset = -1; 3917 parseError.preContext[0] = parseError.postContext[0] = (UChar)0; 3918 3919 // Set the significant pattern symbols 3920 UChar32 zeroDigit = kPatternZeroDigit; // '0' 3921 UChar32 sigDigit = kPatternSignificantDigit; // '@' 3922 UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator); 3923 UnicodeString decimalSeparator ((UChar)kPatternDecimalSeparator); 3924 UnicodeString percent ((UChar)kPatternPercent); 3925 UnicodeString perMill ((UChar)kPatternPerMill); 3926 UnicodeString digit ((UChar)kPatternDigit); // '#' 3927 UnicodeString separator ((UChar)kPatternSeparator); 3928 UnicodeString exponent ((UChar)kPatternExponent); 3929 UnicodeString plus ((UChar)kPatternPlus); 3930 UnicodeString minus ((UChar)kPatternMinus); 3931 UnicodeString padEscape ((UChar)kPatternPadEscape); 3932 // Substitute with the localized symbols if necessary 3933 if (localized) { 3934 zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); 3935 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0); 3936 groupingSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)); 3937 decimalSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)); 3938 percent. remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)); 3939 perMill. remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)); 3940 digit. remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)); 3941 separator. remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)); 3942 exponent. remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol)); 3943 plus. remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)); 3944 minus. remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)); 3945 padEscape. remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol)); 3946 } 3947 UChar nineDigit = (UChar)(zeroDigit + 9); 3948 int32_t digitLen = digit.length(); 3949 int32_t groupSepLen = groupingSeparator.length(); 3950 int32_t decimalSepLen = decimalSeparator.length(); 3951 3952 int32_t pos = 0; 3953 int32_t patLen = pattern.length(); 3954 // Part 0 is the positive pattern. Part 1, if present, is the negative 3955 // pattern. 3956 for (int32_t part=0; part<2 && pos<patLen; ++part) { 3957 // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 3958 // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is 3959 // between the prefix and suffix, and consists of pattern 3960 // characters. In the prefix and suffix, percent, perMill, and 3961 // currency symbols are recognized and translated. 3962 int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0; 3963 3964 // It's important that we don't change any fields of this object 3965 // prematurely. We set the following variables for the multiplier, 3966 // grouping, etc., and then only change the actual object fields if 3967 // everything parses correctly. This also lets us register 3968 // the data from part 0 and ignore the part 1, except for the 3969 // prefix and suffix. 3970 UnicodeString prefix; 3971 UnicodeString suffix; 3972 int32_t decimalPos = -1; 3973 int32_t multiplier = 1; 3974 int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0; 3975 int8_t groupingCount = -1; 3976 int8_t groupingCount2 = -1; 3977 int32_t padPos = -1; 3978 UChar32 padChar = 0; 3979 int32_t roundingPos = -1; 3980 DigitList roundingInc; 3981 int8_t expDigits = -1; 3982 UBool expSignAlways = FALSE; 3983 3984 // The affix is either the prefix or the suffix. 3985 UnicodeString* affix = &prefix; 3986 3987 int32_t start = pos; 3988 UBool isPartDone = FALSE; 3989 UChar32 ch; 3990 3991 for (; !isPartDone && pos < patLen; ) { 3992 // Todo: account for surrogate pairs 3993 ch = pattern.char32At(pos); 3994 switch (subpart) { 3995 case 0: // Pattern proper subpart (between prefix & suffix) 3996 // Process the digits, decimal, and grouping characters. We 3997 // record five pieces of information. We expect the digits 3998 // to occur in the pattern ####00.00####, and we record the 3999 // number of left digits, zero (central) digits, and right 4000 // digits. The position of the last grouping character is 4001 // recorded (should be somewhere within the first two blocks 4002 // of characters), as is the position of the decimal point, 4003 // if any (should be in the zero digits). If there is no 4004 // decimal point, then there should be no right digits. 4005 if (pattern.compare(pos, digitLen, digit) == 0) { 4006 if (zeroDigitCount > 0 || sigDigitCount > 0) { 4007 ++digitRightCount; 4008 } else { 4009 ++digitLeftCount; 4010 } 4011 if (groupingCount >= 0 && decimalPos < 0) { 4012 ++groupingCount; 4013 } 4014 pos += digitLen; 4015 } else if ((ch >= zeroDigit && ch <= nineDigit) || 4016 ch == sigDigit) { 4017 if (digitRightCount > 0) { 4018 // Unexpected '0' 4019 debug("Unexpected '0'") 4020 status = U_UNEXPECTED_TOKEN; 4021 syntaxError(pattern,pos,parseError); 4022 return; 4023 } 4024 if (ch == sigDigit) { 4025 ++sigDigitCount; 4026 } else { 4027 ++zeroDigitCount; 4028 if (ch != zeroDigit && roundingPos < 0) { 4029 roundingPos = digitLeftCount + zeroDigitCount; 4030 } 4031 if (roundingPos >= 0) { 4032 roundingInc.append((char)(ch - zeroDigit + '0')); 4033 } 4034 } 4035 if (groupingCount >= 0 && decimalPos < 0) { 4036 ++groupingCount; 4037 } 4038 pos += U16_LENGTH(ch); 4039 } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) { 4040 if (decimalPos >= 0) { 4041 // Grouping separator after decimal 4042 debug("Grouping separator after decimal") 4043 status = U_UNEXPECTED_TOKEN; 4044 syntaxError(pattern,pos,parseError); 4045 return; 4046 } 4047 groupingCount2 = groupingCount; 4048 groupingCount = 0; 4049 pos += groupSepLen; 4050 } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) { 4051 if (decimalPos >= 0) { 4052 // Multiple decimal separators 4053 debug("Multiple decimal separators") 4054 status = U_MULTIPLE_DECIMAL_SEPARATORS; 4055 syntaxError(pattern,pos,parseError); 4056 return; 4057 } 4058 // Intentionally incorporate the digitRightCount, 4059 // even though it is illegal for this to be > 0 4060 // at this point. We check pattern syntax below. 4061 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount; 4062 pos += decimalSepLen; 4063 } else { 4064 if (pattern.compare(pos, exponent.length(), exponent) == 0) { 4065 if (expDigits >= 0) { 4066 // Multiple exponential symbols 4067 debug("Multiple exponential symbols") 4068 status = U_MULTIPLE_EXPONENTIAL_SYMBOLS; 4069 syntaxError(pattern,pos,parseError); 4070 return; 4071 } 4072 if (groupingCount >= 0) { 4073 // Grouping separator in exponential pattern 4074 debug("Grouping separator in exponential pattern") 4075 status = U_MALFORMED_EXPONENTIAL_PATTERN; 4076 syntaxError(pattern,pos,parseError); 4077 return; 4078 } 4079 pos += exponent.length(); 4080 // Check for positive prefix 4081 if (pos < patLen 4082 && pattern.compare(pos, plus.length(), plus) == 0) { 4083 expSignAlways = TRUE; 4084 pos += plus.length(); 4085 } 4086 // Use lookahead to parse out the exponential part of the 4087 // pattern, then jump into suffix subpart. 4088 expDigits = 0; 4089 while (pos < patLen && 4090 pattern.char32At(pos) == zeroDigit) { 4091 ++expDigits; 4092 pos += U16_LENGTH(zeroDigit); 4093 } 4094 4095 // 1. Require at least one mantissa pattern digit 4096 // 2. Disallow "#+ @" in mantissa 4097 // 3. Require at least one exponent pattern digit 4098 if (((digitLeftCount + zeroDigitCount) < 1 && 4099 (sigDigitCount + digitRightCount) < 1) || 4100 (sigDigitCount > 0 && digitLeftCount > 0) || 4101 expDigits < 1) { 4102 // Malformed exponential pattern 4103 debug("Malformed exponential pattern") 4104 status = U_MALFORMED_EXPONENTIAL_PATTERN; 4105 syntaxError(pattern,pos,parseError); 4106 return; 4107 } 4108 } 4109 // Transition to suffix subpart 4110 subpart = 2; // suffix subpart 4111 affix = &suffix; 4112 sub0Limit = pos; 4113 continue; 4114 } 4115 break; 4116 case 1: // Prefix subpart 4117 case 2: // Suffix subpart 4118 // Process the prefix / suffix characters 4119 // Process unquoted characters seen in prefix or suffix 4120 // subpart. 4121 4122 // Several syntax characters implicitly begins the 4123 // next subpart if we are in the prefix; otherwise 4124 // they are illegal if unquoted. 4125 if (!pattern.compare(pos, digitLen, digit) || 4126 !pattern.compare(pos, groupSepLen, groupingSeparator) || 4127 !pattern.compare(pos, decimalSepLen, decimalSeparator) || 4128 (ch >= zeroDigit && ch <= nineDigit) || 4129 ch == sigDigit) { 4130 if (subpart == 1) { // prefix subpart 4131 subpart = 0; // pattern proper subpart 4132 sub0Start = pos; // Reprocess this character 4133 continue; 4134 } else { 4135 status = U_UNQUOTED_SPECIAL; 4136 syntaxError(pattern,pos,parseError); 4137 return; 4138 } 4139 } else if (ch == kCurrencySign) { 4140 affix->append(kQuote); // Encode currency 4141 // Use lookahead to determine if the currency sign is 4142 // doubled or not. 4143 U_ASSERT(U16_LENGTH(kCurrencySign) == 1); 4144 if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) { 4145 affix->append(kCurrencySign); 4146 ++pos; // Skip over the doubled character 4147 if ((pos+1) < pattern.length() && 4148 pattern[pos+1] == kCurrencySign) { 4149 affix->append(kCurrencySign); 4150 ++pos; // Skip over the doubled character 4151 fCurrencySignCount = fgCurrencySignCountInPluralFormat; 4152 } else { 4153 fCurrencySignCount = fgCurrencySignCountInISOFormat; 4154 } 4155 } else { 4156 fCurrencySignCount = fgCurrencySignCountInSymbolFormat; 4157 } 4158 // Fall through to append(ch) 4159 } else if (ch == kQuote) { 4160 // A quote outside quotes indicates either the opening 4161 // quote or two quotes, which is a quote literal. That is, 4162 // we have the first quote in 'do' or o''clock. 4163 U_ASSERT(U16_LENGTH(kQuote) == 1); 4164 ++pos; 4165 if (pos < pattern.length() && pattern[pos] == kQuote) { 4166 affix->append(kQuote); // Encode quote 4167 // Fall through to append(ch) 4168 } else { 4169 subpart += 2; // open quote 4170 continue; 4171 } 4172 } else if (pattern.compare(pos, separator.length(), separator) == 0) { 4173 // Don't allow separators in the prefix, and don't allow 4174 // separators in the second pattern (part == 1). 4175 if (subpart == 1 || part == 1) { 4176 // Unexpected separator 4177 debug("Unexpected separator") 4178 status = U_UNEXPECTED_TOKEN; 4179 syntaxError(pattern,pos,parseError); 4180 return; 4181 } 4182 sub2Limit = pos; 4183 isPartDone = TRUE; // Go to next part 4184 pos += separator.length(); 4185 break; 4186 } else if (pattern.compare(pos, percent.length(), percent) == 0) { 4187 // Next handle characters which are appended directly. 4188 if (multiplier != 1) { 4189 // Too many percent/perMill characters 4190 debug("Too many percent characters") 4191 status = U_MULTIPLE_PERCENT_SYMBOLS; 4192 syntaxError(pattern,pos,parseError); 4193 return; 4194 } 4195 affix->append(kQuote); // Encode percent/perMill 4196 affix->append(kPatternPercent); // Use unlocalized pattern char 4197 multiplier = 100; 4198 pos += percent.length(); 4199 break; 4200 } else if (pattern.compare(pos, perMill.length(), perMill) == 0) { 4201 // Next handle characters which are appended directly. 4202 if (multiplier != 1) { 4203 // Too many percent/perMill characters 4204 debug("Too many perMill characters") 4205 status = U_MULTIPLE_PERMILL_SYMBOLS; 4206 syntaxError(pattern,pos,parseError); 4207 return; 4208 } 4209 affix->append(kQuote); // Encode percent/perMill 4210 affix->append(kPatternPerMill); // Use unlocalized pattern char 4211 multiplier = 1000; 4212 pos += perMill.length(); 4213 break; 4214 } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) { 4215 if (padPos >= 0 || // Multiple pad specifiers 4216 (pos+1) == pattern.length()) { // Nothing after padEscape 4217 debug("Multiple pad specifiers") 4218 status = U_MULTIPLE_PAD_SPECIFIERS; 4219 syntaxError(pattern,pos,parseError); 4220 return; 4221 } 4222 padPos = pos; 4223 pos += padEscape.length(); 4224 padChar = pattern.char32At(pos); 4225 pos += U16_LENGTH(padChar); 4226 break; 4227 } else if (pattern.compare(pos, minus.length(), minus) == 0) { 4228 affix->append(kQuote); // Encode minus 4229 affix->append(kPatternMinus); 4230 pos += minus.length(); 4231 break; 4232 } else if (pattern.compare(pos, plus.length(), plus) == 0) { 4233 affix->append(kQuote); // Encode plus 4234 affix->append(kPatternPlus); 4235 pos += plus.length(); 4236 break; 4237 } 4238 // Unquoted, non-special characters fall through to here, as 4239 // well as other code which needs to append something to the 4240 // affix. 4241 affix->append(ch); 4242 pos += U16_LENGTH(ch); 4243 break; 4244 case 3: // Prefix subpart, in quote 4245 case 4: // Suffix subpart, in quote 4246 // A quote within quotes indicates either the closing 4247 // quote or two quotes, which is a quote literal. That is, 4248 // we have the second quote in 'do' or 'don''t'. 4249 if (ch == kQuote) { 4250 ++pos; 4251 if (pos < pattern.length() && pattern[pos] == kQuote) { 4252 affix->append(kQuote); // Encode quote 4253 // Fall through to append(ch) 4254 } else { 4255 subpart -= 2; // close quote 4256 continue; 4257 } 4258 } 4259 affix->append(ch); 4260 pos += U16_LENGTH(ch); 4261 break; 4262 } 4263 } 4264 4265 if (sub0Limit == 0) { 4266 sub0Limit = pattern.length(); 4267 } 4268 4269 if (sub2Limit == 0) { 4270 sub2Limit = pattern.length(); 4271 } 4272 4273 /* Handle patterns with no '0' pattern character. These patterns 4274 * are legal, but must be recodified to make sense. "##.###" -> 4275 * "#0.###". ".###" -> ".0##". 4276 * 4277 * We allow patterns of the form "####" to produce a zeroDigitCount 4278 * of zero (got that?); although this seems like it might make it 4279 * possible for format() to produce empty strings, format() checks 4280 * for this condition and outputs a zero digit in this situation. 4281 * Having a zeroDigitCount of zero yields a minimum integer digits 4282 * of zero, which allows proper round-trip patterns. We don't want 4283 * "#" to become "#0" when toPattern() is called (even though that's 4284 * what it really is, semantically). 4285 */ 4286 if (zeroDigitCount == 0 && sigDigitCount == 0 && 4287 digitLeftCount > 0 && decimalPos >= 0) { 4288 // Handle "###.###" and "###." and ".###" 4289 int n = decimalPos; 4290 if (n == 0) 4291 ++n; // Handle ".###" 4292 digitRightCount = digitLeftCount - n; 4293 digitLeftCount = n - 1; 4294 zeroDigitCount = 1; 4295 } 4296 4297 // Do syntax checking on the digits, decimal points, and quotes. 4298 if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) || 4299 (decimalPos >= 0 && 4300 (sigDigitCount > 0 || 4301 decimalPos < digitLeftCount || 4302 decimalPos > (digitLeftCount + zeroDigitCount))) || 4303 groupingCount == 0 || groupingCount2 == 0 || 4304 (sigDigitCount > 0 && zeroDigitCount > 0) || 4305 subpart > 2) 4306 { // subpart > 2 == unmatched quote 4307 debug("Syntax error") 4308 status = U_PATTERN_SYNTAX_ERROR; 4309 syntaxError(pattern,pos,parseError); 4310 return; 4311 } 4312 4313 // Make sure pad is at legal position before or after affix. 4314 if (padPos >= 0) { 4315 if (padPos == start) { 4316 padPos = kPadBeforePrefix; 4317 } else if (padPos+2 == sub0Start) { 4318 padPos = kPadAfterPrefix; 4319 } else if (padPos == sub0Limit) { 4320 padPos = kPadBeforeSuffix; 4321 } else if (padPos+2 == sub2Limit) { 4322 padPos = kPadAfterSuffix; 4323 } else { 4324 // Illegal pad position 4325 debug("Illegal pad position") 4326 status = U_ILLEGAL_PAD_POSITION; 4327 syntaxError(pattern,pos,parseError); 4328 return; 4329 } 4330 } 4331 4332 if (part == 0) { 4333 delete fPosPrefixPattern; 4334 delete fPosSuffixPattern; 4335 delete fNegPrefixPattern; 4336 delete fNegSuffixPattern; 4337 fPosPrefixPattern = new UnicodeString(prefix); 4338 /* test for NULL */ 4339 if (fPosPrefixPattern == 0) { 4340 status = U_MEMORY_ALLOCATION_ERROR; 4341 return; 4342 } 4343 fPosSuffixPattern = new UnicodeString(suffix); 4344 /* test for NULL */ 4345 if (fPosSuffixPattern == 0) { 4346 status = U_MEMORY_ALLOCATION_ERROR; 4347 delete fPosPrefixPattern; 4348 return; 4349 } 4350 fNegPrefixPattern = 0; 4351 fNegSuffixPattern = 0; 4352 4353 fUseExponentialNotation = (expDigits >= 0); 4354 if (fUseExponentialNotation) { 4355 fMinExponentDigits = expDigits; 4356 } 4357 fExponentSignAlwaysShown = expSignAlways; 4358 int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount; 4359 // The effectiveDecimalPos is the position the decimal is at or 4360 // would be at if there is no decimal. Note that if 4361 // decimalPos<0, then digitTotalCount == digitLeftCount + 4362 // zeroDigitCount. 4363 int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount; 4364 UBool isSigDig = (sigDigitCount > 0); 4365 setSignificantDigitsUsed(isSigDig); 4366 if (isSigDig) { 4367 setMinimumSignificantDigits(sigDigitCount); 4368 setMaximumSignificantDigits(sigDigitCount + digitRightCount); 4369 } else { 4370 int32_t minInt = effectiveDecimalPos - digitLeftCount; 4371 setMinimumIntegerDigits(minInt); 4372 setMaximumIntegerDigits(fUseExponentialNotation 4373 ? digitLeftCount + getMinimumIntegerDigits() 4374 : kDoubleIntegerDigits); 4375 setMaximumFractionDigits(decimalPos >= 0 4376 ? (digitTotalCount - decimalPos) : 0); 4377 setMinimumFractionDigits(decimalPos >= 0 4378 ? (digitLeftCount + zeroDigitCount - decimalPos) : 0); 4379 } 4380 setGroupingUsed(groupingCount > 0); 4381 fGroupingSize = (groupingCount > 0) ? groupingCount : 0; 4382 fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount) 4383 ? groupingCount2 : 0; 4384 setMultiplier(multiplier); 4385 setDecimalSeparatorAlwaysShown(decimalPos == 0 4386 || decimalPos == digitTotalCount); 4387 if (padPos >= 0) { 4388 fPadPosition = (EPadPosition) padPos; 4389 // To compute the format width, first set up sub0Limit - 4390 // sub0Start. Add in prefix/suffix length later. 4391 4392 // fFormatWidth = prefix.length() + suffix.length() + 4393 // sub0Limit - sub0Start; 4394 fFormatWidth = sub0Limit - sub0Start; 4395 fPad = padChar; 4396 } else { 4397 fFormatWidth = 0; 4398 } 4399 if (roundingPos >= 0) { 4400 roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos); 4401 if (fRoundingIncrement != NULL) { 4402 *fRoundingIncrement = roundingInc; 4403 } else { 4404 fRoundingIncrement = new DigitList(roundingInc); 4405 /* test for NULL */ 4406 if (fRoundingIncrement == NULL) { 4407 status = U_MEMORY_ALLOCATION_ERROR; 4408 delete fPosPrefixPattern; 4409 delete fPosSuffixPattern; 4410 return; 4411 } 4412 } 4413 fRoundingIncrement->getDouble(); // forces caching of double in the DigitList, 4414 // makes getting it thread safe. 4415 fRoundingMode = kRoundHalfEven; 4416 } else { 4417 setRoundingIncrement(0.0); 4418 } 4419 } else { 4420 fNegPrefixPattern = new UnicodeString(prefix); 4421 /* test for NULL */ 4422 if (fNegPrefixPattern == 0) { 4423 status = U_MEMORY_ALLOCATION_ERROR; 4424 return; 4425 } 4426 fNegSuffixPattern = new UnicodeString(suffix); 4427 /* test for NULL */ 4428 if (fNegSuffixPattern == 0) { 4429 delete fNegPrefixPattern; 4430 status = U_MEMORY_ALLOCATION_ERROR; 4431 return; 4432 } 4433 } 4434 } 4435 4436 if (pattern.length() == 0) { 4437 delete fNegPrefixPattern; 4438 delete fNegSuffixPattern; 4439 fNegPrefixPattern = NULL; 4440 fNegSuffixPattern = NULL; 4441 if (fPosPrefixPattern != NULL) { 4442 fPosPrefixPattern->remove(); 4443 } else { 4444 fPosPrefixPattern = new UnicodeString(); 4445 /* test for NULL */ 4446 if (fPosPrefixPattern == 0) { 4447 status = U_MEMORY_ALLOCATION_ERROR; 4448 return; 4449 } 4450 } 4451 if (fPosSuffixPattern != NULL) { 4452 fPosSuffixPattern->remove(); 4453 } else { 4454 fPosSuffixPattern = new UnicodeString(); 4455 /* test for NULL */ 4456 if (fPosSuffixPattern == 0) { 4457 delete fPosPrefixPattern; 4458 status = U_MEMORY_ALLOCATION_ERROR; 4459 return; 4460 } 4461 } 4462 4463 setMinimumIntegerDigits(0); 4464 setMaximumIntegerDigits(kDoubleIntegerDigits); 4465 setMinimumFractionDigits(0); 4466 setMaximumFractionDigits(kDoubleFractionDigits); 4467 4468 fUseExponentialNotation = FALSE; 4469 fCurrencySignCount = 0; 4470 setGroupingUsed(FALSE); 4471 fGroupingSize = 0; 4472 fGroupingSize2 = 0; 4473 setMultiplier(1); 4474 setDecimalSeparatorAlwaysShown(FALSE); 4475 fFormatWidth = 0; 4476 setRoundingIncrement(0.0); 4477 } 4478 4479 // If there was no negative pattern, or if the negative pattern is 4480 // identical to the positive pattern, then prepend the minus sign to the 4481 // positive pattern to form the negative pattern. 4482 if (fNegPrefixPattern == NULL || 4483 (*fNegPrefixPattern == *fPosPrefixPattern 4484 && *fNegSuffixPattern == *fPosSuffixPattern)) { 4485 _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern); 4486 if (fNegPrefixPattern == NULL) { 4487 fNegPrefixPattern = new UnicodeString(); 4488 /* test for NULL */ 4489 if (fNegPrefixPattern == 0) { 4490 status = U_MEMORY_ALLOCATION_ERROR; 4491 return; 4492 } 4493 } else { 4494 fNegPrefixPattern->remove(); 4495 } 4496 fNegPrefixPattern->append(kQuote).append(kPatternMinus) 4497 .append(*fPosPrefixPattern); 4498 } 4499 #ifdef FMT_DEBUG 4500 UnicodeString s; 4501 s.append("\"").append(pattern).append("\"->"); 4502 debugout(s); 4503 #endif 4504 4505 // save the pattern 4506 fFormatPattern = pattern; 4507 } 4508 4509 4510 void 4511 DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) { 4512 expandAffixes(pluralCount); 4513 if (fFormatWidth > 0) { 4514 // Finish computing format width (see above) 4515 // TODO: how to handle fFormatWidth, 4516 // need to save in f(Plural)AffixesForCurrecy? 4517 fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length(); 4518 } 4519 } 4520 4521 4522 void 4523 DecimalFormat::applyPattern(const UnicodeString& pattern, 4524 UBool localized, 4525 UParseError& parseError, 4526 UErrorCode& status) 4527 { 4528 // do the following re-set first. since they change private data by 4529 // apply pattern again. 4530 if (pattern.indexOf(kCurrencySign) != -1) { 4531 if (fCurrencyPluralInfo == NULL) { 4532 // initialize currencyPluralInfo if needed 4533 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status); 4534 } 4535 if (fAffixPatternsForCurrency == NULL) { 4536 setupCurrencyAffixPatterns(status); 4537 } 4538 if (pattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) { 4539 // only setup the affixes of the current pattern. 4540 setupCurrencyAffixes(pattern, TRUE, FALSE, status); 4541 } 4542 } 4543 applyPatternWithoutExpandAffix(pattern, localized, parseError, status); 4544 expandAffixAdjustWidth(NULL); 4545 } 4546 4547 4548 void 4549 DecimalFormat::applyPatternInternally(const UnicodeString& pluralCount, 4550 const UnicodeString& pattern, 4551 UBool localized, 4552 UParseError& parseError, 4553 UErrorCode& status) { 4554 applyPatternWithoutExpandAffix(pattern, localized, parseError, status); 4555 expandAffixAdjustWidth(&pluralCount); 4556 } 4557 4558 4559 /** 4560 * Sets the maximum number of digits allowed in the integer portion of a 4561 * number. This override limits the integer digit count to 309. 4562 * @see NumberFormat#setMaximumIntegerDigits 4563 */ 4564 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { 4565 NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits)); 4566 } 4567 4568 /** 4569 * Sets the minimum number of digits allowed in the integer portion of a 4570 * number. This override limits the integer digit count to 309. 4571 * @see NumberFormat#setMinimumIntegerDigits 4572 */ 4573 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { 4574 NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits)); 4575 } 4576 4577 /** 4578 * Sets the maximum number of digits allowed in the fraction portion of a 4579 * number. This override limits the fraction digit count to 340. 4580 * @see NumberFormat#setMaximumFractionDigits 4581 */ 4582 void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { 4583 NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits)); 4584 } 4585 4586 /** 4587 * Sets the minimum number of digits allowed in the fraction portion of a 4588 * number. This override limits the fraction digit count to 340. 4589 * @see NumberFormat#setMinimumFractionDigits 4590 */ 4591 void DecimalFormat::setMinimumFractionDigits(int32_t newValue) { 4592 NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits)); 4593 } 4594 4595 int32_t DecimalFormat::getMinimumSignificantDigits() const { 4596 return fMinSignificantDigits; 4597 } 4598 4599 int32_t DecimalFormat::getMaximumSignificantDigits() const { 4600 return fMaxSignificantDigits; 4601 } 4602 4603 void DecimalFormat::setMinimumSignificantDigits(int32_t min) { 4604 if (min < 1) { 4605 min = 1; 4606 } 4607 // pin max sig dig to >= min 4608 int32_t max = _max(fMaxSignificantDigits, min); 4609 fMinSignificantDigits = min; 4610 fMaxSignificantDigits = max; 4611 } 4612 4613 void DecimalFormat::setMaximumSignificantDigits(int32_t max) { 4614 if (max < 1) { 4615 max = 1; 4616 } 4617 // pin min sig dig to 1..max 4618 U_ASSERT(fMinSignificantDigits >= 1); 4619 int32_t min = _min(fMinSignificantDigits, max); 4620 fMinSignificantDigits = min; 4621 fMaxSignificantDigits = max; 4622 } 4623 4624 UBool DecimalFormat::areSignificantDigitsUsed() const { 4625 return fUseSignificantDigits; 4626 } 4627 4628 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) { 4629 fUseSignificantDigits = useSignificantDigits; 4630 } 4631 4632 void DecimalFormat::setCurrencyInternally(const UChar* theCurrency, 4633 UErrorCode& ec) { 4634 // If we are a currency format, then modify our affixes to 4635 // encode the currency symbol for the given currency in our 4636 // locale, and adjust the decimal digits and rounding for the 4637 // given currency. 4638 4639 // Note: The code is ordered so that this object is *not changed* 4640 // until we are sure we are going to succeed. 4641 4642 // NULL or empty currency is *legal* and indicates no currency. 4643 UBool isCurr = (theCurrency && *theCurrency); 4644 4645 double rounding = 0.0; 4646 int32_t frac = 0; 4647 if (fCurrencySignCount > fgCurrencySignCountZero && isCurr) { 4648 rounding = ucurr_getRoundingIncrement(theCurrency, &ec); 4649 frac = ucurr_getDefaultFractionDigits(theCurrency, &ec); 4650 } 4651 4652 NumberFormat::setCurrency(theCurrency, ec); 4653 if (U_FAILURE(ec)) return; 4654 4655 if (fCurrencySignCount > fgCurrencySignCountZero) { 4656 // NULL or empty currency is *legal* and indicates no currency. 4657 if (isCurr) { 4658 setRoundingIncrement(rounding); 4659 setMinimumFractionDigits(frac); 4660 setMaximumFractionDigits(frac); 4661 } 4662 expandAffixes(NULL); 4663 } 4664 } 4665 4666 void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) { 4667 // set the currency before compute affixes to get the right currency names 4668 NumberFormat::setCurrency(theCurrency, ec); 4669 if (fFormatPattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) { 4670 UnicodeString savedPtn = fFormatPattern; 4671 setupCurrencyAffixes(fFormatPattern, TRUE, TRUE, ec); 4672 UParseError parseErr; 4673 applyPattern(savedPtn, FALSE, parseErr, ec); 4674 } 4675 // set the currency after apply pattern to get the correct rounding/fraction 4676 setCurrencyInternally(theCurrency, ec); 4677 } 4678 4679 // Deprecated variant with no UErrorCode parameter 4680 void DecimalFormat::setCurrency(const UChar* theCurrency) { 4681 UErrorCode ec = U_ZERO_ERROR; 4682 setCurrency(theCurrency, ec); 4683 } 4684 4685 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const { 4686 if (fSymbols == NULL) { 4687 ec = U_MEMORY_ALLOCATION_ERROR; 4688 return; 4689 } 4690 ec = U_ZERO_ERROR; 4691 const UChar* c = getCurrency(); 4692 if (*c == 0) { 4693 const UnicodeString &intl = 4694 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); 4695 c = intl.getBuffer(); // ok for intl to go out of scope 4696 } 4697 u_strncpy(result, c, 3); 4698 result[3] = 0; 4699 } 4700 4701 /** 4702 * Return the number of fraction digits to display, or the total 4703 * number of digits for significant digit formats and exponential 4704 * formats. 4705 */ 4706 int32_t 4707 DecimalFormat::precision() const { 4708 if (areSignificantDigitsUsed()) { 4709 return getMaximumSignificantDigits(); 4710 } else if (fUseExponentialNotation) { 4711 return getMinimumIntegerDigits() + getMaximumFractionDigits(); 4712 } else { 4713 return getMaximumFractionDigits(); 4714 } 4715 } 4716 4717 4718 // TODO: template algorithm 4719 Hashtable* 4720 DecimalFormat::initHashForAffix(UErrorCode& status) { 4721 if ( U_FAILURE(status) ) { 4722 return NULL; 4723 } 4724 Hashtable* hTable; 4725 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) { 4726 status = U_MEMORY_ALLOCATION_ERROR; 4727 return NULL; 4728 } 4729 if ( U_FAILURE(status) ) { 4730 delete hTable; 4731 return NULL; 4732 } 4733 hTable->setValueComparator(decimfmtAffixValueComparator); 4734 return hTable; 4735 } 4736 4737 Hashtable* 4738 DecimalFormat::initHashForAffixPattern(UErrorCode& status) { 4739 if ( U_FAILURE(status) ) { 4740 return NULL; 4741 } 4742 Hashtable* hTable; 4743 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) { 4744 status = U_MEMORY_ALLOCATION_ERROR; 4745 return NULL; 4746 } 4747 if ( U_FAILURE(status) ) { 4748 delete hTable; 4749 return NULL; 4750 } 4751 hTable->setValueComparator(decimfmtAffixPatternValueComparator); 4752 return hTable; 4753 } 4754 4755 void 4756 DecimalFormat::deleteHashForAffix(Hashtable*& table) 4757 { 4758 if ( table == NULL ) { 4759 return; 4760 } 4761 int32_t pos = -1; 4762 const UHashElement* element = NULL; 4763 while ( (element = table->nextElement(pos)) != NULL ) { 4764 const UHashTok valueTok = element->value; 4765 const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer; 4766 delete value; 4767 } 4768 delete table; 4769 table = NULL; 4770 } 4771 4772 4773 4774 void 4775 DecimalFormat::deleteHashForAffixPattern() 4776 { 4777 if ( fAffixPatternsForCurrency == NULL ) { 4778 return; 4779 } 4780 int32_t pos = -1; 4781 const UHashElement* element = NULL; 4782 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { 4783 const UHashTok valueTok = element->value; 4784 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer; 4785 delete value; 4786 } 4787 delete fAffixPatternsForCurrency; 4788 fAffixPatternsForCurrency = NULL; 4789 } 4790 4791 4792 void 4793 DecimalFormat::copyHashForAffixPattern(const Hashtable* source, 4794 Hashtable* target, 4795 UErrorCode& status) { 4796 if ( U_FAILURE(status) ) { 4797 return; 4798 } 4799 int32_t pos = -1; 4800 const UHashElement* element = NULL; 4801 if ( source ) { 4802 while ( (element = source->nextElement(pos)) != NULL ) { 4803 const UHashTok keyTok = element->key; 4804 const UnicodeString* key = (UnicodeString*)keyTok.pointer; 4805 const UHashTok valueTok = element->value; 4806 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer; 4807 AffixPatternsForCurrency* copy = new AffixPatternsForCurrency( 4808 value->negPrefixPatternForCurrency, 4809 value->negSuffixPatternForCurrency, 4810 value->posPrefixPatternForCurrency, 4811 value->posSuffixPatternForCurrency, 4812 value->patternType); 4813 target->put(UnicodeString(*key), copy, status); 4814 if ( U_FAILURE(status) ) { 4815 return; 4816 } 4817 } 4818 } 4819 } 4820 4821 4822 4823 void 4824 DecimalFormat::copyHashForAffix(const Hashtable* source, 4825 Hashtable* target, 4826 UErrorCode& status) { 4827 if ( U_FAILURE(status) ) { 4828 return; 4829 } 4830 int32_t pos = -1; 4831 const UHashElement* element = NULL; 4832 if ( source ) { 4833 while ( (element = source->nextElement(pos)) != NULL ) { 4834 const UHashTok keyTok = element->key; 4835 const UnicodeString* key = (UnicodeString*)keyTok.pointer; 4836 4837 const UHashTok valueTok = element->value; 4838 const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer; 4839 AffixesForCurrency* copy = new AffixesForCurrency( 4840 value->negPrefixForCurrency, 4841 value->negSuffixForCurrency, 4842 value->posPrefixForCurrency, 4843 value->posSuffixForCurrency); 4844 target->put(UnicodeString(*key), copy, status); 4845 if ( U_FAILURE(status) ) { 4846 return; 4847 } 4848 } 4849 } 4850 } 4851 4852 U_NAMESPACE_END 4853 4854 #endif /* #if !UCONFIG_NO_FORMATTING */ 4855 4856 //eof 4857