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