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