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