home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / i18n / decimfmt.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  98.5 KB  |  2,617 lines

  1. /*
  2. ********************************************************************************
  3. *                                                                              *
  4. * COPYRIGHT:                                                                   *
  5. *   (C) Copyright Taligent, Inc.,  1997                                        *
  6. *   (C) Copyright International Business Machines Corporation,  1997-1998      *
  7. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  8. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  9. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  10. *                                                                              *
  11. ********************************************************************************
  12. *
  13. * File DECIMFMT.CPP
  14. *
  15. * Modification History:
  16. *
  17. *   Date        Name        Description
  18. *   02/19/97    aliu        Converted from java.
  19. *   03/20/97    clhuang     Implemented with new APIs.
  20. *   03/31/97    aliu        Moved isLONG_MIN to DigitList, and fixed it.
  21. *   04/3/97     aliu        Rewrote parsing and formatting completely, and
  22. *                           cleaned up and debugged.  Actually works now.
  23. *                           Implemented NAN and INF handling, for both parsing
  24. *                           and formatting.  Extensive testing & debugging.
  25. *   04/10/97    aliu        Modified to compile on AIX.
  26. *   04/16/97    aliu        Rewrote to use DigitList, which has been resurrected.
  27. *                           Changed DigitCount to int per code review.
  28. *   07/09/97    helena      Made ParsePosition into a class.
  29. *   08/26/97    aliu        Extensive changes to applyPattern; completely
  30. *                           rewritten from the Java.
  31. *   09/09/97    aliu        Ported over support for exponential formats.
  32. *   07/20/98    stephen     JDK 1.2 sync up.
  33. *                             Various instances of '0' replaced with 'NULL'
  34. *                             Check for grouping size in subFormat()
  35. *                             Brought subParse() in line with Java 1.2
  36. *                             Added method appendAffix()
  37. *   08/24/1998  srl         Removed Mutex calls. This is not a thread safe class!
  38. *   02/22/99    stephen     Removed character literals for EBCDIC safety
  39. *   06/24/99    helena      Integrated Alan's NF enhancements and Java2 bug fixes
  40. *   06/28/99    stephen     Fixed bugs in toPattern().
  41. *   06/29/99    stephen     Fixed operator= to copy fFormatWidth, fPad, 
  42. *                             fPadPosition
  43. ********************************************************************************
  44. */
  45.  
  46. #include "decimfmt.h"
  47. #include "digitlst.h"
  48. #include "dcfmtsym.h"
  49. #include "resbund.h"
  50. #include "unicode.h"
  51. #include "cmemory.h"
  52. #include <float.h>
  53. #include <limits.h>
  54.  
  55. // #define DEBUG
  56.  
  57. #ifdef DEBUG
  58. #include <stdio.h>
  59. static void debugout(UnicodeString s) {
  60.     char buf[2000];
  61.     s.extract((UTextOffset) 0, s.length(), buf);
  62.     buf[s.length()] = 0;
  63.     printf("%s", buf);
  64. }
  65. #define debug(x) printf("%s", x);
  66. #else
  67. #define debugout(x)
  68. #define debug(x)
  69. #endif
  70.  
  71. // *****************************************************************************
  72. // class DecimalFormat
  73. // *****************************************************************************
  74.  
  75. char DecimalFormat::fgClassID = 0; // Value is irrelevan
  76.  
  77. // Constants for characters used in programmatic (unlocalized) patterns.
  78. const UChar DecimalFormat::kPatternZeroDigit           = 0x0030 /*'0'*/;
  79. const UChar DecimalFormat::kPatternGroupingSeparator   = 0x002C /*','*/;
  80. const UChar DecimalFormat::kPatternDecimalSeparator    = 0x002E /*'.'*/;
  81. const UChar DecimalFormat::kPatternPerMill             = 0x2030;
  82. const UChar DecimalFormat::kPatternPercent             = 0x0025 /*'%'*/;
  83. const UChar DecimalFormat::kPatternDigit               = 0x0023 /*'#'*/;
  84. const UChar DecimalFormat::kPatternSeparator           = 0x003B /*';'*/;
  85. const UChar DecimalFormat::kPatternExponent            = 0x0045 /*'E'*/;
  86. const UChar DecimalFormat::kPatternPlus                = 0x002B /*'+'*/;
  87. const UChar DecimalFormat::kPatternMinus               = 0x002D /*'-'*/;
  88. const UChar DecimalFormat::kPatternPadEscape           = 0x002A /*'*'*/;
  89. const UChar DecimalFormat::kCurrencySign               = 0x00A4;
  90. const UChar DecimalFormat::kQuote                      = 0x0027 /*'\''*/;
  91.  
  92. const int8_t DecimalFormat::fgMaxDigit                  = 9;
  93.  
  94. const int32_t DecimalFormat::kDoubleIntegerDigits  = 309;
  95. const int32_t DecimalFormat::kDoubleFractionDigits = 340;
  96.  
  97. /**
  98.  * These are the tags we expect to see in normal resource bundle files associated
  99.  * with a locale.
  100.  */
  101. const UnicodeString DecimalFormat::fgNumberPatterns("NumberPatterns");
  102.  
  103. //------------------------------------------------------------------------------
  104. // Constructs a DecimalFormat instance in the default locale.
  105.  
  106. DecimalFormat::DecimalFormat(UErrorCode& status)
  107. : NumberFormat(), 
  108.   fPosPrefixPattern(0), 
  109.   fNegPrefixPattern(0), 
  110.   fPosSuffixPattern(0), 
  111.   fNegSuffixPattern(0),
  112.   fSymbols(0)
  113. {
  114.     construct(status);
  115. }
  116.  
  117. //------------------------------------------------------------------------------
  118. // Constructs a DecimalFormat instance with the specified number format
  119. // pattern in the default locale.
  120.  
  121. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  122.                              UErrorCode& status)
  123. : NumberFormat(),
  124.   fPosPrefixPattern(0), 
  125.   fNegPrefixPattern(0), 
  126.   fPosSuffixPattern(0), 
  127.   fNegSuffixPattern(0),
  128.   fSymbols(0)
  129. {
  130.     construct(status, &pattern);
  131. }
  132.  
  133. //------------------------------------------------------------------------------
  134. // Constructs a DecimalFormat instance with the specified number format
  135. // pattern and the number format symbols in the default locale.  The
  136. // created instance owns the symbols.
  137.  
  138. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  139.                              DecimalFormatSymbols* symbolsToAdopt,
  140.                              UErrorCode& status)
  141. : NumberFormat(),
  142.   fPosPrefixPattern(0), 
  143.   fNegPrefixPattern(0), 
  144.   fPosSuffixPattern(0), 
  145.   fNegSuffixPattern(0),
  146.   fSymbols(0)
  147. {
  148.     if (symbolsToAdopt == NULL) status = U_ILLEGAL_ARGUMENT_ERROR;
  149.     construct(status, &pattern, symbolsToAdopt);
  150. }
  151.  
  152. //------------------------------------------------------------------------------
  153. // Constructs a DecimalFormat instance with the specified number format
  154. // pattern and the number format symbols in the default locale.  The
  155. // created instance owns the clone of the symbols.
  156.  
  157. DecimalFormat::DecimalFormat(const UnicodeString& pattern,
  158.                              const DecimalFormatSymbols& symbols,
  159.                              UErrorCode& status)
  160. : NumberFormat(),
  161.   fPosPrefixPattern(0), 
  162.   fNegPrefixPattern(0), 
  163.   fPosSuffixPattern(0), 
  164.   fNegSuffixPattern(0),
  165.   fSymbols(0)
  166. {
  167.     construct(status, &pattern, new DecimalFormatSymbols(symbols));
  168. }
  169.  
  170. //------------------------------------------------------------------------------
  171. // Constructs a DecimalFormat instance with the specified number format
  172. // pattern and the number format symbols in the desired locale.  The
  173. // created instance owns the symbols.
  174.  
  175. void
  176. DecimalFormat::construct(UErrorCode&             status,
  177.                          const UnicodeString*   pattern,
  178.                          DecimalFormatSymbols*  symbolsToAdopt,
  179.                          const Locale&          locale)
  180. {
  181.     fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!!
  182.     fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!!
  183.     fRoundingIncrement = NULL;
  184.     fRoundingDouble = 0.0;
  185.     fRoundingMode = kRoundHalfEven;
  186.     fPad = kPatternPadEscape;
  187.     fPadPosition = kPadBeforePrefix;
  188.     if (U_FAILURE(status)) return;
  189.  
  190.     fPosPrefixPattern = fPosSuffixPattern = NULL;
  191.     fNegPrefixPattern = fNegSuffixPattern = NULL;
  192.     fMultiplier = 1;
  193.     fGroupingSize = 3;
  194.     fDecimalSeparatorAlwaysShown = FALSE;
  195.     fIsCurrencyFormat = FALSE;
  196.     fUseExponentialNotation = FALSE;
  197.     fMinExponentDigits = 0;
  198.  
  199.     if (fSymbols == NULL) fSymbols = new DecimalFormatSymbols(locale, status);
  200.  
  201.     UnicodeString str;
  202.     // Uses the default locale's number format pattern if there isn't
  203.     // one specified.
  204.     if (pattern == NULL)
  205.     {
  206.         ResourceBundle resource(Locale::getDataDirectory(), Locale::getDefault(), status);
  207.         resource.getArrayItem(fgNumberPatterns, 0, str, status);
  208.         pattern = &str;
  209.     }
  210.  
  211.     if (U_FAILURE(status)) return;
  212.  
  213.     applyPattern(*pattern, FALSE /*not localized*/, status);
  214. }
  215.  
  216. //------------------------------------------------------------------------------
  217.  
  218. DecimalFormat::~DecimalFormat()
  219. {
  220.     delete fSymbols;
  221.     delete fDigitList;
  222.     delete fPosPrefixPattern;
  223.     delete fPosSuffixPattern;
  224.     delete fNegPrefixPattern;
  225.     delete fNegSuffixPattern;
  226.     delete fRoundingIncrement;
  227. }
  228.  
  229. //------------------------------------------------------------------------------
  230. // copy constructor
  231.  
  232. DecimalFormat::DecimalFormat(const DecimalFormat &source)
  233. :   NumberFormat(source),
  234.     fSymbols(NULL),
  235.     fDigitList(NULL),
  236.     fPosPrefixPattern(NULL),
  237.     fPosSuffixPattern(NULL),
  238.     fNegPrefixPattern(NULL),
  239.     fNegSuffixPattern(NULL),
  240.     fRoundingIncrement(NULL)
  241. {
  242.     *this = source;
  243. }
  244.  
  245. //------------------------------------------------------------------------------
  246. // assignment operator
  247. // Note that fDigitList is not considered a significant part of the
  248. // DecimalFormat because it's used as a buffer to process the numbers.
  249.  
  250. static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) {
  251.     if (source == NULL) {
  252.         delete *pdest;
  253.         *pdest = NULL;
  254.     } else if (*pdest == NULL) {
  255.         *pdest = new UnicodeString(*source);
  256.     } else {
  257.         **pdest  = *source;
  258.     }
  259. }
  260.  
  261. DecimalFormat&
  262. DecimalFormat::operator=(const DecimalFormat& rhs)
  263. {
  264.   if(this != &rhs) {
  265.     NumberFormat::operator=(rhs);
  266.     fPositivePrefix = rhs.fPositivePrefix;
  267.     fPositiveSuffix = rhs.fPositiveSuffix;
  268.     fNegativePrefix = rhs.fNegativePrefix;
  269.     fNegativeSuffix = rhs.fNegativeSuffix;
  270.     _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
  271.     _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
  272.     _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
  273.     _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
  274.     if(rhs.fRoundingIncrement == NULL) {
  275.       delete fRoundingIncrement;
  276.       fRoundingIncrement = NULL;
  277.     } 
  278.     else if(fRoundingIncrement == NULL) {
  279.       fRoundingIncrement = new DigitList(*rhs.fRoundingIncrement);
  280.     } 
  281.     else {
  282.       *fRoundingIncrement = *rhs.fRoundingIncrement;
  283.     }
  284.     fRoundingDouble = rhs.fRoundingDouble;
  285.     fMultiplier = rhs.fMultiplier;
  286.     fGroupingSize = rhs.fGroupingSize;
  287.     fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
  288.     if(fSymbols == NULL) 
  289.     fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
  290.     else 
  291.     *fSymbols = *rhs.fSymbols;
  292.     fUseExponentialNotation = rhs.fUseExponentialNotation;
  293.     /*Bertrand A. D. Update 98.03.17*/
  294.     fIsCurrencyFormat = rhs.fIsCurrencyFormat;
  295.     /*end of Update*/
  296.     fMinExponentDigits = rhs.fMinExponentDigits;
  297.     if (fDigitList == NULL) fDigitList = new DigitList();
  298.     
  299.     /* sfb 990629 */
  300.     fFormatWidth = rhs.fFormatWidth;
  301.     fPad = rhs.fPad;
  302.     fPadPosition = rhs.fPadPosition;
  303.     /* end sfb */
  304.   }
  305.   return *this;
  306. }
  307.  
  308. //------------------------------------------------------------------------------
  309.  
  310. bool_t
  311. DecimalFormat::operator==(const Format& that) const
  312. {
  313.     if (this == &that) return TRUE;
  314.  
  315.     if (getDynamicClassID() != that.getDynamicClassID()) return FALSE;
  316.  
  317.     const DecimalFormat* other = (DecimalFormat*)&that;
  318.  
  319. #if 0
  320.     // This code makes it easy to determine why two format objects that should
  321.     // be equal aren't.
  322.     bool_t first = TRUE;
  323.     if (!NumberFormat::operator==(that)) {
  324.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  325.         debug("NumberFormat::!=");
  326.     }
  327.     if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null
  328.               fPositivePrefix == other->fPositivePrefix)
  329.            || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
  330.                *fPosPrefixPattern  == *other->fPosPrefixPattern))) {
  331.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  332.         debug("Pos Prefix !=");
  333.     }
  334.     if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null
  335.            fPositiveSuffix == other->fPositiveSuffix)
  336.           || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
  337.               *fPosSuffixPattern  == *other->fPosSuffixPattern))) {
  338.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  339.         debug("Pos Suffix !=");
  340.     }
  341.     if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null
  342.            fNegativePrefix == other->fNegativePrefix)
  343.           || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
  344.               *fNegPrefixPattern  == *other->fNegPrefixPattern))) {
  345.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  346.         debug("Neg Prefix ");
  347.         if (fNegPrefixPattern == NULL) {
  348.             debug("NULL(");
  349.             debugout(fNegativePrefix);
  350.             debug(")");
  351.         } else {
  352.             debugout(*fNegPrefixPattern);
  353.         }
  354.         debug(" != ");
  355.         if (other->fNegPrefixPattern == NULL) {
  356.             debug("NULL(");
  357.             debugout(other->fNegativePrefix);
  358.             debug(")");
  359.         } else {
  360.             debugout(*other->fNegPrefixPattern);
  361.         }
  362.     }
  363.     if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null
  364.            fNegativeSuffix == other->fNegativeSuffix)
  365.           || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
  366.               *fNegSuffixPattern  == *other->fNegSuffixPattern))) {
  367.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  368.         debug("Neg Suffix ");
  369.         if (fNegSuffixPattern == NULL) {
  370.             debug("NULL(");
  371.             debugout(fNegativeSuffix);
  372.             debug(")");
  373.         } else {
  374.             debugout(*fNegSuffixPattern);
  375.         }
  376.         debug(" != ");
  377.         if (other->fNegSuffixPattern == NULL) {
  378.             debug("NULL(");
  379.             debugout(other->fNegativeSuffix);
  380.             debug(")");
  381.         } else {
  382.             debugout(*other->fNegSuffixPattern);
  383.         }
  384.     }
  385.     if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
  386.           || (fRoundingIncrement != NULL &&
  387.               other->fRoundingIncrement != NULL &&
  388.               *fRoundingIncrement == *other->fRoundingIncrement))) {
  389.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  390.         debug("Rounding Increment !=");
  391.               }
  392.     if (fMultiplier != other->fMultiplier) {
  393.         if (first) { printf("[ "); first = FALSE; }
  394.         printf("Multiplier %ld != %ld", fMultiplier, other->fMultiplier);
  395.     }
  396.     if (fGroupingSize != other->fGroupingSize) {
  397.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  398.         printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
  399.     }
  400.     if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
  401.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  402.         printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown);
  403.     }
  404.     if (fUseExponentialNotation != other->fUseExponentialNotation) {
  405.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  406.         debug("Use Exp !=");
  407.     }
  408.     if (!(!fUseExponentialNotation ||
  409.           fMinExponentDigits != other->fMinExponentDigits)) {
  410.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  411.         debug("Exp Digits !=");
  412.     }
  413.     if (*fSymbols != *(other->fSymbols)) {
  414.         if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
  415.         debug("Symbols !=");
  416.     }
  417.     if (!first) { printf(" ]"); }
  418. #endif
  419.  
  420.     return (NumberFormat::operator==(that) &&
  421.             ((fPosPrefixPattern == other->fPosPrefixPattern && // both null
  422.               fPositivePrefix == other->fPositivePrefix)
  423.              || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
  424.                  *fPosPrefixPattern  == *other->fPosPrefixPattern)) &&
  425.             ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
  426.               fPositiveSuffix == other->fPositiveSuffix)
  427.              || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
  428.                  *fPosSuffixPattern  == *other->fPosSuffixPattern)) &&
  429.             ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
  430.               fNegativePrefix == other->fNegativePrefix)
  431.              || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
  432.                  *fNegPrefixPattern  == *other->fNegPrefixPattern)) &&
  433.             ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
  434.               fNegativeSuffix == other->fNegativeSuffix)
  435.              || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
  436.                  *fNegSuffixPattern  == *other->fNegSuffixPattern)) &&
  437.             ((fRoundingIncrement == other->fRoundingIncrement) // both null
  438.              || (fRoundingIncrement != NULL &&
  439.                  other->fRoundingIncrement != NULL &&
  440.                  *fRoundingIncrement == *other->fRoundingIncrement)) &&
  441.         fMultiplier == other->fMultiplier &&
  442.         fGroupingSize == other->fGroupingSize &&
  443.         fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
  444.         fUseExponentialNotation == other->fUseExponentialNotation &&
  445.         (!fUseExponentialNotation ||
  446.          fMinExponentDigits == other->fMinExponentDigits) &&
  447.         *fSymbols == *(other->fSymbols));
  448. }
  449.  
  450. //------------------------------------------------------------------------------
  451.  
  452. Format*
  453. DecimalFormat::clone() const
  454. {
  455.     return new DecimalFormat(*this);
  456. }
  457.  
  458. //------------------------------------------------------------------------------
  459.  
  460. UnicodeString&
  461. DecimalFormat::format(int32_t number,
  462.                       UnicodeString& result,
  463.                       FieldPosition& fieldPosition) const
  464. {
  465.     // Clears field positions.
  466.     fieldPosition.setBeginIndex(0);
  467.     fieldPosition.setEndIndex(0);
  468.  
  469.     // If we are to do rounding, we need to move into the BigDecimal
  470.     // domain in order to do divide/multiply correctly.
  471.     if (fRoundingIncrement != NULL) {
  472.         return format((double) number, result, fieldPosition);
  473.     }
  474.  
  475.     bool_t isNegative = (number < 0);
  476.     if (isNegative) number = -number; // NOTE: number will still be negative if it is LONG_MIN
  477.  
  478.     // In general, long values always represent real finite numbers, so
  479.     // we don't have to check for +/- Infinity or NaN.  However, there
  480.     // is one case we have to be careful of:  The multiplier can push
  481.     // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
  482.     // check for this before multiplying, and if it happens we use doubles
  483.     // instead, trading off accuracy for range.
  484.     if (fMultiplier != 1 && fMultiplier != 0)
  485.     {
  486.         bool_t useDouble = FALSE;
  487.  
  488.         if (number < 0) // This can only happen if number == Long.MIN_VALUE
  489.         {
  490.             int32_t cutoff = LONG_MIN / fMultiplier;
  491.             useDouble = (number < cutoff);
  492.         }
  493.         else
  494.         {
  495.             int32_t cutoff = T_INT32_MAX / fMultiplier;
  496.             useDouble = (number > cutoff);
  497.         }
  498.         // use double to format the number instead so we don't get out
  499.         // of range errors.
  500.         if (useDouble)
  501.         {
  502.             double dnumber = (double)(isNegative ? -number : number);
  503.             return format(dnumber, result, fieldPosition);
  504.         }
  505.     }
  506.  
  507.     number *= fMultiplier;
  508.     DecimalFormat *non_const = (DecimalFormat*)this;
  509.     non_const->fDigitList->set(number, fUseExponentialNotation ?
  510.                                getMinimumIntegerDigits() + getMaximumFractionDigits() : 0);
  511.  
  512.     return subformat(result, fieldPosition, isNegative, TRUE);
  513. }
  514.  
  515. //------------------------------------------------------------------------------
  516.  
  517. UnicodeString&
  518. DecimalFormat::format(  double number,
  519.                         UnicodeString& result,
  520.                         FieldPosition& fieldPosition) const
  521. {
  522.     // Clears field positions.
  523.     fieldPosition.setBeginIndex(0);
  524.     fieldPosition.setEndIndex(0);
  525.  
  526.     // Special case for NaN, sets the begin and end index to be the
  527.     // the string length of localized name of NaN.
  528.     if (icu_isNaN(number))
  529.     {
  530.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  531.             fieldPosition.setBeginIndex(result.size());
  532.  
  533.         UnicodeString nan;
  534.         result += fSymbols->getNaN(nan);
  535.  
  536.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  537.             fieldPosition.setEndIndex(result.size());
  538.  
  539.         addPadding(result, FALSE, FALSE /*ignored*/);
  540.         return result;
  541.     }
  542.  
  543.     /* Detecting whether a double is negative is easy with the exception of
  544.      * the value -0.0.  This is a double which has a zero mantissa (and
  545.      * exponent), but a negative sign bit.  It is semantically distinct from
  546.      * a zero with a positive sign bit, and this distinction is important
  547.      * to certain kinds of computations.  However, it's a little tricky to
  548.      * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
  549.      * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
  550.      * -Infinity.  Proper detection of -0.0 is needed to deal with the
  551.      * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
  552.      */
  553.     bool_t isNegative = (number < 0.0) || (number == 0.0 && 1/number < 0.0);
  554.     if (isNegative) number = -number;
  555.  
  556.     // Do this BEFORE checking to see if value is infinite! Sets the
  557.     // begin and end index to be length of the string composed of
  558.     // localized name of Infinite and the positive/negative localized
  559.     // signs.
  560.  
  561.     if (fMultiplier != 1) number *= fMultiplier;
  562.  
  563.     // Apply rounding after multiplier
  564.     if (fRoundingIncrement != NULL) {
  565.         number = fRoundingDouble
  566.             * round(number / fRoundingDouble, fRoundingMode, isNegative);
  567.     }
  568.  
  569.     // Special case for INFINITE,
  570.     if (icu_isInfinite(number))
  571.     {
  572.         result += (isNegative ? fNegativePrefix : fPositivePrefix);
  573.  
  574.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  575.             fieldPosition.setBeginIndex(result.size());
  576.  
  577.         UnicodeString inf;
  578.         result += fSymbols->getInfinity(inf);
  579.  
  580.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  581.             fieldPosition.setEndIndex(result.size());
  582.  
  583.         result += (isNegative ? fNegativeSuffix : fPositiveSuffix);
  584.  
  585.         addPadding(result, TRUE, isNegative);
  586.         return result;
  587.     }
  588.  
  589.     // At this point we are guaranteed a nonnegative finite
  590.     // number.
  591.     DecimalFormat* non_const = (DecimalFormat*)this;
  592.     // Sets up the digit list buffer with the number.
  593.     // Please see digitlst.cpp for the details regarding DigitList.
  594.     non_const->fDigitList->set(number, fUseExponentialNotation ?
  595.                              getMinimumIntegerDigits() + getMaximumFractionDigits() :
  596.                              getMaximumFractionDigits(),
  597.                              !fUseExponentialNotation);
  598.  
  599.     return subformat(result, fieldPosition, isNegative, FALSE);
  600. }
  601.  
  602. /**
  603.  * Round a double value to the nearest integer according to the
  604.  * given mode.
  605.  * @param a the absolute value of the number to be rounded
  606.  * @param mode a BigDecimal rounding mode
  607.  * @param isNegative true if the number to be rounded is negative
  608.  * @return the absolute value of the rounded result
  609.  */
  610. double DecimalFormat::round(double a, ERoundingMode mode, bool_t isNegative) {
  611.     switch (mode) {
  612.     case kRoundCeiling:
  613.         return isNegative ? icu_floor(a) : icu_ceil(a);
  614.     case kRoundFloor:
  615.         return isNegative ? icu_ceil(a) : icu_floor(a);
  616.     case kRoundDown:
  617.         return icu_floor(a);
  618.     case kRoundUp:
  619.         return icu_ceil(a);
  620.     case kRoundHalfEven:
  621.         {
  622.             double f = icu_floor(a);
  623.             if ((a - f) != 0.5) {
  624.                 return icu_floor(a + 0.5);
  625.             }
  626.             double g = f / 2.0;
  627.             return (g == icu_floor(g)) ? f : (f + 1.0);
  628.         }
  629.     case kRoundHalfDown:
  630.         return ((a - icu_floor(a)) <= 0.5) ? icu_floor(a) : icu_ceil(a);
  631.     case kRoundHalfUp:
  632.         return ((a - icu_floor(a)) < 0.5) ? icu_floor(a) : icu_ceil(a);
  633.     }
  634.     return 1.0;
  635. }
  636.  
  637. UnicodeString&
  638. DecimalFormat::format(  const Formattable& obj,
  639.                         UnicodeString& result,
  640.                         FieldPosition& fieldPosition,
  641.                         UErrorCode& status) const
  642. {
  643.     return NumberFormat::format(obj, result, fieldPosition, status);
  644. }
  645.  
  646. //------------------------------------------------------------------------------
  647.  
  648. /**
  649.  * Complete the formatting of a finite number.  On entry, the fDigitList must
  650.  * be filled in with the correct digits.
  651.  */
  652. UnicodeString&
  653. DecimalFormat::subformat(UnicodeString& result,
  654.                          FieldPosition& fieldPosition,
  655.                          bool_t         isNegative,
  656.                          bool_t         isInteger) const
  657. {
  658.     // Gets the localized zero Unicode character.
  659.     UChar zero = fSymbols->getZeroDigit();
  660.     int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
  661.     UChar grouping = fSymbols->getGroupingSeparator();
  662.     UChar decimal = fIsCurrencyFormat ?
  663.         fSymbols->getMonetaryDecimalSeparator() :
  664.         fSymbols->getDecimalSeparator();
  665.     int32_t maxIntDig = getMaximumIntegerDigits();
  666.     int32_t minIntDig = getMinimumIntegerDigits();
  667.  
  668.     /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
  669.      * format as zero.  This allows sensible computations and preserves
  670.      * relations such as signum(1/x) = signum(x), where x is +Infinity or
  671.      * -Infinity.  Prior to this fix, we always formatted zero values as if
  672.      * they were positive.  Liu 7/6/98.
  673.      */
  674.     if (fDigitList->isZero())
  675.     {
  676.         fDigitList->fDecimalAt = fDigitList->fCount = 0; // Normalize
  677.     }
  678.  
  679.     // Appends the prefix.
  680.     result += (isNegative ? fNegativePrefix : fPositivePrefix);
  681.  
  682.     if (fUseExponentialNotation)
  683.     {
  684.         // Record field information for caller.
  685.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  686.         {
  687.             fieldPosition.setBeginIndex(result.size());
  688.             fieldPosition.setEndIndex(-1);
  689.         }
  690.         else if (fieldPosition.getField() == NumberFormat::kFractionField)
  691.         {
  692.             fieldPosition.setBeginIndex(-1);
  693.         }
  694.  
  695.         // Minimum integer digits are handled in exponential format by
  696.         // adjusting the exponent.  For example, 0.01234 with 3 minimum
  697.         // integer digits is "123.4E-4".
  698.  
  699.         // Maximum integer digits are interpreted as indicating the
  700.         // repeating range.  This is useful for engineering notation, in
  701.         // which the exponent is restricted to a multiple of 3.  For
  702.         // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
  703.         // If maximum integer digits are defined and are larger than
  704.         // minimum integer digits, then minimum integer digits are
  705.         // ignored.
  706.         int32_t exponent = fDigitList->fDecimalAt;
  707.         if (maxIntDig > 1 && maxIntDig != minIntDig) {
  708.             // A exponent increment is defined; adjust to it.
  709.             exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
  710.                                       : (exponent / maxIntDig) - 1;
  711.             exponent *= maxIntDig;
  712.         } else {
  713.             // No exponent increment is defined; use minimum integer digits.
  714.             // If none is specified, as in "#E0", generate 1 integer digit.
  715.             exponent -= (minIntDig > 0 || getMinimumFractionDigits() > 0)
  716.                         ? minIntDig : 1;
  717.         }
  718.  
  719.         // We now output a minimum number of digits, and more if there
  720.         // are more digits, up to the maximum number of digits.  We
  721.         // place the decimal point after the "integer" digits, which
  722.         // are the first (decimalAt - exponent) digits.
  723.         int32_t minimumDigits =  minIntDig + getMinimumFractionDigits();
  724.         // The number of integer digits is handled specially if the number
  725.         // is zero, since then there may be no digits.
  726.         int32_t integerDigits = fDigitList->isZero() ? minIntDig :
  727.             fDigitList->fDecimalAt - exponent;
  728.         int32_t totalDigits = fDigitList->fCount;
  729.         if (minimumDigits > totalDigits) totalDigits = minimumDigits;
  730.         if (integerDigits > totalDigits) totalDigits = integerDigits;
  731.  
  732.         // totalDigits records total number of digits needs to be processed
  733.         int32_t i;
  734.         for (i=0; i<totalDigits; ++i)
  735.         {
  736.             if (i == integerDigits)
  737.             {
  738.                 // Record field information for caller.
  739.                 if (fieldPosition.getField() == NumberFormat::kIntegerField)
  740.                     fieldPosition.setEndIndex(result.size());
  741.  
  742.                 result += (decimal);
  743.  
  744.                 // Record field information for caller.
  745.                 if (fieldPosition.getField() == NumberFormat::kFractionField)
  746.                     fieldPosition.setBeginIndex(result.size());
  747.             }
  748.             // Restores the digit character or pads the buffer with zeros.
  749.             UChar c = ((i < fDigitList->fCount) ?
  750.                           (UChar)(fDigitList->fDigits[i] + zeroDelta) :
  751.                           zero);
  752.             result += c;
  753.         }
  754.  
  755.         // Record field information
  756.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  757.         {
  758.             if (fieldPosition.getEndIndex() < 0)
  759.                 fieldPosition.setEndIndex(result.size());
  760.         }
  761.         else if (fieldPosition.getField() == NumberFormat::kFractionField)
  762.         {
  763.             if (fieldPosition.getBeginIndex() < 0)
  764.                 fieldPosition.setBeginIndex(result.size());
  765.             fieldPosition.setEndIndex(result.size());
  766.         }
  767.  
  768.         // The exponent is output using the pattern-specified minimum
  769.         // exponent digits.  There is no maximum limit to the exponent
  770.         // digits, since truncating the exponent would result in an
  771.         // unacceptable inaccuracy.
  772.         result += fSymbols->getExponentialSymbol();
  773.         
  774.         // For zero values, we force the exponent to zero.  We
  775.         // must do this here, and not earlier, because the value
  776.         // is used to determine integer digit count above.
  777.         if (fDigitList->isZero()) exponent = 0;
  778.  
  779.         bool_t negativeExponent = exponent < 0;
  780.         if (negativeExponent) {
  781.             exponent = -exponent;
  782.             result += fSymbols->getMinusSign();
  783.         } else if (fExponentSignAlwaysShown) {
  784.             result += fSymbols->getPlusSign();
  785.         }
  786.         if (negativeExponent) exponent = -exponent;
  787.         DecimalFormat* non_const = (DecimalFormat*)this;
  788.         non_const->fDigitList->set(exponent);
  789.         for (i=fDigitList->fDecimalAt; i<fMinExponentDigits; ++i)
  790.             result += (zero);
  791.         for (i=0; i<fDigitList->fDecimalAt; ++i)
  792.         {
  793.             UChar c = ((i < fDigitList->fCount) ?
  794.                           (UChar)(fDigitList->fDigits[i] + zeroDelta) : zero);
  795.             result += c;
  796.         }
  797.     }
  798.     else  // Not using exponential notation
  799.     {
  800.         // Record field information for caller.
  801.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  802.             fieldPosition.setBeginIndex(result.size());
  803.  
  804.         // Output the integer portion.  Here 'count' is the total
  805.         // number of integer digits we will display, including both
  806.         // leading zeros required to satisfy getMinimumIntegerDigits,
  807.         // and actual digits present in the number.
  808.         int32_t count = minIntDig;
  809.         int32_t digitIndex = 0; // Index into fDigitList->fDigits[]
  810.         if (fDigitList->fDecimalAt > 0 && count < fDigitList->fDecimalAt)
  811.             count = fDigitList->fDecimalAt;
  812.  
  813.         // Handle the case where getMaximumIntegerDigits() is smaller
  814.         // than the real number of integer digits.  If this is so, we
  815.         // output the least significant max integer digits.  For example,
  816.         // the value 1997 printed with 2 max integer digits is just "97".
  817.  
  818.         if (count > maxIntDig)
  819.         {
  820.             count = maxIntDig;
  821.             digitIndex = fDigitList->fDecimalAt - count;
  822.         }
  823.  
  824.         int32_t sizeBeforeIntegerPart = result.size();
  825.  
  826.         int32_t i;
  827.         for (i=count-1; i>=0; --i)
  828.         {
  829.             if (i < fDigitList->fDecimalAt && digitIndex < fDigitList->fCount)
  830.             {
  831.                 // Output a real digit
  832.                 result += ((UChar)(fDigitList->fDigits[digitIndex++] + zeroDelta));
  833.             }
  834.             else
  835.             {
  836.                 // Output a leading zero
  837.                 result += (zero);
  838.             }
  839.  
  840.             // Output grouping separator if necessary.  Don't output a
  841.             // grouping separator if i==0 though; that's at the end of
  842.             // the integer part.
  843.             if (isGroupingUsed() && i>0 && (fGroupingSize != 0) && (i % fGroupingSize == 0))
  844.             {
  845.                 result += (grouping);
  846.             }
  847.         }
  848.  
  849.         // Record field information for caller.
  850.         if (fieldPosition.getField() == NumberFormat::kIntegerField)
  851.             fieldPosition.setEndIndex(result.size());
  852.  
  853.         // Determine whether or not there are any printable fractional
  854.         // digits.  If we've used up the digits we know there aren't.
  855.         bool_t fractionPresent = (getMinimumFractionDigits() > 0) ||
  856.             (!isInteger && digitIndex < fDigitList->fCount);
  857.  
  858.         // If there is no fraction present, and we haven't printed any
  859.         // integer digits, then print a zero.  Otherwise we won't print
  860.         // _any_ digits, and we won't be able to parse this string.
  861.         if (!fractionPresent && result.size() == sizeBeforeIntegerPart)
  862.             result += (zero);
  863.  
  864.         // Output the decimal separator if we always do so.
  865.         if (fDecimalSeparatorAlwaysShown || fractionPresent)
  866.             result += (decimal);
  867.  
  868.         // Record field information for caller.
  869.         if (fieldPosition.getField() == NumberFormat::kFractionField)
  870.             fieldPosition.setBeginIndex(result.size());
  871.  
  872.         for (i=0; i < getMaximumFractionDigits(); ++i)
  873.         {
  874.             // Here is where we escape from the loop.  We escape if we've output
  875.             // the maximum fraction digits (specified in the for expression above).
  876.             // We also stop when we've output the minimum digits and either:
  877.             // we have an integer, so there is no fractional stuff to display,
  878.             // or we're out of significant digits.
  879.             if (i >= getMinimumFractionDigits() &&
  880.                 (isInteger || digitIndex >= fDigitList->fCount))
  881.                 break;
  882.  
  883.             // Output leading fractional zeros.  These are zeros that come after
  884.             // the decimal but before any significant digits.  These are only
  885.             // output if abs(number being formatted) < 1.0.
  886.             if (-1-i > (fDigitList->fDecimalAt-1))
  887.             {
  888.                 result += (zero);
  889.                 continue;
  890.             }
  891.  
  892.             // Output a digit, if we have any precision left, or a
  893.             // zero if we don't.  We don't want to output noise digits.
  894.             if (!isInteger && digitIndex < fDigitList->fCount)
  895.             {
  896.                 result += ((UChar)(fDigitList->fDigits[digitIndex++] + zeroDelta));
  897.             }
  898.             else
  899.             {
  900.                 result += (zero);
  901.             }
  902.         }
  903.  
  904.         // Record field information for caller.
  905.         if (fieldPosition.getField() == NumberFormat::kFractionField)
  906.             fieldPosition.setEndIndex(result.size());
  907.     }
  908.  
  909.     result += (isNegative ? fNegativeSuffix : fPositiveSuffix);
  910.  
  911.     addPadding(result, TRUE, isNegative);
  912.     return result;
  913. }
  914.  
  915. /**
  916.  * Inserts the character fPad as needed to expand result to fFormatWidth.
  917.  * @param result the string to be padded
  918.  * @param hasAffixes if true, padding is positioned appropriately before or
  919.  * after affixes.  If false, then isNegative is ignored, and there are only
  920.  * two effective pad positions: kPadBeforePrefix/kPadAfterPrefix and
  921.  * kPadBeforeSuffix/kPadAfterSuffix.
  922.  * @param isNegative must be true if result contains a formatted negative
  923.  * number, and false otherwise.  Ignored if hasAffixes is false.
  924.  */
  925. void DecimalFormat::addPadding(UnicodeString& result, bool_t hasAffixes,
  926.                                bool_t isNegative) const {
  927.     if (fFormatWidth > 0) {
  928.         int32_t len = fFormatWidth - result.size();
  929.         if (len > 0) {
  930.             UChar* padding = (UChar*) icu_malloc(sizeof(UChar) * len);
  931.             for (int32_t i=0; i<len; ++i) {
  932.                 padding[i] = fPad;
  933.             }
  934.             switch (fPadPosition) {
  935.             case kPadAfterPrefix:
  936.                 if (hasAffixes) {
  937.                     result.insert(isNegative ? fNegativePrefix.size()
  938.                                              : fPositivePrefix.size(),
  939.                                   padding, len);
  940.                     break;
  941.                 } // else fall through to next case
  942.             case kPadBeforePrefix:
  943.                 result.insert(0, padding, len);
  944.                 break;
  945.             case kPadBeforeSuffix:
  946.                 if (hasAffixes) {
  947.                     result.insert(result.size() -
  948.                                   (isNegative ? fNegativeSuffix.size()
  949.                                               : fPositiveSuffix.size()),
  950.                                   padding, len);
  951.                     break;
  952.                 } // else fall through to next case
  953.             case kPadAfterSuffix:
  954.                 result += padding;
  955.                 break;
  956.             }
  957.             icu_free(padding);
  958.         }
  959.     }
  960. }
  961.  
  962. //------------------------------------------------------------------------------
  963.  
  964. void
  965. DecimalFormat::parse(const UnicodeString& text,
  966.                      Formattable& result,
  967.                      UErrorCode& status) const
  968. {
  969.     NumberFormat::parse(text, result, status);
  970. }
  971.  
  972. const int32_t DecimalFormat::fgStatusInfinite    = 0;
  973. const int32_t DecimalFormat::fgStatusPositive    = 1;
  974. const int32_t DecimalFormat::fgStatusLength        = 2;
  975.  
  976. void
  977. DecimalFormat::parse(const UnicodeString& text,
  978.                      Formattable& result,
  979.                      ParsePosition& parsePosition) const
  980. {
  981.     // Skip padding characters, if any
  982.     int32_t backup = parsePosition.getIndex();
  983.     int32_t i = backup;
  984.     if (fFormatWidth > 0) {
  985.         while (i < text.size() && text[(UTextOffset) i] == fPad) {
  986.             ++i;
  987.         }
  988.         parsePosition.setIndex(i);
  989.     }
  990.  
  991.     // special case NaN
  992.     UnicodeString nan;
  993.     fSymbols->getNaN(nan);
  994.     // If the text is composed of the representation of NaN, returns NaN.
  995.     if (text.compare(parsePosition.getIndex(), nan.size(), nan,
  996.                      0, nan.size()) == 0) {
  997.         parsePosition.setIndex(parsePosition.getIndex() + nan.size());
  998.         result.setDouble(icu_getNaN());
  999.         return;
  1000.     }
  1001.  
  1002.     // status is used to record whether a number is
  1003.     // infinite or positive.
  1004.     bool_t status[fgStatusLength];
  1005.  
  1006.     if (!subparse(text, parsePosition, *fDigitList, FALSE, status)) {
  1007.         parsePosition.setIndex(backup);
  1008.         return;
  1009.     } else if (fFormatWidth < 0) {
  1010.         i = parsePosition.getIndex();
  1011.         while (i < text.size() && text[(UTextOffset) i] == fPad) {
  1012.             ++i;
  1013.         }
  1014.         parsePosition.setIndex(i);
  1015.     }
  1016.  
  1017.     // Handle infinity
  1018.     if (status[fgStatusInfinite]) {
  1019.         double inf = icu_getInfinity();
  1020.         result.setDouble(status[fgStatusPositive] ? inf : -inf);
  1021.         return;
  1022.     }
  1023.  
  1024.     // Do as much of the multiplier conversion as possible without
  1025.     // losing accuracy.
  1026.     int32_t mult = fMultiplier; // Don't modify this.multiplier
  1027.     while (mult % 10 == 0) {
  1028.         --fDigitList->fDecimalAt;
  1029.         mult /= 10;
  1030.     }
  1031.  
  1032.     // Handle integral values
  1033.     if (fDigitList->fitsIntoLong(status[fgStatusPositive],
  1034.                                  isParseIntegerOnly())) {
  1035.         int32_t n = fDigitList->getLong();
  1036.         if (n % mult == 0) {
  1037.             n /= mult;
  1038.             result.setLong((status[fgStatusPositive] == n>=0) ? n : -n);
  1039.             return;
  1040.         }
  1041.     }
  1042.  
  1043.     // Handle non-integral values
  1044.     double a = fDigitList->getDouble();
  1045.     if (mult != 1) {
  1046.         a /= mult;
  1047.     }
  1048.     result.setDouble(status[fgStatusPositive] ? a : -a);
  1049. }
  1050.  
  1051. /**
  1052.  * Parse the given text into a number.  The text is parsed beginning at
  1053.  * parsePosition, until an unparseable character is seen.
  1054.  * @param text The string to parse.
  1055.  * @param parsePosition The position at which to being parsing.  Upon
  1056.  * return, the first unparseable character.
  1057.  * @param digits The DigitList to set to the parsed value.
  1058.  * @param isExponent If true, parse an exponent.  This means no
  1059.  * infinite values and integer only.
  1060.  * @param status Upon return contains boolean status flags indicating
  1061.  * whether the value was infinite and whether it was positive.
  1062.  */
  1063. bool_t DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePosition,
  1064.                                DigitList& digits, bool_t isExponent,
  1065.                                bool_t* status) const
  1066. {
  1067.     int32_t position = parsePosition.getIndex();
  1068.     int32_t oldStart = parsePosition.getIndex();
  1069.     int32_t backup;
  1070.  
  1071.     // check for positivePrefix; take longest
  1072.     bool_t gotPositive = text.compare(position,fPositivePrefix.size(),fPositivePrefix,0,
  1073.                                       fPositivePrefix.size()) == 0;
  1074.     bool_t gotNegative = text.compare(position,fNegativePrefix.size(),fNegativePrefix,0,
  1075.                                       fNegativePrefix.size()) == 0;
  1076.     // If the number is positive and negative at the same time,
  1077.     // 1. the number is positive if the positive prefix is longer
  1078.     // 2. the number is negative if the negative prefix is longer
  1079.     if (gotPositive && gotNegative) {
  1080.         if (fPositivePrefix.size() > fNegativePrefix.size())
  1081.             gotNegative = FALSE;
  1082.         else if (fPositivePrefix.size() < fNegativePrefix.size())
  1083.             gotPositive = FALSE;
  1084.     }
  1085.     if(gotPositive)
  1086.         position += fPositivePrefix.size();
  1087.     else if(gotNegative)
  1088.         position += fNegativePrefix.size();
  1089.     else {
  1090.         parsePosition.setErrorIndex(position);
  1091.         return FALSE;
  1092.     }
  1093.     // process digits or Inf, find decimal position
  1094.     status[fgStatusInfinite] = FALSE;
  1095.     UnicodeString inf;
  1096.     fSymbols->getInfinity(inf);
  1097.     if (!isExponent && text.compare(position,inf.size(),inf,0,
  1098.                                     inf.size()) == 0)
  1099.     {
  1100.         // Found a infinite number.
  1101.         position += inf.size();
  1102.         status[fgStatusInfinite] = TRUE;
  1103.     } else {
  1104.         // We now have a string of digits, possibly with grouping symbols,
  1105.         // and decimal points.  We want to process these into a DigitList.
  1106.         // We don't want to put a bunch of leading zeros into the DigitList
  1107.         // though, so we keep track of the location of the decimal point,
  1108.         // put only significant digits into the DigitList, and adjust the
  1109.         // exponent as needed.
  1110.  
  1111.         digits.fDecimalAt = digits.fCount = 0;
  1112.         UChar zero = fSymbols->getZeroDigit();
  1113.         //UChar nine = (UChar)(zero + 9);
  1114.         //int32_t zeroDelta = '0' - zero;
  1115.         UChar decimal = fIsCurrencyFormat ?
  1116.             fSymbols->getMonetaryDecimalSeparator() : fSymbols->getDecimalSeparator();
  1117.         UChar grouping = fSymbols->getGroupingSeparator();
  1118.         UChar exponentChar = fSymbols->getExponentialSymbol();
  1119.         bool_t sawDecimal = FALSE;
  1120.         bool_t sawExponent = FALSE;
  1121.         bool_t sawDigit= FALSE;
  1122.         int32_t exponent = 0; // Set to the exponent value, if any
  1123.  
  1124.         // We have to track digitCount ourselves, because digits.fCount will
  1125.         // pin when the maximum allowable digits is reached.
  1126.         int32_t digitCount = 0;
  1127.  
  1128.         backup = -1;
  1129.         for (; position < text.size(); ++position)
  1130.         {
  1131.             UChar ch = text[(UTextOffset)position];
  1132.  
  1133.             /* We recognize all digit ranges, not only the Latin digit range
  1134.              * '0'..'9'.  We do so by using the Character.digit() method,
  1135.              * which converts a valid Unicode digit to the range 0..9.
  1136.              *
  1137.              * The character 'ch' may be a digit.  If so, place its value
  1138.              * from 0 to 9 in 'digit'.  First try using the locale digit,
  1139.              * which may or MAY NOT be a standard Unicode digit range.  If
  1140.              * this fails, try using the standard Unicode digit ranges by
  1141.              * calling Character.digit().  If this also fails, digit will
  1142.              * have a value outside the range 0..9.
  1143.              */
  1144.             int32_t digit = ch - zero;
  1145.             if (digit < 0 || digit > 9) digit = Unicode::digitValue(ch);
  1146.  
  1147.             if (digit == 0)
  1148.             {
  1149.                 // Cancel out backup setting (see grouping handler below)
  1150.                 backup = -1; // Do this BEFORE continue statement below!!!
  1151.                 sawDigit = TRUE;
  1152.  
  1153.                 // Handle leading zeros
  1154.                 if (digits.fCount == 0)
  1155.                 {
  1156.                     // Ignore leading zeros in integer part of number.
  1157.                     if (!sawDecimal) continue;
  1158.  
  1159.                     // If we have seen the decimal, but no significant digits yet,
  1160.                     // then we account for leading zeros by decrementing the
  1161.                     // digits.fDecimalAt into negative values.
  1162.                     --digits.fDecimalAt;
  1163.                 }
  1164.                 else
  1165.                 {
  1166.                     // output a regular zero digit.
  1167.                     ++digitCount;
  1168.                     digits.append((char)(digit + '0'));
  1169.                 }
  1170.             }
  1171.             else if (digit > 0 && digit <= 9)
  1172.             {
  1173.                 sawDigit = TRUE;
  1174.                 // output a regular non-zero digit.
  1175.                 ++digitCount;
  1176.                 digits.append((char)(digit + '0'));
  1177.  
  1178.                 // Cancel out backup setting (see grouping handler below)
  1179.                 backup = -1;
  1180.             }
  1181.             else if (!isExponent && ch == decimal)
  1182.             {
  1183.                 // If we're only parsing integers, or if we ALREADY saw the
  1184.                 // decimal, then don't parse this one.
  1185.                 if (isParseIntegerOnly() || sawDecimal) break;
  1186.                 digits.fDecimalAt = digitCount; // Not digits.fCount!
  1187.                 sawDecimal = TRUE;
  1188.             }
  1189.             else if (!isExponent && ch == grouping && isGroupingUsed())
  1190.             {
  1191.                 // Ignore grouping characters, if we are using them, but require
  1192.                 // that they be followed by a digit.  Otherwise we backup and
  1193.                 // reprocess them.
  1194.                 backup = position;
  1195.             }
  1196.             else if (!isExponent && ch == exponentChar && !sawExponent)
  1197.             {
  1198.                 // Parse sign, if present
  1199.                 bool_t negExp = FALSE;
  1200.                 int32_t pos = position + 1; // position + exponentSep.length();
  1201.                 if (pos < text.size()) {
  1202.                     ch = text[(UTextOffset) pos];
  1203.                     if (ch == fSymbols->getPlusSign()) {
  1204.                         ++pos;
  1205.                     } else if (ch == fSymbols->getMinusSign()) {
  1206.                         ++pos;
  1207.                         negExp = TRUE;
  1208.                     }
  1209.                 }
  1210.  
  1211.                 DigitList exponentDigits;
  1212.                 exponentDigits.fCount = 0;
  1213.                 while (pos < text.size()) {
  1214.                     digit = text[(UTextOffset) pos] - zero;
  1215.                     //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~
  1216.                     // TEMPORARY WORKAROUND
  1217.                     //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~
  1218.                     // The following code is disabled pending a fix to
  1219.                     // Unicode::digitValue().  Currently,
  1220.                     // Unicode::digitValue(']') returns 0, when it should
  1221.                     // return -1.  Liu 6/15/99
  1222.                     //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~
  1223.                     // TEMPORARY WORKAROUND
  1224.                     //~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~~*~
  1225.  
  1226.                     // if (digit < 0 || digit > 9) {
  1227.                     //    digit = Unicode::digitValue(ch);
  1228.                     // }
  1229.                     if (digit >= 0 && digit <= 9) {
  1230.                         exponentDigits.append((char)(digit + '0'));
  1231.                         ++pos;
  1232.                     } else {
  1233.                         break;
  1234.                     }
  1235.                 }
  1236.  
  1237.                 if (exponentDigits.fCount > 0) {
  1238.                     exponentDigits.fDecimalAt = exponentDigits.fCount;
  1239.                     exponent = exponentDigits.getLong();
  1240.                     if (negExp) {
  1241.                         exponent = -exponent;
  1242.                     }
  1243.                     position = pos; // Advance past the exponent
  1244.                     sawExponent = TRUE;
  1245.                 }
  1246.  
  1247.                 break; // Whether we fail or succeed, we exit this loop
  1248.             }
  1249.             else break;
  1250.         }
  1251.  
  1252.         if (backup != -1) position = backup;
  1253.  
  1254.         // If there was no decimal point we have an integer
  1255.         if (!sawDecimal) digits.fDecimalAt = digitCount; // Not digits.fCount!
  1256.  
  1257.         // Adjust for exponent, if any
  1258.         digits.fDecimalAt += exponent;
  1259.  
  1260.         // If none of the text string was recognized.  For example, parse
  1261.         // "x" with pattern "#0.00" (return index and error index both 0)
  1262.         // parse "$" with pattern "$#0.00". (return index 0 and error index
  1263.         // 1).
  1264.         if (!sawDigit && digitCount == 0) {
  1265.             parsePosition.setIndex(oldStart);
  1266.             parsePosition.setErrorIndex(oldStart);
  1267.             return FALSE;
  1268.         }
  1269.     }
  1270.  
  1271.     // check for positiveSuffix
  1272.     if (gotPositive)
  1273.         gotPositive = text.compare(position,fPositiveSuffix.size(),fPositiveSuffix,0,
  1274.                                    fPositiveSuffix.size()) == 0;
  1275.     if (gotNegative)
  1276.         gotNegative = text.compare(position,fNegativeSuffix.size(),fNegativeSuffix,0,
  1277.                                    fNegativeSuffix.size()) == 0;
  1278.  
  1279.     // if both match, take longest
  1280.     if (gotPositive && gotNegative) {
  1281.         if (fPositiveSuffix.size() > fNegativeSuffix.size())
  1282.             gotNegative = FALSE;
  1283.         else if (fPositiveSuffix.size() < fNegativeSuffix.size())
  1284.             gotPositive = FALSE;
  1285.     }
  1286.  
  1287.     // fail if neither or both
  1288.     if (gotPositive == gotNegative) {
  1289.         parsePosition.setErrorIndex(position);
  1290.         return FALSE;
  1291.     }
  1292.  
  1293.     parsePosition.setIndex(position +
  1294.                            (gotPositive ? fPositiveSuffix.size() :
  1295.                             fNegativeSuffix.size())); // mark success!
  1296.  
  1297.     status[fgStatusPositive] = gotPositive;
  1298.  
  1299.     if(parsePosition.getIndex() == oldStart) {
  1300.         parsePosition.setErrorIndex(position);
  1301.         return FALSE;
  1302.     }
  1303.     return TRUE;
  1304. }
  1305.  
  1306. //------------------------------------------------------------------------------
  1307. // Gets the pointer to the localized decimal format symbols
  1308.  
  1309. const DecimalFormatSymbols*
  1310. DecimalFormat::getDecimalFormatSymbols() const
  1311. {
  1312.     return fSymbols;
  1313. }
  1314.  
  1315. //------------------------------------------------------------------------------
  1316. // De-owning the current localized symbols and adopt the new symbols.
  1317.  
  1318. void
  1319. DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
  1320. {
  1321.     if (fSymbols != NULL)
  1322.         delete fSymbols;
  1323.  
  1324.     fSymbols = symbolsToAdopt;
  1325. }
  1326. //------------------------------------------------------------------------------
  1327. // Setting the symbols is equlivalent to adopting a newly created localized
  1328. // symbols.
  1329.  
  1330. void
  1331. DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
  1332. {
  1333.     adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
  1334.     expandAffixes();
  1335. }
  1336.  
  1337. //------------------------------------------------------------------------------
  1338. // Gets the positive prefix of the number pattern.
  1339.  
  1340. UnicodeString&
  1341. DecimalFormat::getPositivePrefix(UnicodeString& result) const
  1342. {
  1343.     result = fPositivePrefix;
  1344.     return result;
  1345. }
  1346.  
  1347. //------------------------------------------------------------------------------
  1348. // Sets the positive prefix of the number pattern.
  1349.  
  1350. void
  1351. DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
  1352. {
  1353.     fPositivePrefix = newValue;
  1354.     delete fPosPrefixPattern;
  1355.     fPosPrefixPattern = 0;
  1356. }
  1357.  
  1358. //------------------------------------------------------------------------------
  1359. // Gets the negative prefix  of the number pattern.
  1360.  
  1361. UnicodeString&
  1362. DecimalFormat::getNegativePrefix(UnicodeString& result) const
  1363. {
  1364.     result = fNegativePrefix;
  1365.     return result;
  1366. }
  1367.  
  1368. //------------------------------------------------------------------------------
  1369. // Gets the negative prefix  of the number pattern.
  1370.  
  1371. void
  1372. DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
  1373. {
  1374.     fNegativePrefix = newValue;
  1375.     delete fNegPrefixPattern;
  1376.     fNegPrefixPattern = 0;
  1377. }
  1378.  
  1379. //------------------------------------------------------------------------------
  1380. // Gets the positive suffix of the number pattern.
  1381.  
  1382. UnicodeString&
  1383. DecimalFormat::getPositiveSuffix(UnicodeString& result) const
  1384. {
  1385.     result = fPositiveSuffix;
  1386.     return result;
  1387. }
  1388.  
  1389. //------------------------------------------------------------------------------
  1390. // Sets the positive suffix of the number pattern.
  1391.  
  1392. void
  1393. DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
  1394. {
  1395.     fPositiveSuffix = newValue;
  1396.     delete fPosSuffixPattern;
  1397.     fPosSuffixPattern = 0;
  1398. }
  1399.  
  1400. //------------------------------------------------------------------------------
  1401. // Gets the negative suffix of the number pattern.
  1402.  
  1403. UnicodeString&
  1404. DecimalFormat::getNegativeSuffix(UnicodeString& result) const
  1405. {
  1406.     result = fNegativeSuffix;
  1407.     return result;
  1408. }
  1409.  
  1410. //------------------------------------------------------------------------------
  1411. // Sets the negative suffix of the number pattern.
  1412.  
  1413. void
  1414. DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
  1415. {
  1416.     fNegativeSuffix = newValue;
  1417.     delete fNegSuffixPattern;
  1418.     fNegSuffixPattern = 0;
  1419. }
  1420.  
  1421. //------------------------------------------------------------------------------
  1422. // Gets the multiplier of the number pattern.
  1423.  
  1424. int32_t DecimalFormat::getMultiplier() const
  1425. {
  1426.     return fMultiplier;
  1427. }
  1428.  
  1429. //------------------------------------------------------------------------------
  1430. // Sets the multiplier of the number pattern.
  1431.  
  1432. void
  1433. DecimalFormat::setMultiplier(int32_t newValue)
  1434. {
  1435.     // We should really take a UErrorCode and disallow values <= 0 - liu
  1436.     fMultiplier = newValue;
  1437. }
  1438.  
  1439. /**
  1440.  * Get the rounding increment.
  1441.  * @return A positive rounding increment, or 0.0 if rounding
  1442.  * is not in effect.
  1443.  * @see #setRoundingIncrement
  1444.  * @see #getRoundingMode
  1445.  * @see #setRoundingMode
  1446.  */
  1447. double DecimalFormat::getRoundingIncrement() {
  1448.     return fRoundingDouble;
  1449. }
  1450.  
  1451. /**
  1452.  * Set the rounding increment.  This method also controls whether
  1453.  * rounding is enabled.
  1454.  * @param newValue A positive rounding increment, or 0.0 to disable rounding.
  1455.  * Negative increments are equivalent to 0.0.
  1456.  * @see #getRoundingIncrement
  1457.  * @see #getRoundingMode
  1458.  * @see #setRoundingMode
  1459.  */
  1460. void DecimalFormat::setRoundingIncrement(double newValue) {
  1461.     if (newValue > 0.0) {
  1462.         if (fRoundingIncrement == NULL) {
  1463.             fRoundingIncrement = new DigitList();
  1464.         }
  1465.         fRoundingIncrement->set(newValue);
  1466.         fRoundingDouble = newValue;
  1467.     } else {
  1468.         delete fRoundingIncrement;
  1469.         fRoundingIncrement = NULL;
  1470.         fRoundingDouble = 0.0;
  1471.     }
  1472. }
  1473.  
  1474. /**
  1475.  * Get the rounding mode.
  1476.  * @return A rounding mode
  1477.  * @see #setRoundingIncrement
  1478.  * @see #getRoundingIncrement
  1479.  * @see #setRoundingMode
  1480.  */
  1481. DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() {
  1482.     return fRoundingMode;
  1483. }
  1484.  
  1485. /**
  1486.  * Set the rounding mode.  This has no effect unless the rounding
  1487.  * increment is greater than zero.
  1488.  * @param roundingMode A rounding mode
  1489.  * @see #setRoundingIncrement
  1490.  * @see #getRoundingIncrement
  1491.  * @see #getRoundingMode
  1492.  */
  1493. void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
  1494.     fRoundingMode = roundingMode;
  1495. }
  1496.  
  1497. /**
  1498.  * Get the width to which the output of <code>format()</code> is padded.
  1499.  * @return the format width, or zero if no padding is in effect
  1500.  * @see #setFormatWidth
  1501.  * @see #getPadCharacter
  1502.  * @see #setPadCharacter
  1503.  * @see #getPadPosition
  1504.  * @see #setPadPosition
  1505.  */
  1506. int32_t DecimalFormat::getFormatWidth() {
  1507.     return fFormatWidth;
  1508. }
  1509.  
  1510. /**
  1511.  * Set the width to which the output of <code>format()</code> is padded.
  1512.  * This method also controls whether padding is enabled.
  1513.  * @param width the width to which to pad the result of
  1514.  * <code>format()</code>, or zero to disable padding.  A negative
  1515.  * width is equivalent to 0.
  1516.  * @see #getFormatWidth
  1517.  * @see #getPadCharacter
  1518.  * @see #setPadCharacter
  1519.  * @see #getPadPosition
  1520.  * @see #setPadPosition
  1521.  */
  1522. void DecimalFormat::setFormatWidth(int32_t width) {
  1523.     fFormatWidth = (width > 0) ? width : 0;
  1524. }
  1525.  
  1526. /**
  1527.  * Get the character used to pad to the format width.  The default is ' '.
  1528.  * @return the pad character
  1529.  * @see #setFormatWidth
  1530.  * @see #getFormatWidth
  1531.  * @see #setPadCharacter
  1532.  * @see #getPadPosition
  1533.  * @see #setPadPosition
  1534.  */
  1535. UChar DecimalFormat::getPadCharacter() {
  1536.     return fPad;
  1537. }
  1538.  
  1539. /**
  1540.  * Set the character used to pad to the format width.  This has no effect
  1541.  * unless padding is enabled.
  1542.  * @param padChar the pad character
  1543.  * @see #setFormatWidth
  1544.  * @see #getFormatWidth
  1545.  * @see #getPadCharacter
  1546.  * @see #getPadPosition
  1547.  * @see #setPadPosition
  1548.  */
  1549. void DecimalFormat::setPadCharacter(UChar padChar) {
  1550.     fPad = padChar;
  1551. }
  1552.  
  1553. /**
  1554.  * Get the position at which padding will take place.  This is the location
  1555.  * at which padding will be inserted if the result of <code>format()</code>
  1556.  * is shorter than the format width.
  1557.  * @return the pad position, one of <code>kPadBeforePrefix</code>,
  1558.  * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
  1559.  * <code>kPadAfterSuffix</code>.
  1560.  * @see #setFormatWidth
  1561.  * @see #getFormatWidth
  1562.  * @see #setPadCharacter
  1563.  * @see #getPadCharacter
  1564.  * @see #setPadPosition
  1565.  * @see #kPadBeforePrefix
  1566.  * @see #kPadAfterPrefix
  1567.  * @see #kPadBeforeSuffix
  1568.  * @see #kPadAfterSuffix
  1569.  */
  1570. DecimalFormat::EPadPosition DecimalFormat::getPadPosition() {
  1571.     return fPadPosition;
  1572. }
  1573.  
  1574. /**
  1575.  * <strong><font face=helvetica color=red>NEW</font></strong>
  1576.  * Set the position at which padding will take place.  This is the location
  1577.  * at which padding will be inserted if the result of <code>format()</code>
  1578.  * is shorter than the format width.  This has no effect unless padding is
  1579.  * enabled.
  1580.  * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
  1581.  * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
  1582.  * <code>kPadAfterSuffix</code>.
  1583.  * @see #setFormatWidth
  1584.  * @see #getFormatWidth
  1585.  * @see #setPadCharacter
  1586.  * @see #getPadCharacter
  1587.  * @see #getPadPosition
  1588.  * @see #kPadBeforePrefix
  1589.  * @see #kPadAfterPrefix
  1590.  * @see #kPadBeforeSuffix
  1591.  * @see #kPadAfterSuffix
  1592.  */
  1593. void DecimalFormat::setPadPosition(EPadPosition padPos) {
  1594.     fPadPosition = padPos;
  1595. }
  1596.  
  1597. /**
  1598.  * Return whether or not scientific notation is used.
  1599.  * @return TRUE if this object formats and parses scientific notation
  1600.  * @see #setScientificNotation
  1601.  * @see #getMinimumExponentDigits
  1602.  * @see #setMinimumExponentDigits
  1603.  * @see #isExponentSignAlwaysShown
  1604.  * @see #setExponentSignAlwaysShown
  1605.  */
  1606. bool_t DecimalFormat::isScientificNotation() {
  1607.     return fUseExponentialNotation;
  1608. }
  1609.  
  1610. /**
  1611.  * Set whether or not scientific notation is used.
  1612.  * @param useScientific TRUE if this object formats and parses scientific
  1613.  * notation
  1614.  * @see #isScientificNotation
  1615.  * @see #getMinimumExponentDigits
  1616.  * @see #setMinimumExponentDigits
  1617.  * @see #isExponentSignAlwaysShown
  1618.  * @see #setExponentSignAlwaysShown
  1619.  */
  1620. void DecimalFormat::setScientificNotation(bool_t useScientific) {
  1621.     fUseExponentialNotation = useScientific;
  1622.     if (fUseExponentialNotation && fMinExponentDigits < 1) {
  1623.         fMinExponentDigits = 1;
  1624.     }
  1625. }
  1626.  
  1627. /**
  1628.  * Return the minimum exponent digits that will be shown.
  1629.  * @return the minimum exponent digits that will be shown
  1630.  * @see #setScientificNotation
  1631.  * @see #isScientificNotation
  1632.  * @see #setMinimumExponentDigits
  1633.  * @see #isExponentSignAlwaysShown
  1634.  * @see #setExponentSignAlwaysShown
  1635.  */
  1636. int8_t DecimalFormat::getMinimumExponentDigits() {
  1637.     return fMinExponentDigits;
  1638. }
  1639.  
  1640. /**
  1641.  * Set the minimum exponent digits that will be shown.  This has no
  1642.  * effect unless scientific notation is in use.
  1643.  * @param minExpDig a value >= 1 indicating the fewest exponent digits
  1644.  * that will be shown.  Values less than 1 will be treated as 1.
  1645.  * @see #setScientificNotation
  1646.  * @see #isScientificNotation
  1647.  * @see #getMinimumExponentDigits
  1648.  * @see #isExponentSignAlwaysShown
  1649.  * @see #setExponentSignAlwaysShown
  1650.  */
  1651. void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
  1652.     fMinExponentDigits = (minExpDig > 0) ? minExpDig : 1;
  1653. }
  1654.  
  1655. /**
  1656.  * Return whether the exponent sign is always shown.
  1657.  * @return TRUE if the exponent is always prefixed with either the
  1658.  * localized minus sign or the localized plus sign, false if only negative
  1659.  * exponents are prefixed with the localized minus sign.
  1660.  * @see #setScientificNotation
  1661.  * @see #isScientificNotation
  1662.  * @see #setMinimumExponentDigits
  1663.  * @see #getMinimumExponentDigits
  1664.  * @see #setExponentSignAlwaysShown
  1665.  */
  1666. bool_t DecimalFormat::isExponentSignAlwaysShown() {
  1667.     return fExponentSignAlwaysShown;
  1668. }
  1669.  
  1670. /**
  1671.  * Set whether the exponent sign is always shown.  This has no effect
  1672.  * unless scientific notation is in use.
  1673.  * @param expSignAlways TRUE if the exponent is always prefixed with either
  1674.  * the localized minus sign or the localized plus sign, false if only
  1675.  * negative exponents are prefixed with the localized minus sign.
  1676.  * @see #setScientificNotation
  1677.  * @see #isScientificNotation
  1678.  * @see #setMinimumExponentDigits
  1679.  * @see #getMinimumExponentDigits
  1680.  * @see #isExponentSignAlwaysShown
  1681.  */
  1682. void DecimalFormat::setExponentSignAlwaysShown(bool_t expSignAlways) {
  1683.     fExponentSignAlwaysShown = expSignAlways;
  1684. }
  1685.  
  1686. //------------------------------------------------------------------------------
  1687. // Gets the grouping size of the number pattern.  For example, thousand or 10
  1688. // thousand groupings.
  1689.  
  1690. int32_t
  1691. DecimalFormat::getGroupingSize() const
  1692. {
  1693.     return fGroupingSize;
  1694. }
  1695.  
  1696. //------------------------------------------------------------------------------
  1697. // Gets the grouping size of the number pattern.
  1698.  
  1699. void
  1700. DecimalFormat::setGroupingSize(int32_t newValue)
  1701. {
  1702.     fGroupingSize = newValue;
  1703. }
  1704.  
  1705. //------------------------------------------------------------------------------
  1706. // Checks if to show the decimal separator.
  1707.  
  1708. bool_t
  1709. DecimalFormat::isDecimalSeparatorAlwaysShown() const
  1710. {
  1711.     return fDecimalSeparatorAlwaysShown;
  1712. }
  1713.  
  1714. //------------------------------------------------------------------------------
  1715. // Sets to always show the decimal separator.
  1716.  
  1717. void
  1718. DecimalFormat::setDecimalSeparatorAlwaysShown(bool_t newValue)
  1719. {
  1720.     fDecimalSeparatorAlwaysShown = newValue;
  1721. }
  1722.  
  1723. //------------------------------------------------------------------------------
  1724. // Emits the pattern of this DecimalFormat instance.
  1725.  
  1726. UnicodeString&
  1727. DecimalFormat::toPattern(UnicodeString& result) const
  1728. {
  1729.     return toPattern(result, FALSE);
  1730. }
  1731.  
  1732. //------------------------------------------------------------------------------
  1733. // Emits the localized pattern this DecimalFormat instance.
  1734.  
  1735. UnicodeString&
  1736. DecimalFormat::toLocalizedPattern(UnicodeString& result) const
  1737. {
  1738.     return toPattern(result, TRUE);
  1739. }
  1740.  
  1741. //------------------------------------------------------------------------------
  1742. /**
  1743.  * Expand the affix pattern strings into the expanded affix strings.  If any
  1744.  * affix pattern string is null, do not expand it.  This method should be
  1745.  * called any time the symbols or the affix patterns change in order to keep
  1746.  * the expanded affix strings up to date.
  1747.  */
  1748. void DecimalFormat::expandAffixes() {
  1749.     if (fPosPrefixPattern != 0) {
  1750.         expandAffix(*fPosPrefixPattern, fPositivePrefix);
  1751.     }
  1752.     if (fPosSuffixPattern != 0) {
  1753.         expandAffix(*fPosSuffixPattern, fPositiveSuffix);
  1754.     }
  1755.     if (fNegPrefixPattern != 0) {
  1756.         expandAffix(*fNegPrefixPattern, fNegativePrefix);
  1757.     }
  1758.     if (fNegSuffixPattern != 0) {
  1759.         expandAffix(*fNegSuffixPattern, fNegativeSuffix);
  1760.     }
  1761. #ifdef DEBUG
  1762.     UnicodeString s;
  1763.     s.append("[")
  1764.         .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern)
  1765.         .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern)
  1766.         .append("]->[")
  1767.         .append(fPositivePrefix).append("|").append(fPositiveSuffix)
  1768.         .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix)
  1769.         .append("]\n");
  1770.     debugout(s);
  1771. #endif
  1772. }
  1773.  
  1774. /**
  1775.  * Expand an affix pattern into an affix string.  All characters in the
  1776.  * pattern are literal unless prefixed by kQuote.  The following characters
  1777.  * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
  1778.  * PATTERN_MINUS, and kCurrencySign.  If kCurrencySign is doubled (kQuote +
  1779.  * kCurrencySign + kCurrencySign), it is interpreted as an international
  1780.  * currency sign.  Any other character after a kQuote represents itself.
  1781.  * kQuote must be followed by another character; kQuote may not occur by
  1782.  * itself at the end of the pattern.
  1783.  *
  1784.  * @param pattern the non-null, fPossibly empty pattern
  1785.  * @param affix string to receive the expanded equivalent of pattern
  1786.  */
  1787. void DecimalFormat::expandAffix(const UnicodeString& pattern,
  1788.                                 UnicodeString& affix) const {
  1789.     affix.remove();
  1790.     for (int i=0; i<pattern.size(); ) {
  1791.         UChar c = pattern.charAt(i++);
  1792.         if (c == kQuote) {
  1793.             c = pattern.charAt(i++);
  1794.             switch (c) {
  1795.             case kCurrencySign:
  1796.                 {
  1797.                     UnicodeString s;
  1798.                     if (i<pattern.size() &&
  1799.                         pattern.charAt(i) == kCurrencySign) {
  1800.                         ++i;
  1801.                         affix += fSymbols->getInternationalCurrencySymbol(s);
  1802.                     } else {
  1803.                         affix += fSymbols->getCurrencySymbol(s);
  1804.                     }
  1805.                 }
  1806.                 continue;
  1807.             case kPatternPercent:
  1808.                 c = fSymbols->getPercent();
  1809.                 break;
  1810.             case kPatternPerMill:
  1811.                 c = fSymbols->getPerMill();
  1812.                 break;
  1813.             case kPatternPlus:
  1814.                 c = fSymbols->getPlusSign();
  1815.                 break;
  1816.             case kPatternMinus:
  1817.                 c = fSymbols->getMinusSign();
  1818.                 break;
  1819.             }
  1820.         }
  1821.         affix.append(c);
  1822.     }
  1823. }
  1824.  
  1825. /**
  1826.  * Appends an affix pattern to the given StringBuffer, quoting special
  1827.  * characters as needed.  Uses the internal affix pattern, if that exists,
  1828.  * or the literal affix, if the internal affix pattern is null.  The
  1829.  * appended string will generate the same affix pattern (or literal affix)
  1830.  * when passed to toPattern().
  1831.  *
  1832.  * @param buffer the affix string is appended to this
  1833.  * @param affixPattern a pattern such as fPosPrefixPattern; may be null
  1834.  * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
  1835.  * Ignored unless affixPattern is null.  If affixPattern is null, then
  1836.  * expAffix is appended as a literal affix.
  1837.  * @param localized true if the appended pattern should contain localized
  1838.  * pattern characters; otherwise, non-localized pattern chars are appended
  1839.  */
  1840. void DecimalFormat::appendAffix(UnicodeString& buffer,
  1841.                                 const UnicodeString* affixPattern,
  1842.                                 const UnicodeString& expAffix,
  1843.                                 bool_t localized) const {
  1844.     if (affixPattern == 0) {
  1845.         appendAffix(buffer, expAffix, localized);
  1846.     } else {
  1847.         int i;
  1848.         for (int pos=0; pos<affixPattern->size(); pos=i) {
  1849.             i = affixPattern->indexOf(kQuote, pos);
  1850.             if (i < 0) {
  1851.                 UnicodeString s;
  1852.                 affixPattern->extractBetween(pos, affixPattern->size(), s);
  1853.                 appendAffix(buffer, s, localized);
  1854.                 break;
  1855.             }
  1856.             if (i > pos) {
  1857.                 UnicodeString s;
  1858.                 affixPattern->extractBetween(pos, i, s);
  1859.                 appendAffix(buffer, s, localized);
  1860.             }
  1861.             UChar c = affixPattern->charAt(++i);
  1862.             ++i;
  1863.             if (c == kQuote) {
  1864.                 buffer.append(c);
  1865.                 // Fall through and append another kQuote below
  1866.             } else if (c == kCurrencySign &&
  1867.                        i<affixPattern->size() &&
  1868.                        affixPattern->charAt(i) == kCurrencySign) {
  1869.                 ++i;
  1870.                 buffer.append(c);
  1871.                 // Fall through and append another kCurrencySign below
  1872.             } else if (localized) {
  1873.                 switch (c) {
  1874.                 case kPatternPercent:
  1875.                     c = fSymbols->getPercent();
  1876.                     break;
  1877.                 case kPatternPerMill:
  1878.                     c = fSymbols->getPerMill();
  1879.                     break;
  1880.                 case kPatternPlus:
  1881.                     c = fSymbols->getPlusSign();
  1882.                     break;
  1883.                 case kPatternMinus:
  1884.                     c = fSymbols->getMinusSign();
  1885.                     break;
  1886.                 }
  1887.             }
  1888.             buffer.append(c);
  1889.         }
  1890.     }
  1891. }
  1892.  
  1893. /**
  1894.  * Append an affix to the given StringBuffer, using quotes if
  1895.  * there are special characters.  Single quotes themselves must be
  1896.  * escaped in either case.
  1897.  */
  1898. void
  1899. DecimalFormat::appendAffix(    UnicodeString& buffer,
  1900.                             const UnicodeString& affix,
  1901.                             bool_t localized) const {
  1902.     bool_t needQuote;
  1903.     if(localized) {
  1904.         needQuote = affix.indexOf(fSymbols->getZeroDigit()) >= 0
  1905.             || affix.indexOf(fSymbols->getGroupingSeparator()) >= 0
  1906.             || affix.indexOf(fSymbols->getDecimalSeparator()) >= 0
  1907.             || affix.indexOf(fSymbols->getPercent()) >= 0
  1908.             || affix.indexOf(fSymbols->getPerMill()) >= 0
  1909.             || affix.indexOf(fSymbols->getDigit()) >= 0
  1910.             || affix.indexOf(fSymbols->getPatternSeparator()) >= 0
  1911.             || affix.indexOf(fSymbols->getPlusSign()) >= 0
  1912.             || affix.indexOf(fSymbols->getMinusSign()) >= 0
  1913.             || affix.indexOf(kCurrencySign) >= 0;
  1914.     }
  1915.     else {
  1916.         needQuote = affix.indexOf(kPatternZeroDigit) >= 0
  1917.             || affix.indexOf(kPatternGroupingSeparator) >= 0
  1918.             || affix.indexOf(kPatternDecimalSeparator) >= 0
  1919.             || affix.indexOf(kPatternPercent) >= 0
  1920.             || affix.indexOf(kPatternPerMill) >= 0
  1921.             || affix.indexOf(kPatternDigit) >= 0
  1922.             || affix.indexOf(kPatternSeparator) >= 0
  1923.             || affix.indexOf(kPatternExponent) >= 0
  1924.             || affix.indexOf(kPatternPlus) >= 0
  1925.             || affix.indexOf(kPatternMinus) >= 0
  1926.             || affix.indexOf(kCurrencySign) >= 0;
  1927.     }
  1928.     if (needQuote)
  1929.         buffer += 0x0027 /*'\''*/;
  1930.     if (affix.indexOf(0x0027 /*'\''*/) < 0)
  1931.         buffer += affix;
  1932.     else {
  1933.         for (int32_t j = 0; j < affix.size(); ++j) {
  1934.             UChar c = affix[j];
  1935.             buffer += c;
  1936.             if (c == 0x0027 /*'\''*/) buffer += c;
  1937.         }
  1938.     }
  1939.     if (needQuote) buffer += 0x0027 /*'\''*/;
  1940. }
  1941.  
  1942. //------------------------------------------------------------------------------
  1943.  
  1944. /* Tell the VC++ compiler not to spew out the warnings about integral size conversion */
  1945. #ifdef _WIN32
  1946. #pragma warning( disable : 4761 )
  1947. #endif
  1948.  
  1949. UnicodeString&
  1950. DecimalFormat::toPattern(UnicodeString& result, bool_t localized) const
  1951. {
  1952.     result.remove();
  1953.     UChar zero = localized ? fSymbols->getZeroDigit() : kPatternZeroDigit;
  1954.     UChar digit = localized ? fSymbols->getDigit() : kPatternDigit;
  1955.     UChar group = localized ? fSymbols->getGroupingSeparator()
  1956.                            : kPatternGroupingSeparator;
  1957.     int32_t i;
  1958.     int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
  1959.     UnicodeString roundingDigits;
  1960.     int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
  1961.     UnicodeString padSpec;
  1962.     if(fFormatWidth > 0) {
  1963.       padSpec.append(localized ? fSymbols->getPadEscape() : kPatternPadEscape).
  1964.     append(fPad);
  1965.     }
  1966.     if(fRoundingIncrement != NULL) {
  1967.       for(i=0; i<fRoundingIncrement->fCount; ++i) {
  1968.     roundingDigits.append(fRoundingIncrement->fDigits[i]);
  1969.       }
  1970.       roundingDecimalPos = fRoundingIncrement->fDecimalAt;
  1971.     }
  1972.     for (int32_t part=0; part<2; ++part) {
  1973.       int32_t partStart = result.length();
  1974.       if (padPos == kPadBeforePrefix) {
  1975.     result.append(padSpec);
  1976.       }
  1977.       appendAffix(result,
  1978.           (part==0 ? fPosPrefixPattern : fNegPrefixPattern),
  1979.           (part==0 ? fPositivePrefix : fNegativePrefix),
  1980.           localized);
  1981.       if (padPos == kPadAfterPrefix && ! padSpec.empty()) {
  1982.     result.append(padSpec);
  1983.       }
  1984.       int32_t sub0Start = result.length();
  1985.       int32_t maxIntDig = fUseExponentialNotation ? getMaximumIntegerDigits() :
  1986.     (icu_max(icu_max(fGroupingSize, getMinimumIntegerDigits()),
  1987.          roundingDecimalPos) + 1);
  1988.       for (i = maxIntDig; i > 0; --i) {
  1989.     if (isGroupingUsed() && fGroupingSize != 0
  1990.         && i % fGroupingSize == 0
  1991.         && i < maxIntDig
  1992.         && !fUseExponentialNotation) {
  1993.       result.append(group);
  1994.     }
  1995.     if (! roundingDigits.empty()) {
  1996.       int32_t pos = roundingDecimalPos - i;
  1997.       if (pos >= 0 && pos < roundingDigits.length()) {
  1998.         result.append((UChar) (roundingDigits.charAt(pos) - kPatternZeroDigit + zero));
  1999.         continue;
  2000.       }
  2001.     }
  2002.     result.append(i<=getMinimumIntegerDigits() ? zero : digit);
  2003.       }
  2004.       if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
  2005.     result.append(localized ? fSymbols->getDecimalSeparator() :
  2006.               kPatternDecimalSeparator);
  2007.       }
  2008.       int32_t pos = roundingDecimalPos;
  2009.       for (i = 0; i < getMaximumFractionDigits(); ++i) {
  2010.     if (! roundingDigits.empty() &&
  2011.         pos < roundingDigits.length()) {
  2012.       result.append(pos < 0 ? zero :
  2013.             (UChar) (roundingDigits.charAt(pos) - kPatternZeroDigit + zero));
  2014.       ++pos;
  2015.       continue;
  2016.             }
  2017.             result.append(i<getMinimumFractionDigits() ? zero : digit);
  2018.         }
  2019.         if (fUseExponentialNotation) {
  2020.             result.append(localized ? fSymbols->getExponentialSymbol() :
  2021.                           kPatternExponent);
  2022.             if (fExponentSignAlwaysShown) {
  2023.                 result.append(localized ? fSymbols->getPlusSign() :
  2024.                               kPatternPlus);
  2025.             }
  2026.             for (i=0; i<fMinExponentDigits; ++i) {
  2027.                 result.append(zero);
  2028.             }
  2029.         }
  2030.         if (! padSpec.empty() && !fUseExponentialNotation) {
  2031.             int32_t add = fFormatWidth - result.length() + sub0Start
  2032.                 - ((part == 0)
  2033.                    ? fPositivePrefix.length() + fPositiveSuffix.length()
  2034.                    : fNegativePrefix.length() + fNegativeSuffix.length());
  2035.             while (add > 0) {
  2036.                 result.insert(sub0Start, digit);
  2037.                 --add;
  2038.                 if (isGroupingUsed() && fGroupingSize != 0
  2039.                     && ++maxIntDig % fGroupingSize == 0
  2040.                     && add > 1) {
  2041.                     result.insert(sub0Start, group);
  2042.                     --add;
  2043.                 }
  2044.             }
  2045.         }
  2046.         if (fPadPosition == kPadBeforeSuffix && ! padSpec.empty()) {
  2047.             result.append(padSpec);
  2048.         }
  2049.         if (part == 0) {
  2050.             appendAffix(result, fPosSuffixPattern, fPositiveSuffix, localized);
  2051.             if (fPadPosition == kPadAfterSuffix && ! padSpec.empty()) {
  2052.                 result.append(padSpec);
  2053.             }
  2054.             bool_t isDefault = FALSE;
  2055.             if ((fNegSuffixPattern == fPosSuffixPattern && // both null
  2056.                  fNegativeSuffix == fPositiveSuffix)
  2057.                 || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 &&
  2058.                     *fNegSuffixPattern == *fPosSuffixPattern)) {
  2059.                 if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL) {
  2060.                     int32_t length = fPosPrefixPattern->length();
  2061.                     isDefault = fNegPrefixPattern->length() == (length+2) &&
  2062.                         (*fNegPrefixPattern)[(UTextOffset)0] == kQuote &&
  2063.                         (*fNegPrefixPattern)[(UTextOffset)1] == kPatternMinus &&
  2064.                         fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0;
  2065.                 }
  2066.                 if (!isDefault &&
  2067.                     fNegPrefixPattern == NULL && fPosPrefixPattern == NULL) {
  2068.                     int32_t length = fPositivePrefix.length();
  2069.                     isDefault = fNegativePrefix.length() == (length+1) &&
  2070.                         fNegativePrefix[(UTextOffset)0] == fSymbols->getMinusSign() &&
  2071.                         fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
  2072.                 }
  2073.             }
  2074.             if (isDefault) {
  2075.                 break; // Don't output default negative subpattern
  2076.             } else {
  2077.                 result.append(localized ? fSymbols->getPatternSeparator() :
  2078.                               kPatternSeparator);
  2079.             }
  2080.         } else {
  2081.             appendAffix(result, fNegSuffixPattern, fNegativeSuffix, localized);
  2082.             if (fPadPosition == kPadAfterSuffix && ! padSpec.empty()) {
  2083.                 result.append(padSpec);
  2084.             }
  2085.         }
  2086.     }
  2087.  
  2088.     return result;
  2089. }
  2090.  
  2091. //------------------------------------------------------------------------------
  2092.  
  2093. void
  2094. DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
  2095. {
  2096.     applyPattern(pattern, FALSE, status);
  2097. }
  2098.  
  2099. //------------------------------------------------------------------------------
  2100.  
  2101. void
  2102. DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
  2103. {
  2104.     applyPattern(pattern, TRUE, status);
  2105. }
  2106.  
  2107. //------------------------------------------------------------------------------
  2108.  
  2109. void
  2110. DecimalFormat::applyPattern(const UnicodeString& pattern,
  2111.                             bool_t localized,
  2112.                             UErrorCode& status)
  2113. {
  2114.     if (U_FAILURE(status)) return;
  2115.     // Set the significant pattern symbols
  2116.     UChar zeroDigit         = kPatternZeroDigit;
  2117.     UChar groupingSeparator = kPatternGroupingSeparator;
  2118.     UChar decimalSeparator  = kPatternDecimalSeparator;
  2119.     UChar percent           = kPatternPercent;
  2120.     UChar perMill           = kPatternPerMill;
  2121.     UChar digit             = kPatternDigit;
  2122.     UChar separator         = kPatternSeparator;
  2123.     UChar exponent          = kPatternExponent;
  2124.     UChar plus              = kPatternPlus;
  2125.     UChar minus             = kPatternMinus;
  2126.     UChar padEscape         = kPatternPadEscape;
  2127.     // Substitute with the localized symbols if necessary
  2128.     if (localized) {
  2129.         zeroDigit         = fSymbols->getZeroDigit();
  2130.         groupingSeparator = fSymbols->getGroupingSeparator();
  2131.         decimalSeparator  = fSymbols->getDecimalSeparator();
  2132.         percent           = fSymbols->getPercent();
  2133.         perMill           = fSymbols->getPerMill();
  2134.         digit             = fSymbols->getDigit();
  2135.         separator         = fSymbols->getPatternSeparator();
  2136.         exponent          = fSymbols->getExponentialSymbol();
  2137.         plus              = fSymbols->getPlusSign();
  2138.         minus             = fSymbols->getMinusSign();
  2139.         padEscape         = fSymbols->getPadEscape();
  2140.     }
  2141.     UChar nineDigit = zeroDigit + 9;
  2142.  
  2143.     int32_t pos = 0;
  2144.     // Part 0 is the positive pattern.  Part 1, if present, is the negative
  2145.     // pattern.
  2146.     for (int32_t part=0; part<2 && pos<pattern.length(); ++part) {
  2147.         // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
  2148.         // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
  2149.         // between the prefix and suffix, and consists of pattern
  2150.         // characters.  In the prefix and suffix, percent, perMill, and
  2151.         // currency symbols are recognized and translated.
  2152.         int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
  2153.         
  2154.         // It's important that we don't change any fields of this object
  2155.         // prematurely.  We set the following variables for the multiplier,
  2156.         // grouping, etc., and then only change the actual object fields if
  2157.         // everything parses correctly.  This also lets us register
  2158.         // the data from part 0 and ignore the part 1, except for the
  2159.         // prefix and suffix.
  2160.         UnicodeString prefix;
  2161.         UnicodeString suffix;
  2162.         int32_t decimalPos = -1;
  2163.         int32_t multiplier = 1;
  2164.         int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0;
  2165.         int8_t groupingCount = -1;
  2166.         int32_t padPos = -1;
  2167.         UChar padChar = 0;
  2168.         int32_t roundingPos = -1;
  2169.         DigitList roundingInc;
  2170.         int8_t expDigits = -1;
  2171.         bool_t expSignAlways = FALSE;
  2172.         bool_t isCurrency = FALSE;
  2173.         
  2174.         // The affix is either the prefix or the suffix.
  2175.         UnicodeString* affix = &prefix;
  2176.         
  2177.         int32_t start = pos;
  2178.         bool_t isPartDone = FALSE;
  2179.  
  2180.         for (; !isPartDone && pos < pattern.size(); ++pos) {
  2181.             UChar ch = pattern[(UTextOffset) pos];
  2182.             switch (subpart) {
  2183.             case 0: // Pattern proper subpart (between prefix & suffix)
  2184.                 // Process the digits, decimal, and grouping characters.  We
  2185.                 // record five pieces of information.  We expect the digits
  2186.                 // to occur in the pattern ####00.00####, and we record the
  2187.                 // number of left digits, zero (central) digits, and right
  2188.                 // digits.  The position of the last grouping character is
  2189.                 // recorded (should be somewhere within the first two blocks
  2190.                 // of characters), as is the position of the decimal point,
  2191.                 // if any (should be in the zero digits).  If there is no
  2192.                 // decimal point, then there should be no right digits.
  2193.                 if (ch == digit) {
  2194.                     if (zeroDigitCount > 0) {
  2195.                         ++digitRightCount;
  2196.                     } else {
  2197.                         ++digitLeftCount;
  2198.                     }
  2199.                     if (groupingCount >= 0 && decimalPos < 0) {
  2200.                         ++groupingCount;
  2201.                     }
  2202.                 } else if (ch >= zeroDigit && ch <= nineDigit) {
  2203.                     if (digitRightCount > 0) {
  2204.                         // Unexpected '0'
  2205.                         debug("Unexpected '0'")
  2206.                         status = U_ILLEGAL_ARGUMENT_ERROR;
  2207.                         return;
  2208.                     }
  2209.                     ++zeroDigitCount;
  2210.                     if (groupingCount >= 0 && decimalPos < 0) {
  2211.                         ++groupingCount;
  2212.                     }
  2213.                     if (ch != zeroDigit && roundingPos < 0) {
  2214.                         roundingPos = digitLeftCount + zeroDigitCount;
  2215.                     }
  2216.                     if (roundingPos >= 0) {
  2217.                         roundingInc.append((char)(ch - zeroDigit + '0'));
  2218.                     }
  2219.                 } else if (ch == groupingSeparator) {
  2220.                     if (decimalPos >= 0) {
  2221.                         // Grouping separator after decimal
  2222.                         debug("Grouping separator after decimal")
  2223.                         status = U_ILLEGAL_ARGUMENT_ERROR;
  2224.                         return;
  2225.                     }
  2226.                     groupingCount = 0;
  2227.                 } else if (ch == decimalSeparator) {
  2228.                     if (decimalPos >= 0) {
  2229.                         // Multiple decimal separators
  2230.                         debug("Multiple decimal separators")
  2231.                         status = U_ILLEGAL_ARGUMENT_ERROR;
  2232.                         return;
  2233.                     }
  2234.                     // Intentionally incorporate the digitRightCount,
  2235.                     // even though it is illegal for this to be > 0
  2236.                     // at this point.  We check pattern syntax below.
  2237.                     decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
  2238.                 } else {
  2239.                     if (ch == exponent) {
  2240.                         if (expDigits >= 0) {
  2241.                             // Multiple exponential symbols
  2242.                             debug("Multiple exponential symbols")
  2243.                             status = U_ILLEGAL_ARGUMENT_ERROR;
  2244.                             return;
  2245.                         }
  2246.                         if (groupingCount >= 0) {
  2247.                             // Grouping separator in exponential pattern
  2248.                             debug("Grouping separator in exponential pattern")
  2249.                             status = U_ILLEGAL_ARGUMENT_ERROR;
  2250.                             return;
  2251.                         }
  2252.                         // Check for positive prefix
  2253.                         if ((pos+1) < pattern.size()
  2254.                             && pattern[(UTextOffset) (pos+1)] == plus) {
  2255.                             expSignAlways = TRUE;
  2256.                             ++pos;
  2257.                         }
  2258.                         // Use lookahead to parse out the exponential part of the
  2259.                         // pattern, then jump into suffix subpart.
  2260.                         expDigits = 0;
  2261.                         while (++pos < pattern.size() &&
  2262.                                pattern[(UTextOffset) pos] == zeroDigit) {
  2263.                             ++expDigits;
  2264.                         }
  2265.  
  2266.                         if ((digitLeftCount + zeroDigitCount) < 1 ||
  2267.                             expDigits < 1) {
  2268.                             // Malformed exponential pattern
  2269.                             debug("Malformed exponential pattern")
  2270.                             status = U_ILLEGAL_ARGUMENT_ERROR;
  2271.                             return;
  2272.                         }
  2273.                     }
  2274.                     // Transition to suffix subpart
  2275.                     subpart = 2; // suffix subpart
  2276.                     affix = &suffix;
  2277.                     sub0Limit = pos--;
  2278.                     continue;
  2279.                 }
  2280.                 break;
  2281.             case 1: // Prefix subpart
  2282.             case 2: // Suffix subpart
  2283.                 // Process the prefix / suffix characters
  2284.                 // Process unquoted characters seen in prefix or suffix
  2285.                 // subpart.
  2286.                 if (ch == digit ||
  2287.                     ch == groupingSeparator ||
  2288.                     ch == decimalSeparator ||
  2289.                     (ch >= zeroDigit && ch <= nineDigit)) {
  2290.                     // Any of these characters implicitly begins the
  2291.                     // next subpart if we are in the prefix
  2292.                     if (subpart == 1) { // prefix subpart
  2293.                         subpart = 0; // pattern proper subpart
  2294.                         sub0Start = pos--; // Reprocess this character
  2295.                         continue;
  2296.                     }
  2297.                     // Fall through to append(ch)
  2298.                 } else if (ch == kCurrencySign) {
  2299.                     // Use lookahead to determine if the currency sign is
  2300.                     // doubled or not.
  2301.                     bool_t doubled = (pos + 1) < pattern.size() &&
  2302.                         pattern[(UTextOffset) (pos+1)] == kCurrencySign;
  2303.                     affix->append(kQuote); // Encode currency
  2304.                     if (doubled) {
  2305.                         affix->append(kCurrencySign);
  2306.                         ++pos; // Skip over the doubled character
  2307.                     }
  2308.                     isCurrency = TRUE;
  2309.                     // Fall through to append(ch)
  2310.                 } else if (ch == kQuote) {
  2311.                     // A quote outside quotes indicates either the opening
  2312.                     // quote or two quotes, which is a quote literal.  That is,
  2313.                     // we have the first quote in 'do' or o''clock.
  2314.                     if ((pos+1) < pattern.size() &&
  2315.                         pattern[(UTextOffset) (pos+1)] == kQuote) {
  2316.                         ++pos;
  2317.                         affix->append(kQuote); // Encode quote
  2318.                         // Fall through to append(ch)
  2319.                     } else {
  2320.                         subpart += 2; // open quote
  2321.                         continue;
  2322.                     }
  2323.                 } else if (ch == separator) {
  2324.                     // Don't allow separators in the prefix, and don't allow
  2325.                     // separators in the second pattern (part == 1).
  2326.                     if (subpart == 1 || part == 1) {
  2327.                         // Unexpected separator
  2328.                         debug("Unexpected separator")
  2329.                         status = U_ILLEGAL_ARGUMENT_ERROR;
  2330.                         return;
  2331.                     }
  2332.                     sub2Limit = pos;
  2333.                     isPartDone = TRUE; // Go to next part
  2334.                     break;
  2335.                 } else if (ch == percent || ch == perMill) {
  2336.                     // Next handle characters which are appended directly.
  2337.                     if (multiplier != 1) {
  2338.                         // Too many percent/perMill characters
  2339.                         debug("Too many percent/perMill characters")
  2340.                         status = U_ILLEGAL_ARGUMENT_ERROR;
  2341.                         return;
  2342.                     }
  2343.                     affix->append(kQuote); // Encode percent/perMill
  2344.                     if (ch == percent) {
  2345.                         multiplier = 100;
  2346.                         ch = kPatternPercent; // Use unlocalized pattern char
  2347.                     } else {
  2348.                         multiplier = 1000;
  2349.                         ch = kPatternPerMill; // Use unlocalized pattern char
  2350.                     }
  2351.                     // Fall through to append(ch)
  2352.                 } else if (ch == padEscape) {
  2353.                     if (padPos >= 0 ||               // Multiple pad specifiers
  2354.                         (pos+1) == pattern.size()) { // Nothing after padEscape
  2355.                         debug("Multiple pad specifiers")
  2356.                         status = U_ILLEGAL_ARGUMENT_ERROR;
  2357.                         return;
  2358.                     }
  2359.                     padPos = pos;
  2360.                     padChar = pattern[(UTextOffset) ++pos];
  2361.                     continue;
  2362.                 } else if (ch == minus) {
  2363.                     affix->append(kQuote); // Encode minus
  2364.                     ch = kPatternMinus;
  2365.                     // Fall through to append(ch)
  2366.                 } else if (ch == plus) {
  2367.                     affix->append(kQuote); // Encode plus
  2368.                     ch = kPatternPlus;
  2369.                     // Fall through to append(ch)
  2370.                 }
  2371.                 // Unquoted, non-special characters fall through to here, as
  2372.                 // well as other code which needs to append something to the
  2373.                 // affix.
  2374.                 affix->append(ch);
  2375.                 break;
  2376.             case 3: // Prefix subpart, in quote
  2377.             case 4: // Suffix subpart, in quote
  2378.                 // A quote within quotes indicates either the closing
  2379.                 // quote or two quotes, which is a quote literal.  That is,
  2380.                 // we have the second quote in 'do' or 'don''t'.
  2381.                 if (ch == kQuote) {
  2382.                     if ((pos+1) < pattern.size() &&
  2383.                         pattern[(UTextOffset) (pos+1)] == kQuote) {
  2384.                         ++pos;
  2385.                         affix->append(kQuote); // Encode quote
  2386.                         // Fall through to append(ch)
  2387.                     } else {
  2388.                         subpart -= 2; // close quote
  2389.                         continue;
  2390.                     }
  2391.                 }
  2392.                 affix->append(ch);
  2393.                 break;
  2394.             }
  2395.         }
  2396.  
  2397.         if (sub0Limit == 0) {
  2398.             sub0Limit = pattern.size();
  2399.         }
  2400.  
  2401.         if (sub2Limit == 0) {
  2402.             sub2Limit = pattern.size();
  2403.         }
  2404.  
  2405.         /* Handle patterns with no '0' pattern character.  These patterns
  2406.          * are legal, but must be recodified to make sense.  "##.###" ->
  2407.          * "#0.###".  ".###" -> ".0##".
  2408.          *
  2409.          * We allow patterns of the form "####" to produce a zeroDigitCount
  2410.          * of zero (got that?); although this seems like it might make it
  2411.          * possible for format() to produce empty strings, format() checks
  2412.          * for this condition and outputs a zero digit in this situation.
  2413.          * Having a zeroDigitCount of zero yields a minimum integer digits
  2414.          * of zero, which allows proper round-trip patterns.  We don't want
  2415.          * "#" to become "#0" when toPattern() is called (even though that's
  2416.          * what it really is, semantically).
  2417.          */
  2418.         if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
  2419.             // Handle "###.###" and "###." and ".###"
  2420.             int n = decimalPos;
  2421.             if (n == 0) ++n; // Handle ".###"
  2422.             digitRightCount = digitLeftCount - n;
  2423.             digitLeftCount = n - 1;
  2424.             zeroDigitCount = 1;
  2425.         }
  2426.  
  2427.         // Do syntax checking on the digits, decimal points, and quotes.
  2428.         if ((decimalPos < 0 && digitRightCount > 0) ||
  2429.             (decimalPos >= 0 &&
  2430.              (decimalPos < digitLeftCount ||
  2431.               decimalPos > (digitLeftCount + zeroDigitCount))) ||
  2432.             groupingCount == 0 ||
  2433.             subpart > 2) { // subpart > 2 == unmatched quote
  2434.             debug("Syntax error")
  2435.             status = U_ILLEGAL_ARGUMENT_ERROR;
  2436.             return;
  2437.         }
  2438.  
  2439.         // Make sure pad is at legal position before or after affix.
  2440.         if (padPos >= 0) {
  2441.             if (padPos == start) {
  2442.                 padPos = kPadBeforePrefix;
  2443.             } else if (padPos+2 == sub0Start) {
  2444.                 padPos = kPadAfterPrefix;
  2445.             } else if (padPos == sub0Limit) {
  2446.                 padPos = kPadBeforeSuffix;
  2447.             } else if (padPos+2 == sub2Limit) {
  2448.                 padPos = kPadAfterSuffix;
  2449.             } else {
  2450.                 // Illegal pad position
  2451.                 debug("Illegal pad position")
  2452.                 status = U_ILLEGAL_ARGUMENT_ERROR;
  2453.                 return;
  2454.             }
  2455.         }
  2456.  
  2457.         if (part == 0) {
  2458.             delete fPosPrefixPattern;
  2459.             delete fPosSuffixPattern;
  2460.             delete fNegPrefixPattern;
  2461.             delete fNegSuffixPattern;
  2462.             fPosPrefixPattern = new UnicodeString(prefix);
  2463.             fPosSuffixPattern = new UnicodeString(suffix);
  2464.             fNegPrefixPattern = 0;
  2465.             fNegSuffixPattern = 0;
  2466.  
  2467.             fUseExponentialNotation = (expDigits >= 0);
  2468.             if (fUseExponentialNotation) {
  2469.                 fMinExponentDigits = expDigits;
  2470.                 fExponentSignAlwaysShown = expSignAlways;
  2471.             }
  2472.             fIsCurrencyFormat = isCurrency;
  2473.             int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
  2474.             // The effectiveDecimalPos is the position the decimal is at or
  2475.             // would be at if there is no decimal.  Note that if
  2476.             // decimalPos<0, then digitTotalCount == digitLeftCount +
  2477.             // zeroDigitCount.
  2478.             int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
  2479.             setMinimumIntegerDigits(effectiveDecimalPos - digitLeftCount);
  2480.             setMaximumIntegerDigits(fUseExponentialNotation
  2481.                     ? digitLeftCount + getMinimumIntegerDigits()
  2482.                     : kDoubleIntegerDigits);
  2483.             setMaximumFractionDigits(decimalPos >= 0
  2484.                     ? (digitTotalCount - decimalPos) : 0);
  2485.             setMinimumFractionDigits(decimalPos >= 0
  2486.                     ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
  2487.             setGroupingUsed(groupingCount > 0);
  2488.             fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
  2489.             fMultiplier = multiplier;
  2490.             setDecimalSeparatorAlwaysShown(decimalPos == 0
  2491.                     || decimalPos == digitTotalCount);
  2492.             if (padPos >= 0) {
  2493.                 fPadPosition = (EPadPosition) padPos;
  2494.                 // To compute the format width, first set up sub0Limit -
  2495.                 // sub0Start.  Add in prefix/suffix length later.
  2496.  
  2497.                 // fFormatWidth = prefix.length() + suffix.length() +
  2498.                 //    sub0Limit - sub0Start;
  2499.                 fFormatWidth = sub0Limit - sub0Start;
  2500.                 fPad = padChar;
  2501.             } else {
  2502.                 fFormatWidth = 0;
  2503.             }
  2504.             if (roundingPos >= 0) {
  2505.                 roundingInc.fDecimalAt = effectiveDecimalPos - roundingPos;
  2506.                 if (fRoundingIncrement != NULL) {
  2507.                     *fRoundingIncrement = roundingInc;
  2508.                 } else {
  2509.                     fRoundingIncrement = new DigitList(roundingInc);
  2510.                 }
  2511.                 fRoundingDouble = fRoundingIncrement->getDouble();
  2512.                 fRoundingMode = kRoundHalfEven;
  2513.             } else {
  2514.                 setRoundingIncrement(0.0);
  2515.             }
  2516.         } else {
  2517.             fNegPrefixPattern = new UnicodeString(prefix);
  2518.             fNegSuffixPattern = new UnicodeString(suffix);
  2519.         }
  2520.     }
  2521.  
  2522.     if (pattern.size() == 0) {
  2523.         delete fNegPrefixPattern;
  2524.         delete fNegSuffixPattern;
  2525.         fNegPrefixPattern = NULL;
  2526.         fNegSuffixPattern = NULL;
  2527.         if (fPosPrefixPattern != NULL) {
  2528.             fPosPrefixPattern->remove();
  2529.         } else {
  2530.             fPosPrefixPattern = new UnicodeString();
  2531.         }
  2532.         if (fPosSuffixPattern != NULL) {
  2533.             fPosSuffixPattern->remove();
  2534.         } else {
  2535.             fPosSuffixPattern = new UnicodeString();
  2536.         }
  2537.  
  2538.         setMinimumIntegerDigits(0);
  2539.         setMaximumIntegerDigits(kDoubleIntegerDigits);
  2540.         setMinimumFractionDigits(0);
  2541.         setMaximumFractionDigits(kDoubleFractionDigits);
  2542.  
  2543.         fUseExponentialNotation = FALSE;
  2544.         fIsCurrencyFormat = FALSE;
  2545.         setGroupingUsed(FALSE);
  2546.         fGroupingSize = 0;
  2547.         fMultiplier = 1;
  2548.         setDecimalSeparatorAlwaysShown(FALSE);
  2549.         fFormatWidth = 0;
  2550.         setRoundingIncrement(0.0);
  2551.     }
  2552.  
  2553.     // If there was no negative pattern, or if the negative pattern is
  2554.     // identical to the positive pattern, then prepend the minus sign to the
  2555.     // positive pattern to form the negative pattern.
  2556.     if (fNegPrefixPattern == NULL ||
  2557.         (*fNegPrefixPattern == *fPosPrefixPattern
  2558.          && *fNegSuffixPattern == *fPosSuffixPattern)) {
  2559.         _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern);
  2560.         if (fNegPrefixPattern == NULL) {
  2561.             fNegPrefixPattern = new UnicodeString();
  2562.         } else {
  2563.             fNegPrefixPattern->remove();
  2564.         }
  2565.         fNegPrefixPattern->append(kQuote).append(kPatternMinus)
  2566.             .append(*fPosPrefixPattern);
  2567.     }
  2568. #ifdef DEBUG
  2569.     UnicodeString s;
  2570.     s.append("\"").append(pattern).append("\"->");
  2571.     debugout(s);
  2572. #endif
  2573.     expandAffixes();
  2574.     if (fFormatWidth > 0) {
  2575.         // Finish computing format width (see above)
  2576.         fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length();
  2577.     }
  2578. }
  2579.  
  2580. /**
  2581.  * Sets the maximum number of digits allowed in the integer portion of a
  2582.  * number. This override limits the integer digit count to 309.
  2583.  * @see NumberFormat#setMaximumIntegerDigits
  2584.  */
  2585. void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
  2586.     NumberFormat::setMaximumIntegerDigits(icu_min(newValue, kDoubleIntegerDigits));
  2587. }
  2588.  
  2589. /**
  2590.  * Sets the minimum number of digits allowed in the integer portion of a
  2591.  * number. This override limits the integer digit count to 309.
  2592.  * @see NumberFormat#setMinimumIntegerDigits
  2593.  */
  2594. void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
  2595.     NumberFormat::setMinimumIntegerDigits(icu_min(newValue, kDoubleIntegerDigits));
  2596. }
  2597.  
  2598. /**
  2599.  * Sets the maximum number of digits allowed in the fraction portion of a
  2600.  * number. This override limits the fraction digit count to 340.
  2601.  * @see NumberFormat#setMaximumFractionDigits
  2602.  */
  2603. void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
  2604.     NumberFormat::setMaximumFractionDigits(icu_min(newValue, kDoubleFractionDigits));
  2605. }
  2606.  
  2607. /**
  2608.  * Sets the minimum number of digits allowed in the fraction portion of a
  2609.  * number. This override limits the fraction digit count to 340.
  2610.  * @see NumberFormat#setMinimumFractionDigits
  2611.  */
  2612. void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
  2613.     NumberFormat::setMinimumFractionDigits(icu_min(newValue, kDoubleFractionDigits));
  2614. }
  2615.  
  2616. //eof
  2617.