2 ******************************************************************************* 
   3 * Copyright (C) 1997-2004, International Business Machines Corporation and    * 
   4 * others. All Rights Reserved.                                                * 
   5 ******************************************************************************* 
   9 * Modification History: 
  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,  
  37 ******************************************************************************** 
  40 #include "unicode/utypes.h" 
  42 #if !UCONFIG_NO_FORMATTING 
  44 #include "unicode/decimfmt.h" 
  45 #include "unicode/choicfmt.h" 
  46 #include "unicode/ucurr.h" 
  47 #include "unicode/ustring.h" 
  48 #include "unicode/dcfmtsym.h" 
  49 #include "unicode/ures.h" 
  50 #include "unicode/uchar.h" 
  51 #include "unicode/curramt.h" 
  67 static void debugout(UnicodeString s
) { 
  69     s
.extract((int32_t) 0, s
.length(), buf
); 
  72 #define debug(x) printf("%s", x); 
  78 // ***************************************************************************** 
  79 // class DecimalFormat 
  80 // ***************************************************************************** 
  82 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat
) 
  84 // Constants for characters used in programmatic (unlocalized) patterns. 
  85 #define kPatternZeroDigit            ((UChar)0x0030) /*'0'*/ 
  86 #define kPatternSignificantDigit     ((UChar)0x0040) /*'@'*/ 
  87 #define kPatternGroupingSeparator    ((UChar)0x002C) /*','*/ 
  88 #define kPatternDecimalSeparator     ((UChar)0x002E) /*'.'*/ 
  89 #define kPatternPerMill              ((UChar)0x2030) 
  90 #define kPatternPercent              ((UChar)0x0025) /*'%'*/ 
  91 #define kPatternDigit                ((UChar)0x0023) /*'#'*/ 
  92 #define kPatternSeparator            ((UChar)0x003B) /*';'*/ 
  93 #define kPatternExponent             ((UChar)0x0045) /*'E'*/ 
  94 #define kPatternPlus                 ((UChar)0x002B) /*'+'*/ 
  95 #define kPatternMinus                ((UChar)0x002D) /*'-'*/ 
  96 #define kPatternPadEscape            ((UChar)0x002A) /*'*'*/ 
  97 #define kQuote                       ((UChar)0x0027) /*'\''*/ 
  99  * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It 
 100  * is used in patterns and substitued with either the currency symbol, 
 101  * or if it is doubled, with the international currency symbol.  If the 
 102  * CURRENCY_SIGN is seen in a pattern, then the decimal separator is 
 103  * replaced with the monetary decimal separator. 
 105 #define kCurrencySign                ((UChar)0x00A4) 
 106 #define kDefaultPad                  ((UChar)0x0020) /* */ 
 108 const int32_t DecimalFormat::kDoubleIntegerDigits  
= 309; 
 109 const int32_t DecimalFormat::kDoubleFractionDigits 
= 340; 
 111 const int32_t DecimalFormat::kMaxScientificIntegerDigits 
= 8; 
 114  * These are the tags we expect to see in normal resource bundle files associated 
 117 const char DecimalFormat::fgNumberPatterns
[]="NumberPatterns"; 
 119 inline int32_t _min(int32_t a
, int32_t b
) { return (a
<b
) ? a 
: b
; } 
 120 inline int32_t _max(int32_t a
, int32_t b
) { return (a
<b
) ? b 
: a
; } 
 122 //------------------------------------------------------------------------------ 
 123 // Constructs a DecimalFormat instance in the default locale. 
 125 DecimalFormat::DecimalFormat(UErrorCode
& status
) 
 127   fPosPrefixPattern(0),  
 128   fPosSuffixPattern(0),  
 129   fNegPrefixPattern(0),  
 130   fNegSuffixPattern(0), 
 136   fUseSignificantDigits(FALSE
), 
 137   fMinSignificantDigits(1), 
 138   fMaxSignificantDigits(6), 
 139   fMinExponentDigits(0), 
 140   fRoundingIncrement(0), 
 144     UParseError parseError
; 
 145     construct(status
, parseError
); 
 148 //------------------------------------------------------------------------------ 
 149 // Constructs a DecimalFormat instance with the specified number format 
 150 // pattern in the default locale. 
 152 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
, 
 155   fPosPrefixPattern(0),  
 156   fPosSuffixPattern(0),  
 157   fNegPrefixPattern(0),  
 158   fNegSuffixPattern(0), 
 164   fUseSignificantDigits(FALSE
), 
 165   fMinSignificantDigits(1), 
 166   fMaxSignificantDigits(6), 
 167   fMinExponentDigits(0), 
 168   fRoundingIncrement(0), 
 172     UParseError parseError
; 
 173     construct(status
, parseError
, &pattern
); 
 176 //------------------------------------------------------------------------------ 
 177 // Constructs a DecimalFormat instance with the specified number format 
 178 // pattern and the number format symbols in the default locale.  The 
 179 // created instance owns the symbols. 
 181 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
, 
 182                              DecimalFormatSymbols
* symbolsToAdopt
, 
 185   fPosPrefixPattern(0),  
 186   fPosSuffixPattern(0),  
 187   fNegPrefixPattern(0),  
 188   fNegSuffixPattern(0), 
 194   fUseSignificantDigits(FALSE
), 
 195   fMinSignificantDigits(1), 
 196   fMaxSignificantDigits(6), 
 197   fMinExponentDigits(0), 
 198   fRoundingIncrement(0), 
 202     UParseError parseError
; 
 203     if (symbolsToAdopt 
== NULL
) 
 204         status 
= U_ILLEGAL_ARGUMENT_ERROR
; 
 205     construct(status
, parseError
, &pattern
, symbolsToAdopt
); 
 208 DecimalFormat::DecimalFormat(  const UnicodeString
& pattern
, 
 209                     DecimalFormatSymbols
* symbolsToAdopt
, 
 210                     UParseError
& parseErr
, 
 213   fPosPrefixPattern(0),  
 214   fPosSuffixPattern(0),  
 215   fNegPrefixPattern(0),  
 216   fNegSuffixPattern(0), 
 222   fUseSignificantDigits(FALSE
), 
 223   fMinSignificantDigits(1), 
 224   fMaxSignificantDigits(6), 
 225   fMinExponentDigits(0), 
 226   fRoundingIncrement(0), 
 230     if (symbolsToAdopt 
== NULL
) 
 231         status 
= U_ILLEGAL_ARGUMENT_ERROR
; 
 232     construct(status
,parseErr
, &pattern
, symbolsToAdopt
); 
 234 //------------------------------------------------------------------------------ 
 235 // Constructs a DecimalFormat instance with the specified number format 
 236 // pattern and the number format symbols in the default locale.  The 
 237 // created instance owns the clone of the symbols. 
 239 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
, 
 240                              const DecimalFormatSymbols
& symbols
, 
 243   fPosPrefixPattern(0),  
 244   fPosSuffixPattern(0),  
 245   fNegPrefixPattern(0),  
 246   fNegSuffixPattern(0), 
 252   fUseSignificantDigits(FALSE
), 
 253   fMinSignificantDigits(1), 
 254   fMaxSignificantDigits(6), 
 255   fMinExponentDigits(0), 
 256   fRoundingIncrement(0), 
 260     UParseError parseError
; 
 261     construct(status
, parseError
, &pattern
, new DecimalFormatSymbols(symbols
)); 
 264 //------------------------------------------------------------------------------ 
 265 // Constructs a DecimalFormat instance with the specified number format 
 266 // pattern and the number format symbols in the desired locale.  The 
 267 // created instance owns the symbols. 
 270 DecimalFormat::construct(UErrorCode
&             status
, 
 271                          UParseError
&           parseErr
, 
 272                          const UnicodeString
*   pattern
, 
 273                          DecimalFormatSymbols
*  symbolsToAdopt
) 
 275     fSymbols 
= symbolsToAdopt
; // Do this BEFORE aborting on status failure!!! 
 276 //    fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!! 
 277     fRoundingIncrement 
= NULL
; 
 278     fRoundingDouble 
= 0.0; 
 279     fRoundingMode 
= kRoundHalfEven
; 
 280     fPad 
= kPatternPadEscape
; 
 281     fPadPosition 
= kPadBeforePrefix
; 
 282     if (U_FAILURE(status
)) 
 285     fPosPrefixPattern 
= fPosSuffixPattern 
= NULL
; 
 286     fNegPrefixPattern 
= fNegSuffixPattern 
= NULL
; 
 290     fDecimalSeparatorAlwaysShown 
= FALSE
; 
 291     fIsCurrencyFormat 
= FALSE
; 
 292     fUseExponentialNotation 
= FALSE
; 
 293     fMinExponentDigits 
= 0; 
 295     if (fSymbols 
== NULL
) 
 297         fSymbols 
= new DecimalFormatSymbols(Locale::getDefault(), status
); 
 300             status 
= U_MEMORY_ALLOCATION_ERROR
; 
 306     // Uses the default locale's number format pattern if there isn't 
 311         UResourceBundle 
*resource 
= ures_open(NULL
, Locale::getDefault().getName(), &status
); 
 313         resource 
= ures_getByKey(resource
, fgNumberPatterns
, resource
, &status
); 
 314         const UChar 
*resStr 
= ures_getStringByIndex(resource
, (int32_t)0, &len
, &status
); 
 315         str
.setTo(TRUE
, resStr
, len
); 
 317         ures_close(resource
); 
 320     if (U_FAILURE(status
)) 
 325     if (pattern
->indexOf((UChar
)kCurrencySign
) >= 0) { 
 326         // If it looks like we are going to use a currency pattern 
 327         // then do the time consuming lookup. 
 328         if (symbolsToAdopt 
== NULL
) { 
 329             setCurrencyForLocale(uloc_getDefault(), status
); 
 331             setCurrencyForSymbols(); 
 334         setCurrency(NULL
, status
); 
 337     applyPattern(*pattern
, FALSE 
/*not localized*/,parseErr
, status
); 
 341  * Sets our currency to be the default currency for the given locale. 
 343 void DecimalFormat::setCurrencyForLocale(const char* locale
, UErrorCode
& ec
) { 
 344     const UChar
* c 
= NULL
; 
 346         // Trap an error in mapping locale to currency.  If we can't 
 347         // map, then don't fail and set the currency to "". 
 348         UErrorCode ec2 
= U_ZERO_ERROR
; 
 350         ucurr_forLocale(locale
, c
, 4, &ec2
); 
 355 //------------------------------------------------------------------------------ 
 357 DecimalFormat::~DecimalFormat() 
 359 //    delete fDigitList; 
 360     delete fPosPrefixPattern
; 
 361     delete fPosSuffixPattern
; 
 362     delete fNegPrefixPattern
; 
 363     delete fNegSuffixPattern
; 
 364     delete fCurrencyChoice
; 
 366     delete fRoundingIncrement
; 
 369 //------------------------------------------------------------------------------ 
 372 DecimalFormat::DecimalFormat(const DecimalFormat 
&source
) 
 373 :   NumberFormat(source
), 
 375     fPosPrefixPattern(NULL
), 
 376     fPosSuffixPattern(NULL
), 
 377     fNegPrefixPattern(NULL
), 
 378     fNegSuffixPattern(NULL
), 
 379     fCurrencyChoice(NULL
), 
 381     fRoundingIncrement(NULL
) 
 386 //------------------------------------------------------------------------------ 
 387 // assignment operator 
 388 // Note that fDigitList is not considered a significant part of the 
 389 // DecimalFormat because it's used as a buffer to process the numbers. 
 391 static void _copy_us_ptr(UnicodeString
** pdest
, const UnicodeString
* source
) { 
 392     if (source 
== NULL
) { 
 395     } else if (*pdest 
== NULL
) { 
 396         *pdest 
= new UnicodeString(*source
); 
 403 DecimalFormat::operator=(const DecimalFormat
& rhs
) 
 406         NumberFormat::operator=(rhs
); 
 407         fPositivePrefix 
= rhs
.fPositivePrefix
; 
 408         fPositiveSuffix 
= rhs
.fPositiveSuffix
; 
 409         fNegativePrefix 
= rhs
.fNegativePrefix
; 
 410         fNegativeSuffix 
= rhs
.fNegativeSuffix
; 
 411         _copy_us_ptr(&fPosPrefixPattern
, rhs
.fPosPrefixPattern
); 
 412         _copy_us_ptr(&fPosSuffixPattern
, rhs
.fPosSuffixPattern
); 
 413         _copy_us_ptr(&fNegPrefixPattern
, rhs
.fNegPrefixPattern
); 
 414         _copy_us_ptr(&fNegSuffixPattern
, rhs
.fNegSuffixPattern
); 
 415         if (rhs
.fCurrencyChoice 
== 0) { 
 416             delete fCurrencyChoice
; 
 419             fCurrencyChoice 
= (ChoiceFormat
*) rhs
.fCurrencyChoice
->clone(); 
 421         if(rhs
.fRoundingIncrement 
== NULL
) { 
 422             delete fRoundingIncrement
; 
 423             fRoundingIncrement 
= NULL
; 
 425         else if(fRoundingIncrement 
== NULL
) { 
 426             fRoundingIncrement 
= new DigitList(*rhs
.fRoundingIncrement
); 
 429             *fRoundingIncrement 
= *rhs
.fRoundingIncrement
; 
 431         fRoundingDouble 
= rhs
.fRoundingDouble
; 
 432         fRoundingMode 
= rhs
.fRoundingMode
; 
 433         fMultiplier 
= rhs
.fMultiplier
; 
 434         fGroupingSize 
= rhs
.fGroupingSize
; 
 435         fGroupingSize2 
= rhs
.fGroupingSize2
; 
 436         fDecimalSeparatorAlwaysShown 
= rhs
.fDecimalSeparatorAlwaysShown
; 
 437         if(fSymbols 
== NULL
) { 
 438             fSymbols 
= new DecimalFormatSymbols(*rhs
.fSymbols
); 
 440             *fSymbols 
= *rhs
.fSymbols
; 
 442         fUseExponentialNotation 
= rhs
.fUseExponentialNotation
; 
 443         fExponentSignAlwaysShown 
= rhs
.fExponentSignAlwaysShown
; 
 444         /*Bertrand A. D. Update 98.03.17*/ 
 445         fIsCurrencyFormat 
= rhs
.fIsCurrencyFormat
; 
 447         fMinExponentDigits 
= rhs
.fMinExponentDigits
; 
 448         //    if (fDigitList == NULL) 
 449         //        fDigitList = new DigitList(); 
 452         fFormatWidth 
= rhs
.fFormatWidth
; 
 454         fPadPosition 
= rhs
.fPadPosition
; 
 456         fMinSignificantDigits 
= rhs
.fMinSignificantDigits
; 
 457         fMaxSignificantDigits 
= rhs
.fMaxSignificantDigits
; 
 458         fUseSignificantDigits 
= rhs
.fUseSignificantDigits
; 
 463 //------------------------------------------------------------------------------ 
 466 DecimalFormat::operator==(const Format
& that
) const 
 471     // NumberFormat::operator== guarantees this cast is safe 
 472     const DecimalFormat
* other 
= (DecimalFormat
*)&that
; 
 475     // This code makes it easy to determine why two format objects that should 
 478     if (!NumberFormat::operator==(that
)) { 
 479         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 480         debug("NumberFormat::!="); 
 482     if (!((fPosPrefixPattern 
== other
->fPosPrefixPattern 
&& // both null 
 483               fPositivePrefix 
== other
->fPositivePrefix
) 
 484            || (fPosPrefixPattern 
!= 0 && other
->fPosPrefixPattern 
!= 0 && 
 485                *fPosPrefixPattern  
== *other
->fPosPrefixPattern
))) { 
 486         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 487         debug("Pos Prefix !="); 
 489     if (!((fPosSuffixPattern 
== other
->fPosSuffixPattern 
&& // both null 
 490            fPositiveSuffix 
== other
->fPositiveSuffix
) 
 491           || (fPosSuffixPattern 
!= 0 && other
->fPosSuffixPattern 
!= 0 && 
 492               *fPosSuffixPattern  
== *other
->fPosSuffixPattern
))) { 
 493         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 494         debug("Pos Suffix !="); 
 496     if (!((fNegPrefixPattern 
== other
->fNegPrefixPattern 
&& // both null 
 497            fNegativePrefix 
== other
->fNegativePrefix
) 
 498           || (fNegPrefixPattern 
!= 0 && other
->fNegPrefixPattern 
!= 0 && 
 499               *fNegPrefixPattern  
== *other
->fNegPrefixPattern
))) { 
 500         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 501         debug("Neg Prefix "); 
 502         if (fNegPrefixPattern 
== NULL
) { 
 504             debugout(fNegativePrefix
); 
 507             debugout(*fNegPrefixPattern
); 
 510         if (other
->fNegPrefixPattern 
== NULL
) { 
 512             debugout(other
->fNegativePrefix
); 
 515             debugout(*other
->fNegPrefixPattern
); 
 518     if (!((fNegSuffixPattern 
== other
->fNegSuffixPattern 
&& // both null 
 519            fNegativeSuffix 
== other
->fNegativeSuffix
) 
 520           || (fNegSuffixPattern 
!= 0 && other
->fNegSuffixPattern 
!= 0 && 
 521               *fNegSuffixPattern  
== *other
->fNegSuffixPattern
))) { 
 522         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 523         debug("Neg Suffix "); 
 524         if (fNegSuffixPattern 
== NULL
) { 
 526             debugout(fNegativeSuffix
); 
 529             debugout(*fNegSuffixPattern
); 
 532         if (other
->fNegSuffixPattern 
== NULL
) { 
 534             debugout(other
->fNegativeSuffix
); 
 537             debugout(*other
->fNegSuffixPattern
); 
 540     if (!((fRoundingIncrement 
== other
->fRoundingIncrement
) // both null 
 541           || (fRoundingIncrement 
!= NULL 
&& 
 542               other
->fRoundingIncrement 
!= NULL 
&& 
 543               *fRoundingIncrement 
== *other
->fRoundingIncrement
))) { 
 544         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 545         debug("Rounding Increment !="); 
 547     if (fMultiplier 
!= other
->fMultiplier
) { 
 548         if (first
) { printf("[ "); first 
= FALSE
; } 
 549         printf("Multiplier %ld != %ld", fMultiplier
, other
->fMultiplier
); 
 551     if (fGroupingSize 
!= other
->fGroupingSize
) { 
 552         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 553         printf("Grouping Size %ld != %ld", fGroupingSize
, other
->fGroupingSize
); 
 555     if (fGroupingSize2 
!= other
->fGroupingSize2
) { 
 556         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 557         printf("Secondary Grouping Size %ld != %ld", fGroupingSize2
, other
->fGroupingSize2
); 
 559     if (fDecimalSeparatorAlwaysShown 
!= other
->fDecimalSeparatorAlwaysShown
) { 
 560         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 561         printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown
, other
->fDecimalSeparatorAlwaysShown
); 
 563     if (fUseExponentialNotation 
!= other
->fUseExponentialNotation
) { 
 564         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 567     if (!(!fUseExponentialNotation 
|| 
 568           fMinExponentDigits 
!= other
->fMinExponentDigits
)) { 
 569         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 570         debug("Exp Digits !="); 
 572     if (*fSymbols 
!= *(other
->fSymbols
)) { 
 573         if (first
) { printf("[ "); first 
= FALSE
; } else { printf(", "); } 
 576     // TODO Add debug stuff for significant digits here 
 577     if (!first
) { printf(" ]"); } 
 580     return (NumberFormat::operator==(that
) && 
 581             ((fPosPrefixPattern 
== other
->fPosPrefixPattern 
&& // both null 
 582               fPositivePrefix 
== other
->fPositivePrefix
) 
 583              || (fPosPrefixPattern 
!= 0 && other
->fPosPrefixPattern 
!= 0 && 
 584                  *fPosPrefixPattern  
== *other
->fPosPrefixPattern
)) && 
 585             ((fPosSuffixPattern 
== other
->fPosSuffixPattern 
&& // both null 
 586               fPositiveSuffix 
== other
->fPositiveSuffix
) 
 587              || (fPosSuffixPattern 
!= 0 && other
->fPosSuffixPattern 
!= 0 && 
 588                  *fPosSuffixPattern  
== *other
->fPosSuffixPattern
)) && 
 589             ((fNegPrefixPattern 
== other
->fNegPrefixPattern 
&& // both null 
 590               fNegativePrefix 
== other
->fNegativePrefix
) 
 591              || (fNegPrefixPattern 
!= 0 && other
->fNegPrefixPattern 
!= 0 && 
 592                  *fNegPrefixPattern  
== *other
->fNegPrefixPattern
)) && 
 593             ((fNegSuffixPattern 
== other
->fNegSuffixPattern 
&& // both null 
 594               fNegativeSuffix 
== other
->fNegativeSuffix
) 
 595              || (fNegSuffixPattern 
!= 0 && other
->fNegSuffixPattern 
!= 0 && 
 596                  *fNegSuffixPattern  
== *other
->fNegSuffixPattern
)) && 
 597             ((fRoundingIncrement 
== other
->fRoundingIncrement
) // both null 
 598              || (fRoundingIncrement 
!= NULL 
&& 
 599                  other
->fRoundingIncrement 
!= NULL 
&& 
 600                  *fRoundingIncrement 
== *other
->fRoundingIncrement
)) && 
 601         fMultiplier 
== other
->fMultiplier 
&& 
 602         fGroupingSize 
== other
->fGroupingSize 
&& 
 603         fGroupingSize2 
== other
->fGroupingSize2 
&& 
 604         fDecimalSeparatorAlwaysShown 
== other
->fDecimalSeparatorAlwaysShown 
&& 
 605         fUseExponentialNotation 
== other
->fUseExponentialNotation 
&& 
 606         (!fUseExponentialNotation 
|| 
 607          fMinExponentDigits 
== other
->fMinExponentDigits
) && 
 608         *fSymbols 
== *(other
->fSymbols
) && 
 609         fUseSignificantDigits 
== other
->fUseSignificantDigits 
&& 
 610         (!fUseSignificantDigits 
|| 
 611          (fMinSignificantDigits 
== other
->fMinSignificantDigits 
&& 
 612           fMaxSignificantDigits 
== other
->fMaxSignificantDigits
))); 
 615 //------------------------------------------------------------------------------ 
 618 DecimalFormat::clone() const 
 620     return new DecimalFormat(*this); 
 623 //------------------------------------------------------------------------------ 
 626 DecimalFormat::format(int32_t number
, 
 627                       UnicodeString
& appendTo
, 
 628                       FieldPosition
& fieldPosition
) const 
 630     return format((int64_t)number
, appendTo
, fieldPosition
); 
 633 //------------------------------------------------------------------------------ 
 636 DecimalFormat::format(int64_t number
, 
 637                       UnicodeString
& appendTo
, 
 638                       FieldPosition
& fieldPosition
) const 
 642     // Clears field positions. 
 643     fieldPosition
.setBeginIndex(0); 
 644     fieldPosition
.setEndIndex(0); 
 646     // If we are to do rounding, we need to move into the BigDecimal 
 647     // domain in order to do divide/multiply correctly. 
 649     // In general, long values always represent real finite numbers, so 
 650     // we don't have to check for +/- Infinity or NaN.  However, there 
 651     // is one case we have to be careful of:  The multiplier can push 
 652     // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We 
 653     // check for this before multiplying, and if it happens we use doubles 
 654     // instead, trading off accuracy for range. 
 655     if (fRoundingIncrement 
!= NULL
 
 656         || (fMultiplier 
!= 0 && (number 
> (U_INT64_MAX 
/ fMultiplier
) 
 657                               || number 
< (U_INT64_MIN 
/ fMultiplier
)))) 
 659         digits
.set(((double)number
) * fMultiplier
, 
 661                    !fUseExponentialNotation 
&& !areSignificantDigitsUsed()); 
 665         digits
.set(number 
* fMultiplier
, precision(TRUE
)); 
 668     return subformat(appendTo
, fieldPosition
, digits
, TRUE
); 
 671 //------------------------------------------------------------------------------ 
 674 DecimalFormat::format(  double number
, 
 675                         UnicodeString
& appendTo
, 
 676                         FieldPosition
& fieldPosition
) const 
 678     // Clears field positions. 
 679     fieldPosition
.setBeginIndex(0); 
 680     fieldPosition
.setEndIndex(0); 
 682     // Special case for NaN, sets the begin and end index to be the 
 683     // the string length of localized name of NaN. 
 684     if (uprv_isNaN(number
)) 
 686         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 687             fieldPosition
.setBeginIndex(appendTo
.length()); 
 689         appendTo 
+= getConstSymbol(DecimalFormatSymbols::kNaNSymbol
); 
 691         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 692             fieldPosition
.setEndIndex(appendTo
.length()); 
 694         addPadding(appendTo
, fieldPosition
, 0, 0); 
 698     /* Detecting whether a double is negative is easy with the exception of 
 699      * the value -0.0.  This is a double which has a zero mantissa (and 
 700      * exponent), but a negative sign bit.  It is semantically distinct from 
 701      * a zero with a positive sign bit, and this distinction is important 
 702      * to certain kinds of computations.  However, it's a little tricky to 
 703      * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may 
 704      * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) == 
 705      * -Infinity.  Proper detection of -0.0 is needed to deal with the 
 706      * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98. 
 708     UBool isNegative 
= uprv_isNegative(number
); 
 710     // Do this BEFORE checking to see if value is infinite! Sets the 
 711     // begin and end index to be length of the string composed of 
 712     // localized name of Infinite and the positive/negative localized 
 715     number 
*= fMultiplier
; 
 717     // Apply rounding after multiplier 
 718     if (fRoundingIncrement 
!= NULL
) { 
 719         if (isNegative
)     // For rounding in the correct direction 
 721         number 
= fRoundingDouble
 
 722             * round(number 
/ fRoundingDouble
, fRoundingMode
, isNegative
); 
 727     // Special case for INFINITE, 
 728     if (uprv_isInfinite(number
)) 
 730         int32_t prefixLen 
= appendAffix(appendTo
, number
, isNegative
, TRUE
); 
 732         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 733             fieldPosition
.setBeginIndex(appendTo
.length()); 
 735         appendTo 
+= getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
); 
 737         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 738             fieldPosition
.setEndIndex(appendTo
.length()); 
 740         int32_t suffixLen 
= appendAffix(appendTo
, number
, isNegative
, FALSE
); 
 742         addPadding(appendTo
, fieldPosition
, prefixLen
, suffixLen
); 
 748     // This detects negativity too. 
 749     if (fRoundingIncrement 
== NULL
) { 
 750         // If we did not round in binary space, round in decimal space 
 751         digits
.fRoundingMode 
= fRoundingMode
; 
 753     digits
.set(number
, precision(FALSE
), 
 754                !fUseExponentialNotation 
&& !areSignificantDigitsUsed()); 
 756     return subformat(appendTo
, fieldPosition
, digits
, FALSE
); 
 760  * Round a double value to the nearest integer according to the 
 762  * @param a the absolute value of the number to be rounded 
 763  * @param mode a BigDecimal rounding mode 
 764  * @param isNegative true if the number to be rounded is negative 
 765  * @return the absolute value of the rounded result 
 767 double DecimalFormat::round(double a
, ERoundingMode mode
, UBool isNegative
) { 
 770         return isNegative 
? uprv_floor(a
) : uprv_ceil(a
); 
 772         return isNegative 
? uprv_ceil(a
) : uprv_floor(a
); 
 774         return uprv_floor(a
); 
 779             double f 
= uprv_floor(a
); 
 780             if ((a 
- f
) != 0.5) { 
 781                 return uprv_floor(a 
+ 0.5); 
 784             return (g 
== uprv_floor(g
)) ? f 
: (f 
+ 1.0); 
 787         return ((a 
- uprv_floor(a
)) <= 0.5) ? uprv_floor(a
) : uprv_ceil(a
); 
 789         return ((a 
- uprv_floor(a
)) < 0.5) ? uprv_floor(a
) : uprv_ceil(a
); 
 795 DecimalFormat::format(  const Formattable
& obj
, 
 796                         UnicodeString
& appendTo
, 
 797                         FieldPosition
& fieldPosition
, 
 798                         UErrorCode
& status
) const 
 800     return NumberFormat::format(obj
, appendTo
, fieldPosition
, status
); 
 804  * Return true if a grouping separator belongs at the given 
 805  * position, based on whether grouping is in use and the values of 
 806  * the primary and secondary grouping interval. 
 807  * @param pos the number of integer digits to the right of 
 808  * the current position.  Zero indicates the position after the 
 809  * rightmost integer digit. 
 810  * @return true if a grouping character belongs at the current 
 813 UBool 
DecimalFormat::isGroupingPosition(int32_t pos
) const { 
 814     UBool result 
= FALSE
; 
 815     if (isGroupingUsed() && (pos 
> 0) && (fGroupingSize 
> 0)) { 
 816         if ((fGroupingSize2 
> 0) && (pos 
> fGroupingSize
)) { 
 817             result 
= ((pos 
- fGroupingSize
) % fGroupingSize2
) == 0; 
 819             result 
= pos 
% fGroupingSize 
== 0; 
 825 //------------------------------------------------------------------------------ 
 828  * Complete the formatting of a finite number.  On entry, the fDigitList must 
 829  * be filled in with the correct digits. 
 832 DecimalFormat::subformat(UnicodeString
& appendTo
, 
 833                          FieldPosition
& fieldPosition
, 
 835                          UBool         isInteger
) const 
 837     // Gets the localized zero Unicode character. 
 838     UChar32 zero 
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0); 
 839     int32_t zeroDelta 
= zero 
- '0'; // '0' is the DigitList representation of zero 
 840     const UnicodeString 
*grouping 
= &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
); 
 841     const UnicodeString 
*decimal
; 
 842     if(fIsCurrencyFormat
) { 
 843         decimal 
= &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
); 
 845         decimal 
= &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
); 
 847     UBool useSigDig 
= areSignificantDigitsUsed(); 
 848     int32_t maxIntDig 
= getMaximumIntegerDigits(); 
 849     int32_t minIntDig 
= getMinimumIntegerDigits(); 
 851     /* Per bug 4147706, DecimalFormat must respect the sign of numbers which 
 852      * format as zero.  This allows sensible computations and preserves 
 853      * relations such as signum(1/x) = signum(x), where x is +Infinity or 
 854      * -Infinity.  Prior to this fix, we always formatted zero values as if 
 855      * they were positive.  Liu 7/6/98. 
 859         digits
.fDecimalAt 
= digits
.fCount 
= 0; // Normalize 
 862     // Appends the prefix. 
 863     double doubleValue 
= digits
.getDouble(); 
 864     int32_t prefixLen 
= appendAffix(appendTo
, doubleValue
, !digits
.fIsPositive
, TRUE
); 
 866     if (fUseExponentialNotation
) 
 868         // Record field information for caller. 
 869         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 871             fieldPosition
.setBeginIndex(appendTo
.length()); 
 872             fieldPosition
.setEndIndex(-1); 
 874         else if (fieldPosition
.getField() == NumberFormat::kFractionField
) 
 876             fieldPosition
.setBeginIndex(-1); 
 879         int32_t minFracDig 
= 0; 
 881             maxIntDig 
= minIntDig 
= 1; 
 882             minFracDig 
= getMinimumSignificantDigits() - 1; 
 884             minFracDig 
= getMinimumFractionDigits(); 
 885             if (maxIntDig 
> kMaxScientificIntegerDigits
) { 
 887                 if (maxIntDig 
< minIntDig
) { 
 888                     maxIntDig 
= minIntDig
; 
 891             if (maxIntDig 
> minIntDig
) { 
 896         // Minimum integer digits are handled in exponential format by 
 897         // adjusting the exponent.  For example, 0.01234 with 3 minimum 
 898         // integer digits is "123.4E-4". 
 900         // Maximum integer digits are interpreted as indicating the 
 901         // repeating range.  This is useful for engineering notation, in 
 902         // which the exponent is restricted to a multiple of 3.  For 
 903         // example, 0.01234 with 3 maximum integer digits is "12.34e-3". 
 904         // If maximum integer digits are defined and are larger than 
 905         // minimum integer digits, then minimum integer digits are 
 907         int32_t exponent 
= digits
.fDecimalAt
; 
 908         if (maxIntDig 
> 1 && maxIntDig 
!= minIntDig
) { 
 909             // A exponent increment is defined; adjust to it. 
 910             exponent 
= (exponent 
> 0) ? (exponent 
- 1) / maxIntDig
 
 911                                       : (exponent 
/ maxIntDig
) - 1; 
 912             exponent 
*= maxIntDig
; 
 914             // No exponent increment is defined; use minimum integer digits. 
 915             // If none is specified, as in "#E0", generate 1 integer digit. 
 916             exponent 
-= (minIntDig 
> 0 || minFracDig 
> 0) 
 920         // We now output a minimum number of digits, and more if there 
 921         // are more digits, up to the maximum number of digits.  We 
 922         // place the decimal point after the "integer" digits, which 
 923         // are the first (decimalAt - exponent) digits. 
 924         int32_t minimumDigits 
=  minIntDig 
+ minFracDig
; 
 925         // The number of integer digits is handled specially if the number 
 926         // is zero, since then there may be no digits. 
 927         int32_t integerDigits 
= digits
.isZero() ? minIntDig 
: 
 928             digits
.fDecimalAt 
- exponent
; 
 929         int32_t totalDigits 
= digits
.fCount
; 
 930         if (minimumDigits 
> totalDigits
) 
 931             totalDigits 
= minimumDigits
; 
 932         if (integerDigits 
> totalDigits
) 
 933             totalDigits 
= integerDigits
; 
 935         // totalDigits records total number of digits needs to be processed 
 937         for (i
=0; i
<totalDigits
; ++i
) 
 939             if (i 
== integerDigits
) 
 941                 // Record field information for caller. 
 942                 if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 943                     fieldPosition
.setEndIndex(appendTo
.length()); 
 945                 appendTo 
+= *decimal
; 
 947                 // Record field information for caller. 
 948                 if (fieldPosition
.getField() == NumberFormat::kFractionField
) 
 949                     fieldPosition
.setBeginIndex(appendTo
.length()); 
 951             // Restores the digit character or pads the buffer with zeros. 
 952             UChar32 c 
= (UChar32
)((i 
< digits
.fCount
) ? 
 953                           (digits
.fDigits
[i
] + zeroDelta
) : 
 958         // Record field information 
 959         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
 961             if (fieldPosition
.getEndIndex() < 0) 
 962                 fieldPosition
.setEndIndex(appendTo
.length()); 
 964         else if (fieldPosition
.getField() == NumberFormat::kFractionField
) 
 966             if (fieldPosition
.getBeginIndex() < 0) 
 967                 fieldPosition
.setBeginIndex(appendTo
.length()); 
 968             fieldPosition
.setEndIndex(appendTo
.length()); 
 971         // The exponent is output using the pattern-specified minimum 
 972         // exponent digits.  There is no maximum limit to the exponent 
 973         // digits, since truncating the exponent would appendTo in an 
 974         // unacceptable inaccuracy. 
 975         appendTo 
+= getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
); 
 977         // For zero values, we force the exponent to zero.  We 
 978         // must do this here, and not earlier, because the value 
 979         // is used to determine integer digit count above. 
 984             appendTo 
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
); 
 985         } else if (fExponentSignAlwaysShown
) { 
 986             appendTo 
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
); 
 990         expDigits
.set(exponent
); 
 992             int expDig 
= fMinExponentDigits
; 
 993             if (fUseExponentialNotation 
&& expDig 
< 1) { 
 996             for (i
=expDigits
.fDecimalAt
; i
<expDig
; ++i
) 
 999         for (i
=0; i
<expDigits
.fDecimalAt
; ++i
) 
1001             UChar32 c 
= (UChar32
)((i 
< expDigits
.fCount
) ? 
1002                           (expDigits
.fDigits
[i
] + zeroDelta
) : zero
); 
1006     else  // Not using exponential notation 
1008         // Record field information for caller. 
1009         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
1010             fieldPosition
.setBeginIndex(appendTo
.length()); 
1012         int32_t sigCount 
= 0; 
1013         int32_t minSigDig 
= getMinimumSignificantDigits(); 
1014         int32_t maxSigDig 
= getMaximumSignificantDigits(); 
1017             maxSigDig 
= INT32_MAX
; 
1020         // Output the integer portion.  Here 'count' is the total 
1021         // number of integer digits we will display, including both 
1022         // leading zeros required to satisfy getMinimumIntegerDigits, 
1023         // and actual digits present in the number. 
1024         int32_t count 
= useSigDig 
? 
1025             _max(1, digits
.fDecimalAt
) : minIntDig
; 
1026         if (digits
.fDecimalAt 
> 0 && count 
< digits
.fDecimalAt
) { 
1027             count 
= digits
.fDecimalAt
; 
1030         // Handle the case where getMaximumIntegerDigits() is smaller 
1031         // than the real number of integer digits.  If this is so, we 
1032         // output the least significant max integer digits.  For example, 
1033         // the value 1997 printed with 2 max integer digits is just "97". 
1035         int32_t digitIndex 
= 0; // Index into digitList.fDigits[] 
1036         if (count 
> maxIntDig 
&& maxIntDig 
>= 0) { 
1038             digitIndex 
= digits
.fDecimalAt 
- count
; 
1041         int32_t sizeBeforeIntegerPart 
= appendTo
.length(); 
1044         for (i
=count
-1; i
>=0; --i
) 
1046             if (i 
< digits
.fDecimalAt 
&& digitIndex 
< digits
.fCount 
&& 
1047                 sigCount 
< maxSigDig
) { 
1048                 // Output a real digit 
1049                 appendTo 
+= ((UChar32
)(digits
.fDigits
[digitIndex
++] + zeroDelta
)); 
1054                 // Output a zero (leading or trailing) 
1061             // Output grouping separator if necessary. 
1062             if (isGroupingPosition(i
)) { 
1063                 appendTo
.append(*grouping
); 
1067         // Record field information for caller. 
1068         if (fieldPosition
.getField() == NumberFormat::kIntegerField
) 
1069             fieldPosition
.setEndIndex(appendTo
.length()); 
1071         // Determine whether or not there are any printable fractional 
1072         // digits.  If we've used up the digits we know there aren't. 
1073         UBool fractionPresent 
= (!isInteger 
&& digitIndex 
< digits
.fCount
) || 
1074             (useSigDig 
? (sigCount 
< minSigDig
) : (getMinimumFractionDigits() > 0)); 
1076         // If there is no fraction present, and we haven't printed any 
1077         // integer digits, then print a zero.  Otherwise we won't print 
1078         // _any_ digits, and we won't be able to parse this string. 
1079         if (!fractionPresent 
&& appendTo
.length() == sizeBeforeIntegerPart
) 
1082         // Output the decimal separator if we always do so. 
1083         if (fDecimalSeparatorAlwaysShown 
|| fractionPresent
) 
1084             appendTo 
+= *decimal
; 
1086         // Record field information for caller. 
1087         if (fieldPosition
.getField() == NumberFormat::kFractionField
) 
1088             fieldPosition
.setBeginIndex(appendTo
.length()); 
1090         count 
= useSigDig 
? INT32_MAX 
: getMaximumFractionDigits(); 
1091         if (useSigDig 
&& (sigCount 
== maxSigDig 
|| 
1092                           (sigCount 
>= minSigDig 
&& digitIndex 
== digits
.fCount
))) { 
1096         for (i
=0; i 
< count
; ++i
) { 
1097             // Here is where we escape from the loop.  We escape 
1098             // if we've output the maximum fraction digits 
1099             // (specified in the for expression above).  We also 
1100             // stop when we've output the minimum digits and 
1101             // either: we have an integer, so there is no 
1102             // fractional stuff to display, or we're out of 
1103             // significant digits. 
1104             if (!useSigDig 
&& i 
>= getMinimumFractionDigits() && 
1105                 (isInteger 
|| digitIndex 
>= digits
.fCount
)) { 
1109             // Output leading fractional zeros.  These are zeros 
1110             // that come after the decimal but before any 
1111             // significant digits.  These are only output if 
1112             // abs(number being formatted) < 1.0. 
1113             if (-1-i 
> (digits
.fDecimalAt
-1)) { 
1118             // Output a digit, if we have any precision left, or a 
1119             // zero if we don't.  We don't want to output noise digits. 
1120             if (!isInteger 
&& digitIndex 
< digits
.fCount
) { 
1121                 appendTo 
+= ((UChar32
)(digits
.fDigits
[digitIndex
++] + zeroDelta
)); 
1126             // If we reach the maximum number of significant 
1127             // digits, or if we output all the real digits and 
1128             // reach the minimum, then we are done. 
1131                 (sigCount 
== maxSigDig 
|| 
1132                  (digitIndex 
== digits
.fCount 
&& sigCount 
>= minSigDig
))) { 
1137         // Record field information for caller. 
1138         if (fieldPosition
.getField() == NumberFormat::kFractionField
) 
1139             fieldPosition
.setEndIndex(appendTo
.length()); 
1142     int32_t suffixLen 
= appendAffix(appendTo
, doubleValue
, !digits
.fIsPositive
, FALSE
); 
1144     addPadding(appendTo
, fieldPosition
, prefixLen
, suffixLen
); 
1149  * Inserts the character fPad as needed to expand result to fFormatWidth. 
1150  * @param result the string to be padded 
1152 void DecimalFormat::addPadding(UnicodeString
& appendTo
, 
1153                                FieldPosition
& fieldPosition
, 
1155                                int32_t suffixLen
) const 
1157     if (fFormatWidth 
> 0) { 
1158         int32_t len 
= fFormatWidth 
- appendTo
.length(); 
1160             UnicodeString padding
; 
1161             for (int32_t i
=0; i
<len
; ++i
) { 
1164             switch (fPadPosition
) { 
1165             case kPadAfterPrefix
: 
1166                 appendTo
.insert(prefixLen
, padding
); 
1168             case kPadBeforePrefix
: 
1169                 appendTo
.insert(0, padding
); 
1171             case kPadBeforeSuffix
: 
1172                 appendTo
.insert(appendTo
.length() - suffixLen
, padding
); 
1174             case kPadAfterSuffix
: 
1175                 appendTo 
+= padding
; 
1178             if (fPadPosition 
== kPadBeforePrefix 
|| 
1179                 fPadPosition 
== kPadAfterPrefix
) { 
1180                 fieldPosition
.setBeginIndex(len 
+ fieldPosition
.getBeginIndex()); 
1181                 fieldPosition
.setEndIndex(len 
+ fieldPosition
.getEndIndex()); 
1187 //------------------------------------------------------------------------------ 
1190 DecimalFormat::parse(const UnicodeString
& text
, 
1191                      Formattable
& result
, 
1192                      UErrorCode
& status
) const 
1194     NumberFormat::parse(text
, result
, status
); 
1198 DecimalFormat::parse(const UnicodeString
& text
, 
1199                      Formattable
& result
, 
1200                      ParsePosition
& parsePosition
) const { 
1201     parse(text
, result
, parsePosition
, FALSE
); 
1204 Formattable
& DecimalFormat::parseCurrency(const UnicodeString
& text
, 
1205                                           Formattable
& result
, 
1206                                           ParsePosition
& pos
) const { 
1207     parse(text
, result
, pos
, TRUE
); 
1212  * Parses the given text as either a number or a currency amount. 
1213  * @param text the string to parse 
1214  * @param result output parameter for the result 
1215  * @param parsePosition input-output position; on input, the 
1216  * position within text to match; must have 0 <= pos.getIndex() < 
1217  * text.length(); on output, the position after the last matched 
1218  * character. If the parse fails, the position in unchanged upon 
1220  * @param parseCurrency if true, a currency amount is parsed; 
1221  * otherwise a Number is parsed 
1223 void DecimalFormat::parse(const UnicodeString
& text
, 
1224                           Formattable
& result
, 
1225                           ParsePosition
& parsePosition
, 
1226                           UBool parseCurrency
) const { 
1228     int32_t i 
= backup 
= parsePosition
.getIndex(); 
1230     // Handle NaN as a special case: 
1232     // Skip padding characters, if around prefix 
1233     if (fFormatWidth 
> 0 && (fPadPosition 
== kPadBeforePrefix 
|| 
1234                              fPadPosition 
== kPadAfterPrefix
)) { 
1235         i 
= skipPadding(text
, i
); 
1237     // If the text is composed of the representation of NaN, returns NaN.length 
1238     const UnicodeString 
*nan 
= &getConstSymbol(DecimalFormatSymbols::kNaNSymbol
); 
1239     int32_t nanLen 
= (text
.compare(i
, nan
->length(), *nan
) 
1240                       ? 0 : nan
->length()); 
1243         if (fFormatWidth 
> 0 && (fPadPosition 
== kPadBeforeSuffix 
|| 
1244                                  fPadPosition 
== kPadAfterSuffix
)) { 
1245             i 
= skipPadding(text
, i
); 
1247         parsePosition
.setIndex(i
); 
1248         result
.setDouble(uprv_getNaN()); 
1252     // NaN parse failed; start over 
1255     // status is used to record whether a number is infinite. 
1256     UBool status
[fgStatusLength
]; 
1258     UChar
* currency 
= parseCurrency 
? curbuf 
: NULL
; 
1261     if (!subparse(text
, parsePosition
, digits
, status
, currency
)) { 
1262         parsePosition
.setIndex(backup
); 
1267     if (status
[fgStatusInfinite
]) { 
1268         double inf 
= uprv_getInfinity(); 
1269         result
.setDouble(digits
.fIsPositive 
? inf 
: -inf
); 
1273         // Do as much of the multiplier conversion as possible without 
1275         int32_t mult 
= fMultiplier
; // Don't modify this.multiplier 
1276         while (mult 
% 10 == 0) { 
1278             --digits
.fDecimalAt
; 
1281         // Handle integral values.  We want to return the most 
1282         // parsimonious type that will accommodate all of the result's 
1283         // precision.  We therefore only return a long if the result fits 
1284         // entirely within a long (taking into account the multiplier) -- 
1285         // otherwise we fall through and return a double.  When more 
1286         // numeric types are supported by Formattable (e.g., 64-bit 
1287         // integers, bignums) we will extend this logic to include them. 
1288         if (digits
.fitsIntoLong(isParseIntegerOnly())) { 
1289             int32_t n 
= digits
.getLong(); 
1290             if (n 
% mult 
== 0) { 
1291                 result
.setLong(n 
/ mult
); 
1293             else {  // else handle the remainder 
1294                 result
.setDouble(((double)n
) / mult
); 
1297         else if (digits
.fitsIntoInt64(isParseIntegerOnly())) { 
1298             int64_t n 
= digits
.getInt64(); 
1299             if (n 
% mult 
== 0) { 
1300                 result
.setInt64(n 
/ mult
); 
1302             else {  // else handle the remainder 
1303                 result
.setDouble(((double)n
) / mult
); 
1307             // Handle non-integral or very large values 
1308             // Dividing by one is okay and not that costly. 
1309             result
.setDouble(digits
.getDouble() / mult
); 
1313     if (parseCurrency
) { 
1314         UErrorCode ec 
= U_ZERO_ERROR
; 
1315         Formattable 
n(result
); 
1316         result
.adoptObject(new CurrencyAmount(n
, curbuf
, ec
)); 
1317         U_ASSERT(U_SUCCESS(ec
)); // should always succeed 
1323 This is an old implimentation that was preparing for 64-bit numbers in ICU. 
1324 It is very slow, and 64-bit numbers are not ANSI-C compatible. This code 
1325 is here if we change our minds. 
1327 ^^^ what is this referring to? remove? ^^^ [alan] 
1331  * Parse the given text into a number.  The text is parsed beginning at 
1332  * parsePosition, until an unparseable character is seen. 
1333  * @param text the string to parse. 
1334  * @param parsePosition The position at which to being parsing.  Upon 
1335  * return, the first unparsed character. 
1336  * @param digits the DigitList to set to the parsed value. 
1337  * @param status output param containing boolean status flags indicating 
1338  * whether the value was infinite and whether it was positive. 
1339  * @param currency return value for parsed currency, for generic 
1340  * currency parsing mode, or NULL for normal parsing. In generic 
1341  * currency parsing mode, any currency is parsed, not just the 
1342  * currency that this formatter is set to. 
1344 UBool 
DecimalFormat::subparse(const UnicodeString
& text
, ParsePosition
& parsePosition
, 
1345                               DigitList
& digits
, UBool
* status
, 
1346                               UChar
* currency
) const 
1348     int32_t position 
= parsePosition
.getIndex(); 
1349     int32_t oldStart 
= position
; 
1351     // Match padding before prefix 
1352     if (fFormatWidth 
> 0 && fPadPosition 
== kPadBeforePrefix
) { 
1353         position 
= skipPadding(text
, position
); 
1356     // Match positive and negative prefixes; prefer longest match. 
1357     int32_t posMatch 
= compareAffix(text
, position
, FALSE
, TRUE
, currency
); 
1358     int32_t negMatch 
= compareAffix(text
, position
, TRUE
, TRUE
, currency
); 
1359     if (posMatch 
>= 0 && negMatch 
>= 0) { 
1360         if (posMatch 
> negMatch
) { 
1362         } else if (negMatch 
> posMatch
) { 
1366     if (posMatch 
>= 0) { 
1367         position 
+= posMatch
; 
1368     } else if (negMatch 
>= 0) { 
1369         position 
+= negMatch
; 
1371         parsePosition
.setErrorIndex(position
); 
1375     // Match padding before prefix 
1376     if (fFormatWidth 
> 0 && fPadPosition 
== kPadAfterPrefix
) { 
1377         position 
= skipPadding(text
, position
); 
1380     // process digits or Inf, find decimal position 
1381     const UnicodeString 
*inf 
= &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
); 
1382     int32_t infLen 
= (text
.compare(position
, inf
->length(), *inf
) 
1383         ? 0 : inf
->length()); 
1384     position 
+= infLen
; // infLen is non-zero when it does equal to infinity 
1385     status
[fgStatusInfinite
] = (UBool
)infLen
; 
1388         // We now have a string of digits, possibly with grouping symbols, 
1389         // and decimal points.  We want to process these into a DigitList. 
1390         // We don't want to put a bunch of leading zeros into the DigitList 
1391         // though, so we keep track of the location of the decimal point, 
1392         // put only significant digits into the DigitList, and adjust the 
1393         // exponent as needed. 
1395         digits
.fDecimalAt 
= digits
.fCount 
= 0; 
1396         UChar32 zero 
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0); 
1398         const UnicodeString 
*decimal
; 
1399         if(fIsCurrencyFormat
) { 
1400             decimal 
= &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
); 
1402             decimal 
= &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
); 
1404         const UnicodeString 
*grouping 
= &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
); 
1405         UBool sawDecimal 
= FALSE
; 
1406         UBool sawDigit 
= FALSE
; 
1407         int32_t backup 
= -1; 
1409         int32_t textLength 
= text
.length(); // One less pointer to follow 
1410         int32_t groupingLen 
= grouping
->length(); 
1411         int32_t decimalLen 
= decimal
->length(); 
1413         // We have to track digitCount ourselves, because digits.fCount will 
1414         // pin when the maximum allowable digits is reached. 
1415         int32_t digitCount 
= 0; 
1417         for (; position 
< textLength
; ) 
1419             UChar32 ch 
= text
.char32At(position
); 
1421             /* We recognize all digit ranges, not only the Latin digit range 
1422              * '0'..'9'.  We do so by using the Character.digit() method, 
1423              * which converts a valid Unicode digit to the range 0..9. 
1425              * The character 'ch' may be a digit.  If so, place its value 
1426              * from 0 to 9 in 'digit'.  First try using the locale digit, 
1427              * which may or MAY NOT be a standard Unicode digit range.  If 
1428              * this fails, try using the standard Unicode digit ranges by 
1429              * calling Character.digit().  If this also fails, digit will 
1430              * have a value outside the range 0..9. 
1433             if (digit 
< 0 || digit 
> 9) 
1435                 digit 
= u_charDigitValue(ch
); 
1438             if (digit 
> 0 && digit 
<= 9) 
1440                 // Cancel out backup setting (see grouping handler below) 
1444                 // output a regular non-zero digit. 
1446                 digits
.append((char)(digit 
+ '0')); 
1447                 position 
+= U16_LENGTH(ch
); 
1449             else if (digit 
== 0) 
1451                 // Cancel out backup setting (see grouping handler below) 
1455                 // Check for leading zeros 
1456                 if (digits
.fCount 
!= 0) 
1458                     // output a regular zero digit. 
1460                     digits
.append((char)(digit 
+ '0')); 
1462                 else if (sawDecimal
) 
1464                     // If we have seen the decimal, but no significant digits yet, 
1465                     // then we account for leading zeros by decrementing the 
1466                     // digits.fDecimalAt into negative values. 
1467                     --digits
.fDecimalAt
; 
1469                 // else ignore leading zeros in integer part of number. 
1470                 position 
+= U16_LENGTH(ch
); 
1472             else if (!text
.compare(position
, groupingLen
, *grouping
) && isGroupingUsed()) 
1474                 // Ignore grouping characters, if we are using them, but require 
1475                 // that they be followed by a digit.  Otherwise we backup and 
1478                 position 
+= groupingLen
; 
1480             else if (!text
.compare(position
, decimalLen
, *decimal
) && !isParseIntegerOnly() && !sawDecimal
) 
1482                 // If we're only parsing integers, or if we ALREADY saw the 
1483                 // decimal, then don't parse this one. 
1485                 digits
.fDecimalAt 
= digitCount
; // Not digits.fCount! 
1487                 position 
+= decimalLen
; 
1490                 const UnicodeString 
*tmp
; 
1491                 tmp 
= &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
); 
1492                 if (!text
.caseCompare(position
, tmp
->length(), *tmp
, U_FOLD_CASE_DEFAULT
))    // error code is set below if !sawDigit 
1494                     // Parse sign, if present 
1495                     int32_t pos 
= position 
+ tmp
->length(); 
1496                     DigitList exponentDigits
; 
1498                     if (pos 
< textLength
) 
1500                         tmp 
= &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
); 
1501                         if (!text
.compare(pos
, tmp
->length(), *tmp
)) 
1503                             pos 
+= tmp
->length(); 
1506                             tmp 
= &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
); 
1507                             if (!text
.compare(pos
, tmp
->length(), *tmp
)) 
1509                                 pos 
+= tmp
->length(); 
1510                                 exponentDigits
.fIsPositive 
= FALSE
; 
1515                     while (pos 
< textLength
) { 
1516                         ch 
= text
[(int32_t)pos
]; 
1519                         if (digit 
< 0 || digit 
> 9) { 
1520                             digit 
= u_charDigitValue(ch
); 
1522                         if (0 <= digit 
&& digit 
<= 9) { 
1524                             exponentDigits
.append((char)(digit 
+ '0')); 
1530                     if (exponentDigits
.fCount 
> 0) { 
1531                         exponentDigits
.fDecimalAt 
= exponentDigits
.fCount
; 
1532                         digits
.fDecimalAt 
+= exponentDigits
.getLong(); 
1533                         position 
= pos
; // Advance past the exponent 
1536                     break; // Whether we fail or succeed, we exit this loop 
1549         // If there was no decimal point we have an integer 
1552             digits
.fDecimalAt 
+= digitCount
; // Not digits.fCount! 
1555         // If none of the text string was recognized.  For example, parse 
1556         // "x" with pattern "#0.00" (return index and error index both 0) 
1557         // parse "$" with pattern "$#0.00". (return index 0 and error index 
1559         if (!sawDigit 
&& digitCount 
== 0) { 
1560             parsePosition
.setIndex(oldStart
); 
1561             parsePosition
.setErrorIndex(oldStart
); 
1566     // Match padding before suffix 
1567     if (fFormatWidth 
> 0 && fPadPosition 
== kPadBeforeSuffix
) { 
1568         position 
= skipPadding(text
, position
); 
1571     // Match positive and negative suffixes; prefer longest match. 
1572     if (posMatch 
>= 0) { 
1573         posMatch 
= compareAffix(text
, position
, FALSE
, FALSE
, currency
); 
1575     if (negMatch 
>= 0) { 
1576         negMatch 
= compareAffix(text
, position
, TRUE
, FALSE
, currency
); 
1578     if (posMatch 
>= 0 && negMatch 
>= 0) { 
1579         if (posMatch 
> negMatch
) { 
1581         } else if (negMatch 
> posMatch
) { 
1586     // Fail if neither or both 
1587     if ((posMatch 
>= 0) == (negMatch 
>= 0)) { 
1588         parsePosition
.setErrorIndex(position
); 
1592     position 
+= (posMatch
>=0 ? posMatch 
: negMatch
); 
1594     // Match padding before suffix 
1595     if (fFormatWidth 
> 0 && fPadPosition 
== kPadAfterSuffix
) { 
1596         position 
= skipPadding(text
, position
); 
1599     parsePosition
.setIndex(position
); 
1601     digits
.fIsPositive 
= (posMatch 
>= 0); 
1603     if(parsePosition
.getIndex() == oldStart
) 
1605         parsePosition
.setErrorIndex(position
); 
1612  * Starting at position, advance past a run of pad characters, if any. 
1613  * Return the index of the first character after position that is not a pad 
1614  * character.  Result is >= position. 
1616 int32_t DecimalFormat::skipPadding(const UnicodeString
& text
, int32_t position
) const { 
1617     int32_t padLen 
= U16_LENGTH(fPad
); 
1618     while (position 
< text
.length() && 
1619            text
.char32At(position
) == fPad
) { 
1626  * Return the length matched by the given affix, or -1 if none. 
1627  * Runs of white space in the affix, match runs of white space in 
1628  * the input.  Pattern white space and input white space are 
1629  * determined differently; see code. 
1630  * @param text input text 
1631  * @param pos offset into input at which to begin matching 
1634  * @param currency return value for parsed currency, for generic 
1635  * currency parsing mode, or null for normal parsing. In generic 
1636  * currency parsing mode, any currency is parsed, not just the 
1637  * currency that this formatter is set to. 
1638  * @return length of input that matches, or -1 if match failure 
1640 int32_t DecimalFormat::compareAffix(const UnicodeString
& text
, 
1644                                     UChar
* currency
) const { 
1645     if (fCurrencyChoice 
!= NULL 
|| currency 
!= NULL
) { 
1647             return compareComplexAffix(isNegative 
? *fNegPrefixPattern 
: *fPosPrefixPattern
, 
1648                                        text
, pos
, currency
); 
1650             return compareComplexAffix(isNegative 
? *fNegSuffixPattern 
: *fPosSuffixPattern
, 
1651                                        text
, pos
, currency
); 
1656         return compareSimpleAffix(isNegative 
? fNegativePrefix 
: fPositivePrefix
, 
1659         return compareSimpleAffix(isNegative 
? fNegativeSuffix 
: fPositiveSuffix
, 
1665  * Return the length matched by the given affix, or -1 if none. 
1666  * Runs of white space in the affix, match runs of white space in 
1667  * the input.  Pattern white space and input white space are 
1668  * determined differently; see code. 
1669  * @param affix pattern string, taken as a literal 
1670  * @param input input text 
1671  * @param pos offset into input at which to begin matching 
1672  * @return length of input that matches, or -1 if match failure 
1674 int32_t DecimalFormat::compareSimpleAffix(const UnicodeString
& affix
, 
1675                                           const UnicodeString
& input
, 
1677     int32_t start 
= pos
; 
1678     for (int32_t i
=0; i
<affix
.length(); ) { 
1679         UChar32 c 
= affix
.char32At(i
); 
1680         int32_t len 
= U16_LENGTH(c
); 
1681         if (uprv_isRuleWhiteSpace(c
)) { 
1682             // We may have a pattern like: \u200F \u0020 
1683             //        and input text like: \u200F \u0020 
1684             // Note that U+200F and U+0020 are RuleWhiteSpace but only 
1685             // U+0020 is UWhiteSpace.  So we have to first do a direct 
1686             // match of the run of RULE whitespace in the pattern, 
1687             // then match any extra characters. 
1688             UBool literalMatch 
= FALSE
; 
1689             while (pos 
< input
.length() && 
1690                    input
.char32At(pos
) == c
) { 
1691                 literalMatch 
= TRUE
; 
1694                 if (i 
== affix
.length()) { 
1697                 c 
= affix
.char32At(i
); 
1698                 len 
= U16_LENGTH(c
); 
1699                 if (!uprv_isRuleWhiteSpace(c
)) { 
1704             // Advance over run in pattern 
1705             i 
= skipRuleWhiteSpace(affix
, i
); 
1707             // Advance over run in input text 
1708             // Must see at least one white space char in input, 
1709             // unless we've already matched some characters literally. 
1711             pos 
= skipUWhiteSpace(input
, pos
); 
1712             if (pos 
== s 
&& !literalMatch
) { 
1716             if (pos 
< input
.length() && 
1717                 input
.char32At(pos
) == c
) { 
1729  * Skip over a run of zero or more isRuleWhiteSpace() characters at 
1732 int32_t DecimalFormat::skipRuleWhiteSpace(const UnicodeString
& text
, int32_t pos
) { 
1733     while (pos 
< text
.length()) { 
1734         UChar32 c 
= text
.char32At(pos
); 
1735         if (!uprv_isRuleWhiteSpace(c
)) { 
1738         pos 
+= U16_LENGTH(c
); 
1744  * Skip over a run of zero or more isUWhiteSpace() characters at pos 
1747 int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString
& text
, int32_t pos
) { 
1748     while (pos 
< text
.length()) { 
1749         UChar32 c 
= text
.char32At(pos
); 
1750         if (!u_isUWhiteSpace(c
)) { 
1753         pos 
+= U16_LENGTH(c
); 
1759  * Return the length matched by the given affix, or -1 if none. 
1760  * @param affixPat pattern string 
1761  * @param input input text 
1762  * @param pos offset into input at which to begin matching 
1763  * @param currency return value for parsed currency, for generic 
1764  * currency parsing mode, or null for normal parsing. In generic 
1765  * currency parsing mode, any currency is parsed, not just the 
1766  * currency that this formatter is set to. 
1767  * @return length of input that matches, or -1 if match failure 
1769 int32_t DecimalFormat::compareComplexAffix(const UnicodeString
& affixPat
, 
1770                                            const UnicodeString
& text
, 
1772                                            UChar
* currency
) const { 
1773     U_ASSERT(currency 
!= NULL 
|| 
1774              (fCurrencyChoice 
!= NULL 
&& *getCurrency() != 0)); 
1776     for (int32_t i
=0; i
<affixPat
.length() && pos 
>= 0; ) { 
1777         UChar32 c 
= affixPat
.char32At(i
); 
1781             U_ASSERT(i 
<= affixPat
.length()); 
1782             c 
= affixPat
.char32At(i
); 
1785             const UnicodeString
* affix 
= NULL
; 
1788             case kCurrencySign
: { 
1789                 // If currency != null, then perform generic currency matching. 
1790                 // Otherwise, do currency choice parsing. 
1791                 UBool intl 
= i
<affixPat
.length() && 
1792                     affixPat
.char32At(i
) == kCurrencySign
; 
1793                 // Parse generic currency -- anything for which we 
1794                 // have a display name, or any 3-letter ISO code. 
1795                 if (currency 
!= NULL
) { 
1796                     // Try to parse display name for our locale; first 
1797                     // determine our locale. 
1798                     UErrorCode ec 
= U_ZERO_ERROR
; 
1799                     const char* loc 
= getLocaleID(ULOC_VALID_LOCALE
, ec
); 
1800                     if (U_FAILURE(ec
) || loc 
== NULL 
|| *loc 
== 0) { 
1801                         // applyPattern has been called; use the symbols 
1802                         loc 
= fSymbols
->getLocale().getName(); 
1805                     // Delegate parse of display name => ISO code to Currency 
1806                     ParsePosition 
ppos(pos
); 
1808                     uprv_parseCurrency(loc
, text
, ppos
, curr
, ec
); 
1810                     // If parse succeeds, populate currency[0] 
1811                     if (U_SUCCESS(ec
) && ppos
.getIndex() != pos
) { 
1812                         u_strcpy(currency
, curr
); 
1813                         pos 
= ppos
.getIndex(); 
1820                         pos 
= match(text
, pos
, getCurrency()); 
1822                         ParsePosition 
ppos(pos
); 
1824                         fCurrencyChoice
->parse(text
, result
, ppos
); 
1825                         pos 
= (ppos
.getIndex() == pos
) ? -1 : ppos
.getIndex(); 
1830             case kPatternPercent
: 
1831                 affix 
= &getConstSymbol(DecimalFormatSymbols::kPercentSymbol
); 
1833             case kPatternPerMill
: 
1834                 affix 
= &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
); 
1837                 affix 
= &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
); 
1840                 affix 
= &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
); 
1843                 // fall through to affix!=0 test, which will fail 
1847             if (affix 
!= NULL
) { 
1848                 pos 
= match(text
, pos
, *affix
); 
1853         pos 
= match(text
, pos
, c
); 
1854         if (uprv_isRuleWhiteSpace(c
)) { 
1855             i 
= skipRuleWhiteSpace(affixPat
, i
); 
1862  * Match a single character at text[pos] and return the index of the 
1863  * next character upon success.  Return -1 on failure.  If 
1864  * isRuleWhiteSpace(ch) then match a run of white space in text. 
1866 int32_t DecimalFormat::match(const UnicodeString
& text
, int32_t pos
, UChar32 ch
) { 
1867     if (uprv_isRuleWhiteSpace(ch
)) { 
1868         // Advance over run of white space in input text 
1869         // Must see at least one white space char in input 
1871         pos 
= skipUWhiteSpace(text
, pos
); 
1877     return (pos 
>= 0 && text
.char32At(pos
) == ch
) ? 
1878         (pos 
+ U16_LENGTH(ch
)) : -1; 
1882  * Match a string at text[pos] and return the index of the next 
1883  * character upon success.  Return -1 on failure.  Match a run of 
1884  * white space in str with a run of white space in text. 
1886 int32_t DecimalFormat::match(const UnicodeString
& text
, int32_t pos
, const UnicodeString
& str
) { 
1887     for (int32_t i
=0; i
<str
.length() && pos 
>= 0; ) { 
1888         UChar32 ch 
= str
.char32At(i
); 
1889         i 
+= U16_LENGTH(ch
); 
1890         if (uprv_isRuleWhiteSpace(ch
)) { 
1891             i 
= skipRuleWhiteSpace(str
, i
); 
1893         pos 
= match(text
, pos
, ch
); 
1898 //------------------------------------------------------------------------------ 
1899 // Gets the pointer to the localized decimal format symbols 
1901 const DecimalFormatSymbols
* 
1902 DecimalFormat::getDecimalFormatSymbols() const 
1907 //------------------------------------------------------------------------------ 
1908 // De-owning the current localized symbols and adopt the new symbols. 
1911 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols
* symbolsToAdopt
) 
1913     if (symbolsToAdopt 
== NULL
) { 
1914         return; // do not allow caller to set fSymbols to NULL 
1917     UBool sameSymbols 
= FALSE
; 
1918     if (fSymbols 
!= NULL
) { 
1919         sameSymbols 
= (UBool
)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) == 
1920             symbolsToAdopt
->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) && 
1921             getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
) == 
1922             symbolsToAdopt
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
)); 
1926     fSymbols 
= symbolsToAdopt
; 
1928         // If the currency symbols are the same, there is no need to recalculate. 
1929         setCurrencyForSymbols(); 
1933 //------------------------------------------------------------------------------ 
1934 // Setting the symbols is equlivalent to adopting a newly created localized 
1938 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols
& symbols
) 
1940     adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols
)); 
1944  * Update the currency object to match the symbols.  This method 
1945  * is used only when the caller has passed in a symbols object 
1946  * that may not be the default object for its locale. 
1949 DecimalFormat::setCurrencyForSymbols() { 
1951       Update the affix strings accroding to symbols in order to keep 
1952       the affix strings up to date. 
1956     // With the introduction of the Currency object, the currency 
1957     // symbols in the DFS object are ignored.  For backward 
1958     // compatibility, we check any explicitly set DFS object.  If it 
1959     // is a default symbols object for its locale, we change the 
1960     // currency object to one for that locale.  If it is custom, 
1961     // we set the currency to null. 
1962     UErrorCode ec 
= U_ZERO_ERROR
; 
1963     const UChar
* c 
= NULL
; 
1964     const char* loc 
= fSymbols
->getLocale().getName(); 
1965     UChar intlCurrencySymbol
[4];  
1966     ucurr_forLocale(loc
, intlCurrencySymbol
, 4, &ec
); 
1967     UnicodeString currencySymbol
; 
1969     uprv_getStaticCurrencyName(intlCurrencySymbol
, loc
, currencySymbol
, ec
); 
1971         && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) == currencySymbol
 
1972         && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
) == intlCurrencySymbol
) 
1974         // Trap an error in mapping locale to currency.  If we can't 
1975         // map, then don't fail and set the currency to "". 
1976         c 
= intlCurrencySymbol
; 
1978     ec 
= U_ZERO_ERROR
; // reset local error code! 
1983 //------------------------------------------------------------------------------ 
1984 // Gets the positive prefix of the number pattern. 
1987 DecimalFormat::getPositivePrefix(UnicodeString
& result
) const 
1989     result 
= fPositivePrefix
; 
1993 //------------------------------------------------------------------------------ 
1994 // Sets the positive prefix of the number pattern. 
1997 DecimalFormat::setPositivePrefix(const UnicodeString
& newValue
) 
1999     fPositivePrefix 
= newValue
; 
2000     delete fPosPrefixPattern
; 
2001     fPosPrefixPattern 
= 0; 
2004 //------------------------------------------------------------------------------ 
2005 // Gets the negative prefix  of the number pattern. 
2008 DecimalFormat::getNegativePrefix(UnicodeString
& result
) const 
2010     result 
= fNegativePrefix
; 
2014 //------------------------------------------------------------------------------ 
2015 // Gets the negative prefix  of the number pattern. 
2018 DecimalFormat::setNegativePrefix(const UnicodeString
& newValue
) 
2020     fNegativePrefix 
= newValue
; 
2021     delete fNegPrefixPattern
; 
2022     fNegPrefixPattern 
= 0; 
2025 //------------------------------------------------------------------------------ 
2026 // Gets the positive suffix of the number pattern. 
2029 DecimalFormat::getPositiveSuffix(UnicodeString
& result
) const 
2031     result 
= fPositiveSuffix
; 
2035 //------------------------------------------------------------------------------ 
2036 // Sets the positive suffix of the number pattern. 
2039 DecimalFormat::setPositiveSuffix(const UnicodeString
& newValue
) 
2041     fPositiveSuffix 
= newValue
; 
2042     delete fPosSuffixPattern
; 
2043     fPosSuffixPattern 
= 0; 
2046 //------------------------------------------------------------------------------ 
2047 // Gets the negative suffix of the number pattern. 
2050 DecimalFormat::getNegativeSuffix(UnicodeString
& result
) const 
2052     result 
= fNegativeSuffix
; 
2056 //------------------------------------------------------------------------------ 
2057 // Sets the negative suffix of the number pattern. 
2060 DecimalFormat::setNegativeSuffix(const UnicodeString
& newValue
) 
2062     fNegativeSuffix 
= newValue
; 
2063     delete fNegSuffixPattern
; 
2064     fNegSuffixPattern 
= 0; 
2067 //------------------------------------------------------------------------------ 
2068 // Gets the multiplier of the number pattern. 
2070 int32_t DecimalFormat::getMultiplier() const 
2075 //------------------------------------------------------------------------------ 
2076 // Sets the multiplier of the number pattern. 
2078 DecimalFormat::setMultiplier(int32_t newValue
) 
2080     // This shouldn't be set to 0. 
2081     // Due to compatibility with ICU4J we cannot set an error code and refuse 0. 
2082     // So the rest of the code should ignore fMultiplier when it's 0. [grhoten] 
2083     fMultiplier 
= newValue
; 
2087  * Get the rounding increment. 
2088  * @return A positive rounding increment, or 0.0 if rounding 
2090  * @see #setRoundingIncrement 
2091  * @see #getRoundingMode 
2092  * @see #setRoundingMode 
2094 double DecimalFormat::getRoundingIncrement() const { 
2095     return fRoundingDouble
; 
2099  * Set the rounding increment.  This method also controls whether 
2100  * rounding is enabled. 
2101  * @param newValue A positive rounding increment, or 0.0 to disable rounding. 
2102  * Negative increments are equivalent to 0.0. 
2103  * @see #getRoundingIncrement 
2104  * @see #getRoundingMode 
2105  * @see #setRoundingMode 
2107 void DecimalFormat::setRoundingIncrement(double newValue
) { 
2108     if (newValue 
> 0.0) { 
2109         if (fRoundingIncrement 
== NULL
) { 
2110             fRoundingIncrement 
= new DigitList(); 
2112         fRoundingIncrement
->set((int32_t)newValue
); 
2113         fRoundingDouble 
= newValue
; 
2115         delete fRoundingIncrement
; 
2116         fRoundingIncrement 
= NULL
; 
2117         fRoundingDouble 
= 0.0; 
2122  * Get the rounding mode. 
2123  * @return A rounding mode 
2124  * @see #setRoundingIncrement 
2125  * @see #getRoundingIncrement 
2126  * @see #setRoundingMode 
2128 DecimalFormat::ERoundingMode 
DecimalFormat::getRoundingMode() const { 
2129     return fRoundingMode
; 
2133  * Set the rounding mode.  This has no effect unless the rounding 
2134  * increment is greater than zero. 
2135  * @param roundingMode A rounding mode 
2136  * @see #setRoundingIncrement 
2137  * @see #getRoundingIncrement 
2138  * @see #getRoundingMode 
2140 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode
) { 
2141     fRoundingMode 
= roundingMode
; 
2145  * Get the width to which the output of <code>format()</code> is padded. 
2146  * @return the format width, or zero if no padding is in effect 
2147  * @see #setFormatWidth 
2148  * @see #getPadCharacter 
2149  * @see #setPadCharacter 
2150  * @see #getPadPosition 
2151  * @see #setPadPosition 
2153 int32_t DecimalFormat::getFormatWidth() const { 
2154     return fFormatWidth
; 
2158  * Set the width to which the output of <code>format()</code> is padded. 
2159  * This method also controls whether padding is enabled. 
2160  * @param width the width to which to pad the result of 
2161  * <code>format()</code>, or zero to disable padding.  A negative 
2162  * width is equivalent to 0. 
2163  * @see #getFormatWidth 
2164  * @see #getPadCharacter 
2165  * @see #setPadCharacter 
2166  * @see #getPadPosition 
2167  * @see #setPadPosition 
2169 void DecimalFormat::setFormatWidth(int32_t width
) { 
2170     fFormatWidth 
= (width 
> 0) ? width 
: 0; 
2173 UnicodeString 
DecimalFormat::getPadCharacterString() const { 
2177 void DecimalFormat::setPadCharacter(const UnicodeString 
&padChar
) { 
2178     if (padChar
.length() > 0) { 
2179         fPad 
= padChar
.char32At(0); 
2187  * Get the position at which padding will take place.  This is the location 
2188  * at which padding will be inserted if the result of <code>format()</code> 
2189  * is shorter than the format width. 
2190  * @return the pad position, one of <code>kPadBeforePrefix</code>, 
2191  * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or 
2192  * <code>kPadAfterSuffix</code>. 
2193  * @see #setFormatWidth 
2194  * @see #getFormatWidth 
2195  * @see #setPadCharacter 
2196  * @see #getPadCharacter 
2197  * @see #setPadPosition 
2198  * @see #kPadBeforePrefix 
2199  * @see #kPadAfterPrefix 
2200  * @see #kPadBeforeSuffix 
2201  * @see #kPadAfterSuffix 
2203 DecimalFormat::EPadPosition 
DecimalFormat::getPadPosition() const { 
2204     return fPadPosition
; 
2208  * <strong><font face=helvetica color=red>NEW</font></strong> 
2209  * Set the position at which padding will take place.  This is the location 
2210  * at which padding will be inserted if the result of <code>format()</code> 
2211  * is shorter than the format width.  This has no effect unless padding is 
2213  * @param padPos the pad position, one of <code>kPadBeforePrefix</code>, 
2214  * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or 
2215  * <code>kPadAfterSuffix</code>. 
2216  * @see #setFormatWidth 
2217  * @see #getFormatWidth 
2218  * @see #setPadCharacter 
2219  * @see #getPadCharacter 
2220  * @see #getPadPosition 
2221  * @see #kPadBeforePrefix 
2222  * @see #kPadAfterPrefix 
2223  * @see #kPadBeforeSuffix 
2224  * @see #kPadAfterSuffix 
2226 void DecimalFormat::setPadPosition(EPadPosition padPos
) { 
2227     fPadPosition 
= padPos
; 
2231  * Return whether or not scientific notation is used. 
2232  * @return TRUE if this object formats and parses scientific notation 
2233  * @see #setScientificNotation 
2234  * @see #getMinimumExponentDigits 
2235  * @see #setMinimumExponentDigits 
2236  * @see #isExponentSignAlwaysShown 
2237  * @see #setExponentSignAlwaysShown 
2239 UBool 
DecimalFormat::isScientificNotation() { 
2240     return fUseExponentialNotation
; 
2244  * Set whether or not scientific notation is used. 
2245  * @param useScientific TRUE if this object formats and parses scientific 
2247  * @see #isScientificNotation 
2248  * @see #getMinimumExponentDigits 
2249  * @see #setMinimumExponentDigits 
2250  * @see #isExponentSignAlwaysShown 
2251  * @see #setExponentSignAlwaysShown 
2253 void DecimalFormat::setScientificNotation(UBool useScientific
) { 
2254     fUseExponentialNotation 
= useScientific
; 
2258  * Return the minimum exponent digits that will be shown. 
2259  * @return the minimum exponent digits that will be shown 
2260  * @see #setScientificNotation 
2261  * @see #isScientificNotation 
2262  * @see #setMinimumExponentDigits 
2263  * @see #isExponentSignAlwaysShown 
2264  * @see #setExponentSignAlwaysShown 
2266 int8_t DecimalFormat::getMinimumExponentDigits() const { 
2267     return fMinExponentDigits
; 
2271  * Set the minimum exponent digits that will be shown.  This has no 
2272  * effect unless scientific notation is in use. 
2273  * @param minExpDig a value >= 1 indicating the fewest exponent digits 
2274  * that will be shown.  Values less than 1 will be treated as 1. 
2275  * @see #setScientificNotation 
2276  * @see #isScientificNotation 
2277  * @see #getMinimumExponentDigits 
2278  * @see #isExponentSignAlwaysShown 
2279  * @see #setExponentSignAlwaysShown 
2281 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig
) { 
2282     fMinExponentDigits 
= (int8_t)((minExpDig 
> 0) ? minExpDig 
: 1); 
2286  * Return whether the exponent sign is always shown. 
2287  * @return TRUE if the exponent is always prefixed with either the 
2288  * localized minus sign or the localized plus sign, false if only negative 
2289  * exponents are prefixed with the localized minus sign. 
2290  * @see #setScientificNotation 
2291  * @see #isScientificNotation 
2292  * @see #setMinimumExponentDigits 
2293  * @see #getMinimumExponentDigits 
2294  * @see #setExponentSignAlwaysShown 
2296 UBool 
DecimalFormat::isExponentSignAlwaysShown() { 
2297     return fExponentSignAlwaysShown
; 
2301  * Set whether the exponent sign is always shown.  This has no effect 
2302  * unless scientific notation is in use. 
2303  * @param expSignAlways TRUE if the exponent is always prefixed with either 
2304  * the localized minus sign or the localized plus sign, false if only 
2305  * negative exponents are prefixed with the localized minus sign. 
2306  * @see #setScientificNotation 
2307  * @see #isScientificNotation 
2308  * @see #setMinimumExponentDigits 
2309  * @see #getMinimumExponentDigits 
2310  * @see #isExponentSignAlwaysShown 
2312 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways
) { 
2313     fExponentSignAlwaysShown 
= expSignAlways
; 
2316 //------------------------------------------------------------------------------ 
2317 // Gets the grouping size of the number pattern.  For example, thousand or 10 
2318 // thousand groupings. 
2321 DecimalFormat::getGroupingSize() const 
2323     return fGroupingSize
; 
2326 //------------------------------------------------------------------------------ 
2327 // Gets the grouping size of the number pattern. 
2330 DecimalFormat::setGroupingSize(int32_t newValue
) 
2332     fGroupingSize 
= newValue
; 
2335 //------------------------------------------------------------------------------ 
2338 DecimalFormat::getSecondaryGroupingSize() const 
2340     return fGroupingSize2
; 
2343 //------------------------------------------------------------------------------ 
2346 DecimalFormat::setSecondaryGroupingSize(int32_t newValue
) 
2348     fGroupingSize2 
= newValue
; 
2351 //------------------------------------------------------------------------------ 
2352 // Checks if to show the decimal separator. 
2355 DecimalFormat::isDecimalSeparatorAlwaysShown() const 
2357     return fDecimalSeparatorAlwaysShown
; 
2360 //------------------------------------------------------------------------------ 
2361 // Sets to always show the decimal separator. 
2364 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue
) 
2366     fDecimalSeparatorAlwaysShown 
= newValue
; 
2369 //------------------------------------------------------------------------------ 
2370 // Emits the pattern of this DecimalFormat instance. 
2373 DecimalFormat::toPattern(UnicodeString
& result
) const 
2375     return toPattern(result
, FALSE
); 
2378 //------------------------------------------------------------------------------ 
2379 // Emits the localized pattern this DecimalFormat instance. 
2382 DecimalFormat::toLocalizedPattern(UnicodeString
& result
) const 
2384     return toPattern(result
, TRUE
); 
2387 //------------------------------------------------------------------------------ 
2389  * Expand the affix pattern strings into the expanded affix strings.  If any 
2390  * affix pattern string is null, do not expand it.  This method should be 
2391  * called any time the symbols or the affix patterns change in order to keep 
2392  * the expanded affix strings up to date. 
2394 void DecimalFormat::expandAffixes() { 
2395     if (fPosPrefixPattern 
!= 0) { 
2396         expandAffix(*fPosPrefixPattern
, fPositivePrefix
, 0, FALSE
); 
2398     if (fPosSuffixPattern 
!= 0) { 
2399         expandAffix(*fPosSuffixPattern
, fPositiveSuffix
, 0, FALSE
); 
2401     if (fNegPrefixPattern 
!= 0) { 
2402         expandAffix(*fNegPrefixPattern
, fNegativePrefix
, 0, FALSE
); 
2404     if (fNegSuffixPattern 
!= 0) { 
2405         expandAffix(*fNegSuffixPattern
, fNegativeSuffix
, 0, FALSE
); 
2410         .append(*fPosPrefixPattern
).append("|").append(*fPosSuffixPattern
) 
2411         .append(";") .append(*fNegPrefixPattern
).append("|").append(*fNegSuffixPattern
) 
2413         .append(fPositivePrefix
).append("|").append(fPositiveSuffix
) 
2414         .append(";") .append(fNegativePrefix
).append("|").append(fNegativeSuffix
) 
2421  * Expand an affix pattern into an affix string.  All characters in the 
2422  * pattern are literal unless prefixed by kQuote.  The following characters 
2423  * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, 
2424  * PATTERN_MINUS, and kCurrencySign.  If kCurrencySign is doubled (kQuote + 
2425  * kCurrencySign + kCurrencySign), it is interpreted as an international 
2426  * currency sign.  Any other character after a kQuote represents itself. 
2427  * kQuote must be followed by another character; kQuote may not occur by 
2428  * itself at the end of the pattern. 
2430  * This method is used in two distinct ways.  First, it is used to expand 
2431  * the stored affix patterns into actual affixes.  For this usage, doFormat 
2432  * must be false.  Second, it is used to expand the stored affix patterns 
2433  * given a specific number (doFormat == true), for those rare cases in 
2434  * which a currency format references a ChoiceFormat (e.g., en_IN display 
2435  * name for INR).  The number itself is taken from digitList. 
2437  * When used in the first way, this method has a side effect: It sets 
2438  * currencyChoice to a ChoiceFormat object, if the currency's display name 
2439  * in this locale is a ChoiceFormat pattern (very rare).  It only does this 
2440  * if currencyChoice is null to start with. 
2442  * @param pattern the non-null, fPossibly empty pattern 
2443  * @param affix string to receive the expanded equivalent of pattern. 
2444  * Previous contents are deleted. 
2445  * @param doFormat if false, then the pattern will be expanded, and if a 
2446  * currency symbol is encountered that expands to a ChoiceFormat, the 
2447  * currencyChoice member variable will be initialized if it is null.  If 
2448  * doFormat is true, then it is assumed that the currencyChoice has been 
2449  * created, and it will be used to format the value in digitList. 
2451 void DecimalFormat::expandAffix(const UnicodeString
& pattern
, 
2452                                 UnicodeString
& affix
, 
2454                                 UBool doFormat
) const { 
2456     for (int i
=0; i
<pattern
.length(); ) { 
2457         UChar32 c 
= pattern
.char32At(i
); 
2460             c 
= pattern
.char32At(i
); 
2463             case kCurrencySign
: { 
2464                 // As of ICU 2.2 we use the currency object, and 
2465                 // ignore the currency symbols in the DFS, unless 
2466                 // we have a null currency object.  This occurs if 
2467                 // resurrecting a pre-2.2 object or if the user 
2468                 // sets a custom DFS. 
2469                 UBool intl 
= i
<pattern
.length() && 
2470                     pattern
.char32At(i
) == kCurrencySign
; 
2474                 const UChar
* currencyUChars 
= getCurrency(); 
2475                 if (currencyUChars
[0] != 0) { 
2476                     UErrorCode ec 
= U_ZERO_ERROR
; 
2478                         affix 
+= currencyUChars
; 
2481                         UBool isChoiceFormat
; 
2482                         const UChar
* s 
= ucurr_getName(currencyUChars
, fSymbols
->getLocale().getName(), 
2483                                                        UCURR_SYMBOL_NAME
, &isChoiceFormat
, &len
, &ec
); 
2484                         if (isChoiceFormat
) { 
2485                             // Two modes here: If doFormat is false, we set up 
2486                             // currencyChoice.  If doFormat is true, we use the 
2487                             // previously created currencyChoice to format the 
2488                             // value in digitList. 
2490                                 // If the currency is handled by a ChoiceFormat, 
2491                                 // then we're not going to use the expanded 
2492                                 // patterns.  Instantiate the ChoiceFormat and 
2494                                 if (fCurrencyChoice 
== NULL
) { 
2495                                     // TODO Replace double-check with proper thread-safe code 
2496                                     ChoiceFormat
* fmt 
= new ChoiceFormat(s
, ec
); 
2497                                     if (U_SUCCESS(ec
)) { 
2499                                         if (fCurrencyChoice 
== NULL
) { 
2501                                             ((DecimalFormat
*)this)->fCurrencyChoice 
= fmt
; 
2508                                 // We could almost return null or "" here, since the 
2509                                 // expanded affixes are almost not used at all 
2510                                 // in this situation.  However, one method -- 
2511                                 // toPattern() -- still does use the expanded 
2512                                 // affixes, in order to set up a padding 
2513                                 // pattern.  We use the CURRENCY_SIGN as a 
2515                                 affix
.append(kCurrencySign
); 
2517                                 if (fCurrencyChoice 
!= NULL
) { 
2518                                     FieldPosition 
pos(0); // ignored 
2522                                     fCurrencyChoice
->format(number
, affix
, pos
); 
2524                                     // We only arrive here if the currency choice 
2525                                     // format in the locale data is INVALID. 
2526                                     affix 
+= currencyUChars
; 
2531                         affix 
+= UnicodeString(s
, len
); 
2535                         affix 
+= getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
); 
2537                         affix 
+= getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
); 
2542             case kPatternPercent
: 
2543                 affix 
+= getConstSymbol(DecimalFormatSymbols::kPercentSymbol
); 
2545             case kPatternPerMill
: 
2546                 affix 
+= getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
); 
2549                 affix 
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
); 
2552                 affix 
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
); 
2566  * Append an affix to the given StringBuffer. 
2567  * @param buf buffer to append to 
2571 int32_t DecimalFormat::appendAffix(UnicodeString
& buf
, double number
, 
2572                                    UBool isNegative
, UBool isPrefix
) const { 
2573     if (fCurrencyChoice 
!= 0) { 
2574         const UnicodeString
* affixPat 
= 0; 
2576             affixPat 
= isNegative 
? fNegPrefixPattern 
: fPosPrefixPattern
; 
2578             affixPat 
= isNegative 
? fNegSuffixPattern 
: fPosSuffixPattern
; 
2580         UnicodeString affixBuf
; 
2581         expandAffix(*affixPat
, affixBuf
, number
, TRUE
); 
2582         buf
.append(affixBuf
); 
2583         return affixBuf
.length(); 
2586     const UnicodeString
* affix 
= NULL
; 
2588         affix 
= isNegative 
? &fNegativePrefix 
: &fPositivePrefix
; 
2590         affix 
= isNegative 
? &fNegativeSuffix 
: &fPositiveSuffix
; 
2593     return affix
->length(); 
2597  * Appends an affix pattern to the given StringBuffer, quoting special 
2598  * characters as needed.  Uses the internal affix pattern, if that exists, 
2599  * or the literal affix, if the internal affix pattern is null.  The 
2600  * appended string will generate the same affix pattern (or literal affix) 
2601  * when passed to toPattern(). 
2603  * @param appendTo the affix string is appended to this 
2604  * @param affixPattern a pattern such as fPosPrefixPattern; may be null 
2605  * @param expAffix a corresponding expanded affix, such as fPositivePrefix. 
2606  * Ignored unless affixPattern is null.  If affixPattern is null, then 
2607  * expAffix is appended as a literal affix. 
2608  * @param localized true if the appended pattern should contain localized 
2609  * pattern characters; otherwise, non-localized pattern chars are appended 
2611 void DecimalFormat::appendAffixPattern(UnicodeString
& appendTo
, 
2612                                        const UnicodeString
* affixPattern
, 
2613                                        const UnicodeString
& expAffix
, 
2614                                        UBool localized
) const { 
2615     if (affixPattern 
== 0) { 
2616         appendAffixPattern(appendTo
, expAffix
, localized
); 
2619         for (int pos
=0; pos
<affixPattern
->length(); pos
=i
) { 
2620             i 
= affixPattern
->indexOf(kQuote
, pos
); 
2623                 affixPattern
->extractBetween(pos
, affixPattern
->length(), s
); 
2624                 appendAffixPattern(appendTo
, s
, localized
); 
2629                 affixPattern
->extractBetween(pos
, i
, s
); 
2630                 appendAffixPattern(appendTo
, s
, localized
); 
2632             UChar32 c 
= affixPattern
->char32At(++i
); 
2635                 appendTo
.append(c
).append(c
); 
2636                 // Fall through and append another kQuote below 
2637             } else if (c 
== kCurrencySign 
&& 
2638                        i
<affixPattern
->length() && 
2639                        affixPattern
->char32At(i
) == kCurrencySign
) { 
2641                 appendTo
.append(c
).append(c
); 
2642             } else if (localized
) { 
2644                 case kPatternPercent
: 
2645                     appendTo 
+= getConstSymbol(DecimalFormatSymbols::kPercentSymbol
); 
2647                 case kPatternPerMill
: 
2648                     appendTo 
+= getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
); 
2651                     appendTo 
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
); 
2654                     appendTo 
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
); 
2667  * Append an affix to the given StringBuffer, using quotes if 
2668  * there are special characters.  Single quotes themselves must be 
2669  * escaped in either case. 
2672 DecimalFormat::appendAffixPattern(UnicodeString
& appendTo
, 
2673                                   const UnicodeString
& affix
, 
2674                                   UBool localized
) const { 
2677         needQuote 
= affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
)) >= 0 
2678             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
)) >= 0 
2679             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
)) >= 0 
2680             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
)) >= 0 
2681             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
)) >= 0 
2682             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
)) >= 0 
2683             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
)) >= 0 
2684             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
)) >= 0 
2685             || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)) >= 0 
2686             || affix
.indexOf(kCurrencySign
) >= 0; 
2689         needQuote 
= affix
.indexOf(kPatternZeroDigit
) >= 0 
2690             || affix
.indexOf(kPatternGroupingSeparator
) >= 0 
2691             || affix
.indexOf(kPatternDecimalSeparator
) >= 0 
2692             || affix
.indexOf(kPatternPercent
) >= 0 
2693             || affix
.indexOf(kPatternPerMill
) >= 0 
2694             || affix
.indexOf(kPatternDigit
) >= 0 
2695             || affix
.indexOf(kPatternSeparator
) >= 0 
2696             || affix
.indexOf(kPatternExponent
) >= 0 
2697             || affix
.indexOf(kPatternPlus
) >= 0 
2698             || affix
.indexOf(kPatternMinus
) >= 0 
2699             || affix
.indexOf(kCurrencySign
) >= 0; 
2702         appendTo 
+= (UChar
)0x0027 /*'\''*/; 
2703     if (affix
.indexOf((UChar
)0x0027 /*'\''*/) < 0) 
2706         for (int32_t j 
= 0; j 
< affix
.length(); ) { 
2707             UChar32 c 
= affix
.char32At(j
); 
2710             if (c 
== 0x0027 /*'\''*/) 
2715         appendTo 
+= (UChar
)0x0027 /*'\''*/; 
2718 //------------------------------------------------------------------------------ 
2720 /* Tell the VC++ compiler not to spew out the warnings about integral size conversion */ 
2723 #pragma warning( disable : 4761 ) 
2728 DecimalFormat::toPattern(UnicodeString
& result
, UBool localized
) const 
2731     UChar32 zero
, sigDigit 
= kPatternSignificantDigit
; 
2732     UnicodeString digit
, group
; 
2734     int32_t roundingDecimalPos 
= 0; // Pos of decimal in roundingDigits 
2735     UnicodeString roundingDigits
; 
2736     int32_t padPos 
= (fFormatWidth 
> 0) ? fPadPosition 
: -1; 
2737     UnicodeString padSpec
; 
2738     UBool useSigDig 
= areSignificantDigitsUsed(); 
2741         digit
.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
)); 
2742         group
.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
)); 
2743         zero 
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0); 
2745             sigDigit 
= getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
).char32At(0); 
2749         digit
.append((UChar
)kPatternDigit
); 
2750         group
.append((UChar
)kPatternGroupingSeparator
); 
2751         zero 
= (UChar32
)kPatternZeroDigit
; 
2753     if (fFormatWidth 
> 0) { 
2755             padSpec
.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
)); 
2758             padSpec
.append((UChar
)kPatternPadEscape
); 
2760         padSpec
.append(fPad
); 
2762     if (fRoundingIncrement 
!= NULL
) { 
2763         for(i
=0; i
<fRoundingIncrement
->fCount
; ++i
) { 
2764             roundingDigits
.append((UChar
)fRoundingIncrement
->fDigits
[i
]); 
2766         roundingDecimalPos 
= fRoundingIncrement
->fDecimalAt
; 
2768     for (int32_t part
=0; part
<2; ++part
) { 
2769         if (padPos 
== kPadBeforePrefix
) { 
2770             result
.append(padSpec
); 
2772         appendAffixPattern(result
, 
2773                     (part
==0 ? fPosPrefixPattern 
: fNegPrefixPattern
), 
2774                     (part
==0 ? fPositivePrefix 
: fNegativePrefix
), 
2776         if (padPos 
== kPadAfterPrefix 
&& ! padSpec
.isEmpty()) { 
2777             result
.append(padSpec
); 
2779         int32_t sub0Start 
= result
.length(); 
2780         int32_t g 
= isGroupingUsed() ? _max(0, fGroupingSize
) : 0; 
2781         if (g 
> 0 && fGroupingSize2 
> 0 && fGroupingSize2 
!= fGroupingSize
) { 
2782             g 
+= fGroupingSize2
; 
2784         int32_t maxDig 
= 0, minDig 
= 0, maxSigDig 
= 0; 
2786             minDig 
= getMinimumSignificantDigits(); 
2787             maxDig 
= maxSigDig 
= getMaximumSignificantDigits(); 
2789             minDig 
= getMinimumIntegerDigits(); 
2790             maxDig 
= getMaximumIntegerDigits(); 
2792         if (fUseExponentialNotation
) { 
2793             if (maxDig 
> kMaxScientificIntegerDigits
) { 
2796         } else if (useSigDig
) { 
2797             maxDig 
= _max(maxDig
, g
+1); 
2799             maxDig 
= _max(_max(g
, getMinimumIntegerDigits()), 
2800                           roundingDecimalPos
) + 1; 
2802         for (i 
= maxDig
; i 
> 0; --i
) { 
2803             if (!fUseExponentialNotation 
&& i
<maxDig 
&& 
2804                 isGroupingPosition(i
)) { 
2805                 result
.append(group
); 
2808                 //  #@,@###   (maxSigDig == 5, minSigDig == 2) 
2809                 //  65 4321   (1-based pos, count from the right) 
2810                 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig) 
2811                 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig 
2812                 if (maxSigDig 
>= i 
&& i 
> (maxSigDig 
- minDig
)) { 
2813                     result
.append(sigDigit
); 
2815                     result
.append(digit
); 
2818                 if (! roundingDigits
.isEmpty()) { 
2819                     int32_t pos 
= roundingDecimalPos 
- i
; 
2820                     if (pos 
>= 0 && pos 
< roundingDigits
.length()) { 
2821                         result
.append((UChar
) (roundingDigits
.char32At(pos
) - kPatternZeroDigit 
+ zero
)); 
2826                     result
.append(zero
); 
2828                     result
.append(digit
); 
2833             if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown
) { 
2835                     result 
+= getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
); 
2838                     result
.append((UChar
)kPatternDecimalSeparator
); 
2841             int32_t pos 
= roundingDecimalPos
; 
2842             for (i 
= 0; i 
< getMaximumFractionDigits(); ++i
) { 
2843                 if (! roundingDigits
.isEmpty() && pos 
< roundingDigits
.length()) { 
2845                         result
.append(zero
); 
2848                         result
.append((UChar
)(roundingDigits
.char32At(pos
) - kPatternZeroDigit 
+ zero
)); 
2853                 if (i
<getMinimumFractionDigits()) { 
2854                     result
.append(zero
); 
2857                     result
.append(digit
); 
2861         if (fUseExponentialNotation
) { 
2863                 result 
+= getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
); 
2866                 result
.append((UChar
)kPatternExponent
); 
2868             if (fExponentSignAlwaysShown
) { 
2870                     result 
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
); 
2873                     result
.append((UChar
)kPatternPlus
); 
2876             for (i
=0; i
<fMinExponentDigits
; ++i
) { 
2877                 result
.append(zero
); 
2880         if (! padSpec
.isEmpty() && !fUseExponentialNotation
) { 
2881             int32_t add 
= fFormatWidth 
- result
.length() + sub0Start
 
2883                    ? fPositivePrefix
.length() + fPositiveSuffix
.length() 
2884                    : fNegativePrefix
.length() + fNegativeSuffix
.length()); 
2886                 result
.insert(sub0Start
, digit
); 
2889                 // Only add a grouping separator if we have at least 
2890                 // 2 additional characters to be added, so we don't 
2891                 // end up with ",###". 
2892                 if (add
>1 && isGroupingPosition(maxDig
)) { 
2893                     result
.insert(sub0Start
, group
); 
2898         if (fPadPosition 
== kPadBeforeSuffix 
&& ! padSpec
.isEmpty()) { 
2899             result
.append(padSpec
); 
2902             appendAffixPattern(result
, fPosSuffixPattern
, fPositiveSuffix
, localized
); 
2903             if (fPadPosition 
== kPadAfterSuffix 
&& ! padSpec
.isEmpty()) { 
2904                 result
.append(padSpec
); 
2906             UBool isDefault 
= FALSE
; 
2907             if ((fNegSuffixPattern 
== fPosSuffixPattern 
&& // both null 
2908                  fNegativeSuffix 
== fPositiveSuffix
) 
2909                 || (fNegSuffixPattern 
!= 0 && fPosSuffixPattern 
!= 0 && 
2910                     *fNegSuffixPattern 
== *fPosSuffixPattern
)) 
2912                 if (fNegPrefixPattern 
!= NULL 
&& fPosPrefixPattern 
!= NULL
) 
2914                     int32_t length 
= fPosPrefixPattern
->length(); 
2915                     isDefault 
= fNegPrefixPattern
->length() == (length
+2) && 
2916                         (*fNegPrefixPattern
)[(int32_t)0] == kQuote 
&& 
2917                         (*fNegPrefixPattern
)[(int32_t)1] == kPatternMinus 
&& 
2918                         fNegPrefixPattern
->compare(2, length
, *fPosPrefixPattern
, 0, length
) == 0; 
2921                     fNegPrefixPattern 
== NULL 
&& fPosPrefixPattern 
== NULL
) 
2923                     int32_t length 
= fPositivePrefix
.length(); 
2924                     isDefault 
= fNegativePrefix
.length() == (length
+1) && 
2925                         fNegativePrefix
.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)) == 0 && 
2926                         fNegativePrefix
.compare(1, length
, fPositivePrefix
, 0, length
) == 0; 
2930                 break; // Don't output default negative subpattern 
2933                     result 
+= getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
); 
2936                     result
.append((UChar
)kPatternSeparator
); 
2940             appendAffixPattern(result
, fNegSuffixPattern
, fNegativeSuffix
, localized
); 
2941             if (fPadPosition 
== kPadAfterSuffix 
&& ! padSpec
.isEmpty()) { 
2942                 result
.append(padSpec
); 
2950 //------------------------------------------------------------------------------ 
2953 DecimalFormat::applyPattern(const UnicodeString
& pattern
, UErrorCode
& status
) 
2955     UParseError parseError
; 
2956     applyPattern(pattern
, FALSE
, parseError
, status
); 
2959 //------------------------------------------------------------------------------ 
2962 DecimalFormat::applyPattern(const UnicodeString
& pattern
, 
2963                             UParseError
& parseError
,  
2966     applyPattern(pattern
, FALSE
, parseError
, status
); 
2968 //------------------------------------------------------------------------------ 
2971 DecimalFormat::applyLocalizedPattern(const UnicodeString
& pattern
, UErrorCode
& status
) 
2973     UParseError parseError
; 
2974     applyPattern(pattern
, TRUE
,parseError
,status
); 
2977 //------------------------------------------------------------------------------ 
2980 DecimalFormat::applyLocalizedPattern(const UnicodeString
& pattern
, 
2981                                      UParseError
& parseError
, 
2984     applyPattern(pattern
, TRUE
,parseError
,status
); 
2987 //------------------------------------------------------------------------------ 
2990 DecimalFormat::applyPattern(const UnicodeString
& pattern
, 
2992                             UParseError
& parseError
, 
2995     if (U_FAILURE(status
)) 
2999     // Clear error struct 
3000     parseError
.offset 
= -1; 
3001     parseError
.preContext
[0] = parseError
.postContext
[0] = (UChar
)0; 
3003     // Set the significant pattern symbols 
3004     UChar32 zeroDigit               
= kPatternZeroDigit
; // '0' 
3005     UChar32 sigDigit                
= kPatternSignificantDigit
; // '@' 
3006     UnicodeString 
groupingSeparator ((UChar
)kPatternGroupingSeparator
); 
3007     UnicodeString 
decimalSeparator  ((UChar
)kPatternDecimalSeparator
); 
3008     UnicodeString 
percent           ((UChar
)kPatternPercent
); 
3009     UnicodeString 
perMill           ((UChar
)kPatternPerMill
); 
3010     UnicodeString 
digit             ((UChar
)kPatternDigit
); // '#' 
3011     UnicodeString 
separator         ((UChar
)kPatternSeparator
); 
3012     UnicodeString 
exponent          ((UChar
)kPatternExponent
); 
3013     UnicodeString 
plus              ((UChar
)kPatternPlus
); 
3014     UnicodeString 
minus             ((UChar
)kPatternMinus
); 
3015     UnicodeString 
padEscape         ((UChar
)kPatternPadEscape
); 
3016     // Substitute with the localized symbols if necessary 
3018         zeroDigit 
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0); 
3019         sigDigit 
= getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
).char32At(0); 
3020         groupingSeparator
.  remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
)); 
3021         decimalSeparator
.   remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
)); 
3022         percent
.            remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
)); 
3023         perMill
.            remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
)); 
3024         digit
.              remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
)); 
3025         separator
.          remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
)); 
3026         exponent
.           remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
)); 
3027         plus
.               remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
)); 
3028         minus
.              remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)); 
3029         padEscape
.          remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
)); 
3031     UChar nineDigit 
= (UChar
)(zeroDigit 
+ 9); 
3032     int32_t digitLen 
= digit
.length(); 
3033     int32_t groupSepLen 
= groupingSeparator
.length(); 
3034     int32_t decimalSepLen 
= decimalSeparator
.length(); 
3037     int32_t patLen 
= pattern
.length(); 
3038     // Part 0 is the positive pattern.  Part 1, if present, is the negative 
3040     for (int32_t part
=0; part
<2 && pos
<patLen
; ++part
) { 
3041         // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix, 
3042         // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is 
3043         // between the prefix and suffix, and consists of pattern 
3044         // characters.  In the prefix and suffix, percent, perMill, and 
3045         // currency symbols are recognized and translated. 
3046         int32_t subpart 
= 1, sub0Start 
= 0, sub0Limit 
= 0, sub2Limit 
= 0; 
3048         // It's important that we don't change any fields of this object 
3049         // prematurely.  We set the following variables for the multiplier, 
3050         // grouping, etc., and then only change the actual object fields if 
3051         // everything parses correctly.  This also lets us register 
3052         // the data from part 0 and ignore the part 1, except for the 
3053         // prefix and suffix. 
3054         UnicodeString prefix
; 
3055         UnicodeString suffix
; 
3056         int32_t decimalPos 
= -1; 
3057         int32_t multiplier 
= 1; 
3058         int32_t digitLeftCount 
= 0, zeroDigitCount 
= 0, digitRightCount 
= 0, sigDigitCount 
= 0; 
3059         int8_t groupingCount 
= -1; 
3060         int8_t groupingCount2 
= -1; 
3061         int32_t padPos 
= -1; 
3062         UChar32 padChar 
= 0; 
3063         int32_t roundingPos 
= -1; 
3064         DigitList roundingInc
; 
3065         int8_t expDigits 
= -1; 
3066         UBool expSignAlways 
= FALSE
; 
3067         UBool isCurrency 
= FALSE
; 
3069         // The affix is either the prefix or the suffix. 
3070         UnicodeString
* affix 
= &prefix
; 
3072         int32_t start 
= pos
; 
3073         UBool isPartDone 
= FALSE
; 
3076         for (; !isPartDone 
&& pos 
< patLen
; ) { 
3077             // Todo: account for surrogate pairs 
3078             ch 
= pattern
.char32At(pos
); 
3080             case 0: // Pattern proper subpart (between prefix & suffix) 
3081                 // Process the digits, decimal, and grouping characters.  We 
3082                 // record five pieces of information.  We expect the digits 
3083                 // to occur in the pattern ####00.00####, and we record the 
3084                 // number of left digits, zero (central) digits, and right 
3085                 // digits.  The position of the last grouping character is 
3086                 // recorded (should be somewhere within the first two blocks 
3087                 // of characters), as is the position of the decimal point, 
3088                 // if any (should be in the zero digits).  If there is no 
3089                 // decimal point, then there should be no right digits. 
3090                 if (pattern
.compare(pos
, digitLen
, digit
) == 0) { 
3091                     if (zeroDigitCount 
> 0 || sigDigitCount 
> 0) { 
3096                     if (groupingCount 
>= 0 && decimalPos 
< 0) { 
3100                 } else if ((ch 
>= zeroDigit 
&& ch 
<= nineDigit
) || 
3102                     if (digitRightCount 
> 0) { 
3104                         debug("Unexpected '0'") 
3105                         status 
= U_UNEXPECTED_TOKEN
; 
3106                         syntaxError(pattern
,pos
,parseError
); 
3109                     if (ch 
== sigDigit
) { 
3113                         if (ch 
!= zeroDigit 
&& roundingPos 
< 0) { 
3114                             roundingPos 
= digitLeftCount 
+ zeroDigitCount
; 
3116                         if (roundingPos 
>= 0) { 
3117                             roundingInc
.append((char)(ch 
- zeroDigit 
+ '0')); 
3120                     if (groupingCount 
>= 0 && decimalPos 
< 0) { 
3123                     pos 
+= U16_LENGTH(ch
); 
3124                 } else if (pattern
.compare(pos
, groupSepLen
, groupingSeparator
) == 0) { 
3125                     if (decimalPos 
>= 0) { 
3126                         // Grouping separator after decimal 
3127                         debug("Grouping separator after decimal") 
3128                         status 
= U_UNEXPECTED_TOKEN
; 
3129                         syntaxError(pattern
,pos
,parseError
); 
3132                     groupingCount2 
= groupingCount
; 
3135                 } else if (pattern
.compare(pos
, decimalSepLen
, decimalSeparator
) == 0) { 
3136                     if (decimalPos 
>= 0) { 
3137                         // Multiple decimal separators 
3138                         debug("Multiple decimal separators") 
3139                         status 
= U_MULTIPLE_DECIMAL_SEPARATORS
; 
3140                         syntaxError(pattern
,pos
,parseError
); 
3143                     // Intentionally incorporate the digitRightCount, 
3144                     // even though it is illegal for this to be > 0 
3145                     // at this point.  We check pattern syntax below. 
3146                     decimalPos 
= digitLeftCount 
+ zeroDigitCount 
+ digitRightCount
; 
3147                     pos 
+= decimalSepLen
; 
3149                     if (pattern
.compare(pos
, exponent
.length(), exponent
) == 0) { 
3150                         if (expDigits 
>= 0) { 
3151                             // Multiple exponential symbols 
3152                             debug("Multiple exponential symbols") 
3153                             status 
= U_MULTIPLE_EXPONENTIAL_SYMBOLS
; 
3154                             syntaxError(pattern
,pos
,parseError
); 
3157                         if (groupingCount 
>= 0) { 
3158                             // Grouping separator in exponential pattern 
3159                             debug("Grouping separator in exponential pattern") 
3160                             status 
= U_MALFORMED_EXPONENTIAL_PATTERN
; 
3161                             syntaxError(pattern
,pos
,parseError
); 
3164                         pos 
+= exponent
.length(); 
3165                         // Check for positive prefix 
3167                             && pattern
.compare(pos
, plus
.length(), plus
) == 0) { 
3168                             expSignAlways 
= TRUE
; 
3169                             pos 
+= plus
.length(); 
3171                         // Use lookahead to parse out the exponential part of the 
3172                         // pattern, then jump into suffix subpart. 
3174                         while (pos 
< patLen 
&& 
3175                                pattern
.char32At(pos
) == zeroDigit
) { 
3177                             pos 
+= U16_LENGTH(zeroDigit
); 
3180                         // 1. Require at least one mantissa pattern digit 
3181                         // 2. Disallow "#+ @" in mantissa 
3182                         // 3. Require at least one exponent pattern digit 
3183                         if (((digitLeftCount 
+ zeroDigitCount
) < 1 && 
3184                              (sigDigitCount 
+ digitRightCount
) < 1) || 
3185                             (sigDigitCount 
> 0 && digitLeftCount 
> 0) || 
3187                             // Malformed exponential pattern 
3188                             debug("Malformed exponential pattern") 
3189                             status 
= U_MALFORMED_EXPONENTIAL_PATTERN
; 
3190                             syntaxError(pattern
,pos
,parseError
); 
3194                     // Transition to suffix subpart 
3195                     subpart 
= 2; // suffix subpart 
3201             case 1: // Prefix subpart 
3202             case 2: // Suffix subpart 
3203                 // Process the prefix / suffix characters 
3204                 // Process unquoted characters seen in prefix or suffix 
3207                 // Several syntax characters implicitly begins the 
3208                 // next subpart if we are in the prefix; otherwise 
3209                 // they are illegal if unquoted. 
3210                 if (!pattern
.compare(pos
, digitLen
, digit
) || 
3211                     !pattern
.compare(pos
, groupSepLen
, groupingSeparator
) || 
3212                     !pattern
.compare(pos
, decimalSepLen
, decimalSeparator
) || 
3213                     (ch 
>= zeroDigit 
&& ch 
<= nineDigit
) || 
3215                     if (subpart 
== 1) { // prefix subpart 
3216                         subpart 
= 0; // pattern proper subpart 
3217                         sub0Start 
= pos
; // Reprocess this character 
3220                         status 
= U_UNQUOTED_SPECIAL
; 
3221                         syntaxError(pattern
,pos
,parseError
); 
3224                 } else if (ch 
== kCurrencySign
) { 
3225                     affix
->append(kQuote
); // Encode currency 
3226                     // Use lookahead to determine if the currency sign is 
3228                     U_ASSERT(U16_LENGTH(kCurrencySign
) == 1); 
3229                     if ((pos
+1) < pattern
.length() && pattern
[pos
+1] == kCurrencySign
) { 
3230                         affix
->append(kCurrencySign
); 
3231                         ++pos
; // Skip over the doubled character 
3234                     // Fall through to append(ch) 
3235                 } else if (ch 
== kQuote
) { 
3236                     // A quote outside quotes indicates either the opening 
3237                     // quote or two quotes, which is a quote literal.  That is, 
3238                     // we have the first quote in 'do' or o''clock. 
3239                     U_ASSERT(U16_LENGTH(kQuote
) == 1); 
3241                     if (pos 
< pattern
.length() && pattern
[pos
] == kQuote
) { 
3242                         affix
->append(kQuote
); // Encode quote 
3243                         // Fall through to append(ch) 
3245                         subpart 
+= 2; // open quote 
3248                 } else if (pattern
.compare(pos
, separator
.length(), separator
) == 0) { 
3249                     // Don't allow separators in the prefix, and don't allow 
3250                     // separators in the second pattern (part == 1). 
3251                     if (subpart 
== 1 || part 
== 1) { 
3252                         // Unexpected separator 
3253                         debug("Unexpected separator") 
3254                         status 
= U_UNEXPECTED_TOKEN
; 
3255                         syntaxError(pattern
,pos
,parseError
); 
3259                     isPartDone 
= TRUE
; // Go to next part 
3260                     pos 
+= separator
.length(); 
3262                 } else if (pattern
.compare(pos
, percent
.length(), percent
) == 0) { 
3263                     // Next handle characters which are appended directly. 
3264                     if (multiplier 
!= 1) { 
3265                         // Too many percent/perMill characters 
3266                         debug("Too many percent characters") 
3267                         status 
= U_MULTIPLE_PERCENT_SYMBOLS
; 
3268                         syntaxError(pattern
,pos
,parseError
); 
3271                     affix
->append(kQuote
); // Encode percent/perMill 
3272                     affix
->append(kPatternPercent
); // Use unlocalized pattern char 
3274                     pos 
+= percent
.length(); 
3276                 } else if (pattern
.compare(pos
, perMill
.length(), perMill
) == 0) { 
3277                     // Next handle characters which are appended directly. 
3278                     if (multiplier 
!= 1) { 
3279                         // Too many percent/perMill characters 
3280                         debug("Too many perMill characters") 
3281                         status 
= U_MULTIPLE_PERMILL_SYMBOLS
; 
3282                         syntaxError(pattern
,pos
,parseError
); 
3285                     affix
->append(kQuote
); // Encode percent/perMill 
3286                     affix
->append(kPatternPerMill
); // Use unlocalized pattern char 
3288                     pos 
+= perMill
.length(); 
3290                 } else if (pattern
.compare(pos
, padEscape
.length(), padEscape
) == 0) { 
3291                     if (padPos 
>= 0 ||               // Multiple pad specifiers 
3292                         (pos
+1) == pattern
.length()) { // Nothing after padEscape 
3293                         debug("Multiple pad specifiers") 
3294                         status 
= U_MULTIPLE_PAD_SPECIFIERS
; 
3295                         syntaxError(pattern
,pos
,parseError
); 
3299                     pos 
+= padEscape
.length(); 
3300                     padChar 
= pattern
.char32At(pos
); 
3301                     pos 
+= U16_LENGTH(padChar
); 
3303                 } else if (pattern
.compare(pos
, minus
.length(), minus
) == 0) { 
3304                     affix
->append(kQuote
); // Encode minus 
3305                     affix
->append(kPatternMinus
); 
3306                     pos 
+= minus
.length(); 
3308                 } else if (pattern
.compare(pos
, plus
.length(), plus
) == 0) { 
3309                     affix
->append(kQuote
); // Encode plus 
3310                     affix
->append(kPatternPlus
); 
3311                     pos 
+= plus
.length(); 
3314                 // Unquoted, non-special characters fall through to here, as 
3315                 // well as other code which needs to append something to the 
3318                 pos 
+= U16_LENGTH(ch
); 
3320             case 3: // Prefix subpart, in quote 
3321             case 4: // Suffix subpart, in quote 
3322                 // A quote within quotes indicates either the closing 
3323                 // quote or two quotes, which is a quote literal.  That is, 
3324                 // we have the second quote in 'do' or 'don''t'. 
3327                     if (pos 
< pattern
.length() && pattern
[pos
] == kQuote
) { 
3328                         affix
->append(kQuote
); // Encode quote 
3329                         // Fall through to append(ch) 
3331                         subpart 
-= 2; // close quote 
3336                 pos 
+= U16_LENGTH(ch
); 
3341         if (sub0Limit 
== 0) { 
3342             sub0Limit 
= pattern
.length(); 
3345         if (sub2Limit 
== 0) { 
3346             sub2Limit 
= pattern
.length(); 
3349         /* Handle patterns with no '0' pattern character.  These patterns 
3350          * are legal, but must be recodified to make sense.  "##.###" -> 
3351          * "#0.###".  ".###" -> ".0##". 
3353          * We allow patterns of the form "####" to produce a zeroDigitCount 
3354          * of zero (got that?); although this seems like it might make it 
3355          * possible for format() to produce empty strings, format() checks 
3356          * for this condition and outputs a zero digit in this situation. 
3357          * Having a zeroDigitCount of zero yields a minimum integer digits 
3358          * of zero, which allows proper round-trip patterns.  We don't want 
3359          * "#" to become "#0" when toPattern() is called (even though that's 
3360          * what it really is, semantically). 
3362         if (zeroDigitCount 
== 0 && sigDigitCount 
== 0 && 
3363             digitLeftCount 
> 0 && decimalPos 
>= 0) { 
3364             // Handle "###.###" and "###." and ".###" 
3367                 ++n
; // Handle ".###" 
3368             digitRightCount 
= digitLeftCount 
- n
; 
3369             digitLeftCount 
= n 
- 1; 
3373         // Do syntax checking on the digits, decimal points, and quotes. 
3374         if ((decimalPos 
< 0 && digitRightCount 
> 0 && sigDigitCount 
== 0) || 
3376              (sigDigitCount 
> 0 || 
3377               decimalPos 
< digitLeftCount 
|| 
3378               decimalPos 
> (digitLeftCount 
+ zeroDigitCount
))) || 
3379             groupingCount 
== 0 || groupingCount2 
== 0 || 
3380             (sigDigitCount 
> 0 && zeroDigitCount 
> 0) || 
3382         { // subpart > 2 == unmatched quote 
3383             debug("Syntax error") 
3384             status 
= U_PATTERN_SYNTAX_ERROR
; 
3385             syntaxError(pattern
,pos
,parseError
); 
3389         // Make sure pad is at legal position before or after affix. 
3391             if (padPos 
== start
) { 
3392                 padPos 
= kPadBeforePrefix
; 
3393             } else if (padPos
+2 == sub0Start
) { 
3394                 padPos 
= kPadAfterPrefix
; 
3395             } else if (padPos 
== sub0Limit
) { 
3396                 padPos 
= kPadBeforeSuffix
; 
3397             } else if (padPos
+2 == sub2Limit
) { 
3398                 padPos 
= kPadAfterSuffix
; 
3400                 // Illegal pad position 
3401                 debug("Illegal pad position") 
3402                 status 
= U_ILLEGAL_PAD_POSITION
; 
3403                 syntaxError(pattern
,pos
,parseError
); 
3409             delete fPosPrefixPattern
; 
3410             delete fPosSuffixPattern
; 
3411             delete fNegPrefixPattern
; 
3412             delete fNegSuffixPattern
; 
3413             fPosPrefixPattern 
= new UnicodeString(prefix
); 
3415             if (fPosPrefixPattern 
== 0) { 
3416                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3419             fPosSuffixPattern 
= new UnicodeString(suffix
); 
3421             if (fPosSuffixPattern 
== 0) { 
3422                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3423                 delete fPosPrefixPattern
; 
3426             fNegPrefixPattern 
= 0; 
3427             fNegSuffixPattern 
= 0; 
3429             fUseExponentialNotation 
= (expDigits 
>= 0); 
3430             if (fUseExponentialNotation
) { 
3431                 fMinExponentDigits 
= expDigits
; 
3433             fExponentSignAlwaysShown 
= expSignAlways
; 
3434             fIsCurrencyFormat 
= isCurrency
; 
3435             int32_t digitTotalCount 
= digitLeftCount 
+ zeroDigitCount 
+ digitRightCount
; 
3436             // The effectiveDecimalPos is the position the decimal is at or 
3437             // would be at if there is no decimal.  Note that if 
3438             // decimalPos<0, then digitTotalCount == digitLeftCount + 
3440             int32_t effectiveDecimalPos 
= decimalPos 
>= 0 ? decimalPos 
: digitTotalCount
; 
3441             UBool isSigDig 
= (sigDigitCount 
> 0); 
3442             setSignificantDigitsUsed(isSigDig
); 
3444                 setMinimumSignificantDigits(sigDigitCount
); 
3445                 setMaximumSignificantDigits(sigDigitCount 
+ digitRightCount
); 
3447                 int32_t minInt 
= effectiveDecimalPos 
- digitLeftCount
; 
3448                 setMinimumIntegerDigits(minInt
); 
3449                 setMaximumIntegerDigits(fUseExponentialNotation
 
3450                     ? digitLeftCount 
+ getMinimumIntegerDigits() 
3451                     : kDoubleIntegerDigits
); 
3452                 setMaximumFractionDigits(decimalPos 
>= 0 
3453                     ? (digitTotalCount 
- decimalPos
) : 0); 
3454                 setMinimumFractionDigits(decimalPos 
>= 0 
3455                     ? (digitLeftCount 
+ zeroDigitCount 
- decimalPos
) : 0); 
3457             setGroupingUsed(groupingCount 
> 0); 
3458             fGroupingSize 
= (groupingCount 
> 0) ? groupingCount 
: 0; 
3459             fGroupingSize2 
= (groupingCount2 
> 0 && groupingCount2 
!= groupingCount
) 
3460                 ? groupingCount2 
: 0; 
3461             fMultiplier 
= multiplier
; 
3462             setDecimalSeparatorAlwaysShown(decimalPos 
== 0 
3463                     || decimalPos 
== digitTotalCount
); 
3465                 fPadPosition 
= (EPadPosition
) padPos
; 
3466                 // To compute the format width, first set up sub0Limit - 
3467                 // sub0Start.  Add in prefix/suffix length later. 
3469                 // fFormatWidth = prefix.length() + suffix.length() + 
3470                 //    sub0Limit - sub0Start; 
3471                 fFormatWidth 
= sub0Limit 
- sub0Start
; 
3476             if (roundingPos 
>= 0) { 
3477                 roundingInc
.fDecimalAt 
= effectiveDecimalPos 
- roundingPos
; 
3478                 if (fRoundingIncrement 
!= NULL
) { 
3479                     *fRoundingIncrement 
= roundingInc
; 
3481                     fRoundingIncrement 
= new DigitList(roundingInc
); 
3483                     if (fRoundingIncrement 
== 0) { 
3484                         status 
= U_MEMORY_ALLOCATION_ERROR
; 
3485                         delete fPosPrefixPattern
; 
3486                         delete fPosSuffixPattern
; 
3490                 fRoundingDouble 
= fRoundingIncrement
->getDouble(); 
3491                 fRoundingMode 
= kRoundHalfEven
; 
3493                 setRoundingIncrement(0.0); 
3496             fNegPrefixPattern 
= new UnicodeString(prefix
); 
3498             if (fNegPrefixPattern 
== 0) { 
3499                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3502             fNegSuffixPattern 
= new UnicodeString(suffix
); 
3504             if (fNegSuffixPattern 
== 0) { 
3505                 delete fNegPrefixPattern
; 
3506                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3512     if (pattern
.length() == 0) { 
3513         delete fNegPrefixPattern
; 
3514         delete fNegSuffixPattern
; 
3515         fNegPrefixPattern 
= NULL
; 
3516         fNegSuffixPattern 
= NULL
; 
3517         if (fPosPrefixPattern 
!= NULL
) { 
3518             fPosPrefixPattern
->remove(); 
3520             fPosPrefixPattern 
= new UnicodeString(); 
3522             if (fPosPrefixPattern 
== 0) { 
3523                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3527         if (fPosSuffixPattern 
!= NULL
) { 
3528             fPosSuffixPattern
->remove(); 
3530             fPosSuffixPattern 
= new UnicodeString(); 
3532             if (fPosSuffixPattern 
== 0) { 
3533                 delete fPosPrefixPattern
; 
3534                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3539         setMinimumIntegerDigits(0); 
3540         setMaximumIntegerDigits(kDoubleIntegerDigits
); 
3541         setMinimumFractionDigits(0); 
3542         setMaximumFractionDigits(kDoubleFractionDigits
); 
3544         fUseExponentialNotation 
= FALSE
; 
3545         fIsCurrencyFormat 
= FALSE
; 
3546         setGroupingUsed(FALSE
); 
3550         setDecimalSeparatorAlwaysShown(FALSE
); 
3552         setRoundingIncrement(0.0); 
3555     // If there was no negative pattern, or if the negative pattern is 
3556     // identical to the positive pattern, then prepend the minus sign to the 
3557     // positive pattern to form the negative pattern. 
3558     if (fNegPrefixPattern 
== NULL 
|| 
3559         (*fNegPrefixPattern 
== *fPosPrefixPattern
 
3560          && *fNegSuffixPattern 
== *fPosSuffixPattern
)) { 
3561         _copy_us_ptr(&fNegSuffixPattern
, fPosSuffixPattern
); 
3562         if (fNegPrefixPattern 
== NULL
) { 
3563             fNegPrefixPattern 
= new UnicodeString(); 
3565             if (fNegPrefixPattern 
== 0) { 
3566                 status 
= U_MEMORY_ALLOCATION_ERROR
; 
3570             fNegPrefixPattern
->remove(); 
3572         fNegPrefixPattern
->append(kQuote
).append(kPatternMinus
) 
3573             .append(*fPosPrefixPattern
); 
3577     s
.append("\"").append(pattern
).append("\"->"); 
3581     if (fFormatWidth 
> 0) { 
3582         // Finish computing format width (see above) 
3583         fFormatWidth 
+= fPositivePrefix
.length() + fPositiveSuffix
.length(); 
3588  * Sets the maximum number of digits allowed in the integer portion of a 
3589  * number. This override limits the integer digit count to 309. 
3590  * @see NumberFormat#setMaximumIntegerDigits 
3592 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue
) { 
3593     NumberFormat::setMaximumIntegerDigits(_min(newValue
, kDoubleIntegerDigits
)); 
3597  * Sets the minimum number of digits allowed in the integer portion of a 
3598  * number. This override limits the integer digit count to 309. 
3599  * @see NumberFormat#setMinimumIntegerDigits 
3601 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue
) { 
3602     NumberFormat::setMinimumIntegerDigits(_min(newValue
, kDoubleIntegerDigits
)); 
3606  * Sets the maximum number of digits allowed in the fraction portion of a 
3607  * number. This override limits the fraction digit count to 340. 
3608  * @see NumberFormat#setMaximumFractionDigits 
3610 void DecimalFormat::setMaximumFractionDigits(int32_t newValue
) { 
3611     NumberFormat::setMaximumFractionDigits(_min(newValue
, kDoubleFractionDigits
)); 
3615  * Sets the minimum number of digits allowed in the fraction portion of a 
3616  * number. This override limits the fraction digit count to 340. 
3617  * @see NumberFormat#setMinimumFractionDigits 
3619 void DecimalFormat::setMinimumFractionDigits(int32_t newValue
) { 
3620     NumberFormat::setMinimumFractionDigits(_min(newValue
, kDoubleFractionDigits
)); 
3623 int32_t DecimalFormat::getMinimumSignificantDigits() const { 
3624     return fMinSignificantDigits
; 
3627 int32_t DecimalFormat::getMaximumSignificantDigits() const { 
3628     return fMaxSignificantDigits
; 
3631 void DecimalFormat::setMinimumSignificantDigits(int32_t min
) { 
3635     // pin max sig dig to >= min 
3636     int32_t max 
= _max(fMaxSignificantDigits
, min
); 
3637     fMinSignificantDigits 
= min
; 
3638     fMaxSignificantDigits 
= max
; 
3641 void DecimalFormat::setMaximumSignificantDigits(int32_t max
) { 
3645     // pin min sig dig to 1..max 
3646     U_ASSERT(fMinSignificantDigits 
>= 1); 
3647     int32_t min 
= _min(fMinSignificantDigits
, max
); 
3648     fMinSignificantDigits 
= min
; 
3649     fMaxSignificantDigits 
= max
; 
3652 UBool 
DecimalFormat::areSignificantDigitsUsed() const { 
3653     return fUseSignificantDigits
; 
3656 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits
) { 
3657     fUseSignificantDigits 
= useSignificantDigits
; 
3660 void DecimalFormat::setCurrency(const UChar
* theCurrency
, UErrorCode
& ec
) { 
3661     // If we are a currency format, then modify our affixes to 
3662     // encode the currency symbol for the given currency in our 
3663     // locale, and adjust the decimal digits and rounding for the 
3666     // Note: The code is ordered so that this object is *not changed* 
3667     // until we are sure we are going to succeed. 
3669     // NULL or empty currency is *legal* and indicates no currency. 
3670     UBool isCurr 
= (theCurrency 
&& *theCurrency
); 
3672     double rounding 
= 0.0; 
3674     if (fIsCurrencyFormat 
&& isCurr
) { 
3675         rounding 
= ucurr_getRoundingIncrement(theCurrency
, &ec
); 
3676         frac 
= ucurr_getDefaultFractionDigits(theCurrency
, &ec
); 
3679     NumberFormat::setCurrency(theCurrency
, ec
); 
3680     if (U_FAILURE(ec
)) return; 
3682     if (fIsCurrencyFormat
) { 
3683         // NULL or empty currency is *legal* and indicates no currency. 
3685             setRoundingIncrement(rounding
); 
3686             setMinimumFractionDigits(frac
); 
3687             setMaximumFractionDigits(frac
); 
3693 // Deprecated variant with no UErrorCode parameter 
3694 void DecimalFormat::setCurrency(const UChar
* theCurrency
) { 
3695     UErrorCode ec 
= U_ZERO_ERROR
; 
3696     setCurrency(theCurrency
, ec
); 
3699 void DecimalFormat::getEffectiveCurrency(UChar
* result
, UErrorCode
& /*ec*/) const { 
3700     const UChar
* c 
= getCurrency(); 
3702         const UnicodeString 
&intl 
= 
3703             fSymbols
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
); 
3704         c 
= intl
.getBuffer(); // ok for intl to go out of scope 
3706     u_strncpy(result
, c
, 3); 
3711  * Return the number of fraction digits to display, or the total 
3712  * number of digits for significant digit formats and exponential 
3716 DecimalFormat::precision(UBool isIntegral
) const { 
3717     if (areSignificantDigitsUsed()) { 
3718         return getMaximumSignificantDigits(); 
3719     } else if (fUseExponentialNotation
) { 
3720         return getMinimumIntegerDigits() + getMaximumFractionDigits(); 
3722         return isIntegral 
? 0 : getMaximumFractionDigits(); 
3728 #endif /* #if !UCONFIG_NO_FORMATTING */