2 *******************************************************************************
3 * Copyright (C) 1997-2009, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
9 * Modification History:
11 * Date Name Description
12 * 02/19/97 aliu Converted from java.
13 * 03/20/97 clhuang Implemented with new APIs.
14 * 03/31/97 aliu Moved isLONG_MIN to DigitList, and fixed it.
15 * 04/3/97 aliu Rewrote parsing and formatting completely, and
16 * cleaned up and debugged. Actually works now.
17 * Implemented NAN and INF handling, for both parsing
18 * and formatting. Extensive testing & debugging.
19 * 04/10/97 aliu Modified to compile on AIX.
20 * 04/16/97 aliu Rewrote to use DigitList, which has been resurrected.
21 * Changed DigitCount to int per code review.
22 * 07/09/97 helena Made ParsePosition into a class.
23 * 08/26/97 aliu Extensive changes to applyPattern; completely
24 * rewritten from the Java.
25 * 09/09/97 aliu Ported over support for exponential formats.
26 * 07/20/98 stephen JDK 1.2 sync up.
27 * Various instances of '0' replaced with 'NULL'
28 * Check for grouping size in subFormat()
29 * Brought subParse() in line with Java 1.2
30 * Added method appendAffix()
31 * 08/24/1998 srl Removed Mutex calls. This is not a thread safe class!
32 * 02/22/99 stephen Removed character literals for EBCDIC safety
33 * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes
34 * 06/28/99 stephen Fixed bugs in toPattern().
35 * 06/29/99 stephen Fixed operator= to copy fFormatWidth, fPad,
37 ********************************************************************************
40 #include "unicode/utypes.h"
42 #if !UCONFIG_NO_FORMATTING
44 #include "unicode/decimfmt.h"
45 #include "unicode/choicfmt.h"
46 #include "unicode/ucurr.h"
47 #include "unicode/ustring.h"
48 #include "unicode/dcfmtsym.h"
49 #include "unicode/ures.h"
50 #include "unicode/uchar.h"
51 #include "unicode/uniset.h"
52 #include "unicode/curramt.h"
69 static void debugout(UnicodeString s
) {
71 s
.extract((int32_t) 0, s
.length(), buf
);
74 #define debug(x) printf("%s\n", x);
80 // Set to 1 to make leading zeroes be an error
81 // when doing a strict parse.
82 #define CHECK_FOR_LEADING_ZERO 0
84 // Set to 1 to make misplaced grouping separators
85 // be an error when doing a strict parse.
86 #define CHECK_FOR_MISPLACED_GROUPING 0
88 // *****************************************************************************
89 // class DecimalFormat
90 // *****************************************************************************
92 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat
)
94 // Constants for characters used in programmatic (unlocalized) patterns.
95 #define kPatternZeroDigit ((UChar)0x0030) /*'0'*/
96 #define kPatternSignificantDigit ((UChar)0x0040) /*'@'*/
97 #define kPatternGroupingSeparator ((UChar)0x002C) /*','*/
98 #define kPatternDecimalSeparator ((UChar)0x002E) /*'.'*/
99 #define kPatternPerMill ((UChar)0x2030)
100 #define kPatternPercent ((UChar)0x0025) /*'%'*/
101 #define kPatternDigit ((UChar)0x0023) /*'#'*/
102 #define kPatternSeparator ((UChar)0x003B) /*';'*/
103 #define kPatternExponent ((UChar)0x0045) /*'E'*/
104 #define kPatternPlus ((UChar)0x002B) /*'+'*/
105 #define kPatternMinus ((UChar)0x002D) /*'-'*/
106 #define kPatternPadEscape ((UChar)0x002A) /*'*'*/
107 #define kQuote ((UChar)0x0027) /*'\''*/
109 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
110 * is used in patterns and substitued with either the currency symbol,
111 * or if it is doubled, with the international currency symbol. If the
112 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
113 * replaced with the monetary decimal separator.
115 #define kCurrencySign ((UChar)0x00A4)
116 #define kDefaultPad ((UChar)0x0020) /* */
118 const int32_t DecimalFormat::kDoubleIntegerDigits
= 309;
119 const int32_t DecimalFormat::kDoubleFractionDigits
= 340;
121 const int32_t DecimalFormat::kMaxScientificIntegerDigits
= 8;
124 * These are the tags we expect to see in normal resource bundle files associated
127 const char DecimalFormat::fgNumberPatterns
[]="NumberPatterns";
129 inline int32_t _min(int32_t a
, int32_t b
) { return (a
<b
) ? a
: b
; }
130 inline int32_t _max(int32_t a
, int32_t b
) { return (a
<b
) ? b
: a
; }
132 //------------------------------------------------------------------------------
133 // Constructs a DecimalFormat instance in the default locale.
135 DecimalFormat::DecimalFormat(UErrorCode
& status
)
137 fPosPrefixPattern(0),
138 fPosSuffixPattern(0),
139 fNegPrefixPattern(0),
140 fNegSuffixPattern(0),
146 fUseSignificantDigits(FALSE
),
147 fMinSignificantDigits(1),
148 fMaxSignificantDigits(6),
149 fMinExponentDigits(0),
150 fRoundingIncrement(0),
154 UParseError parseError
;
155 construct(status
, parseError
);
158 //------------------------------------------------------------------------------
159 // Constructs a DecimalFormat instance with the specified number format
160 // pattern in the default locale.
162 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
,
165 fPosPrefixPattern(0),
166 fPosSuffixPattern(0),
167 fNegPrefixPattern(0),
168 fNegSuffixPattern(0),
174 fUseSignificantDigits(FALSE
),
175 fMinSignificantDigits(1),
176 fMaxSignificantDigits(6),
177 fMinExponentDigits(0),
178 fRoundingIncrement(0),
182 UParseError parseError
;
183 construct(status
, parseError
, &pattern
);
186 //------------------------------------------------------------------------------
187 // Constructs a DecimalFormat instance with the specified number format
188 // pattern and the number format symbols in the default locale. The
189 // created instance owns the symbols.
191 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
,
192 DecimalFormatSymbols
* symbolsToAdopt
,
195 fPosPrefixPattern(0),
196 fPosSuffixPattern(0),
197 fNegPrefixPattern(0),
198 fNegSuffixPattern(0),
204 fUseSignificantDigits(FALSE
),
205 fMinSignificantDigits(1),
206 fMaxSignificantDigits(6),
207 fMinExponentDigits(0),
208 fRoundingIncrement(0),
212 UParseError parseError
;
213 if (symbolsToAdopt
== NULL
)
214 status
= U_ILLEGAL_ARGUMENT_ERROR
;
215 construct(status
, parseError
, &pattern
, symbolsToAdopt
);
218 DecimalFormat::DecimalFormat( const UnicodeString
& pattern
,
219 DecimalFormatSymbols
* symbolsToAdopt
,
220 UParseError
& parseErr
,
223 fPosPrefixPattern(0),
224 fPosSuffixPattern(0),
225 fNegPrefixPattern(0),
226 fNegSuffixPattern(0),
232 fUseSignificantDigits(FALSE
),
233 fMinSignificantDigits(1),
234 fMaxSignificantDigits(6),
235 fMinExponentDigits(0),
236 fRoundingIncrement(0),
240 if (symbolsToAdopt
== NULL
)
241 status
= U_ILLEGAL_ARGUMENT_ERROR
;
242 construct(status
,parseErr
, &pattern
, symbolsToAdopt
);
244 //------------------------------------------------------------------------------
245 // Constructs a DecimalFormat instance with the specified number format
246 // pattern and the number format symbols in the default locale. The
247 // created instance owns the clone of the symbols.
249 DecimalFormat::DecimalFormat(const UnicodeString
& pattern
,
250 const DecimalFormatSymbols
& symbols
,
253 fPosPrefixPattern(0),
254 fPosSuffixPattern(0),
255 fNegPrefixPattern(0),
256 fNegSuffixPattern(0),
262 fUseSignificantDigits(FALSE
),
263 fMinSignificantDigits(1),
264 fMaxSignificantDigits(6),
265 fMinExponentDigits(0),
266 fRoundingIncrement(0),
270 UParseError parseError
;
271 construct(status
, parseError
, &pattern
, new DecimalFormatSymbols(symbols
));
274 //------------------------------------------------------------------------------
275 // Constructs a DecimalFormat instance with the specified number format
276 // pattern and the number format symbols in the desired locale. The
277 // created instance owns the symbols.
280 DecimalFormat::construct(UErrorCode
& status
,
281 UParseError
& parseErr
,
282 const UnicodeString
* pattern
,
283 DecimalFormatSymbols
* symbolsToAdopt
)
285 fSymbols
= symbolsToAdopt
; // Do this BEFORE aborting on status failure!!!
286 // fDigitList = new DigitList(); // Do this BEFORE aborting on status failure!!!
287 fRoundingIncrement
= NULL
;
288 fRoundingDouble
= 0.0;
289 fRoundingMode
= kRoundHalfEven
;
290 fPad
= kPatternPadEscape
;
291 fPadPosition
= kPadBeforePrefix
;
292 if (U_FAILURE(status
))
295 fPosPrefixPattern
= fPosSuffixPattern
= NULL
;
296 fNegPrefixPattern
= fNegSuffixPattern
= NULL
;
300 fDecimalSeparatorAlwaysShown
= FALSE
;
301 fIsCurrencyFormat
= FALSE
;
302 fUseExponentialNotation
= FALSE
;
303 fMinExponentDigits
= 0;
305 if (fSymbols
== NULL
)
307 fSymbols
= new DecimalFormatSymbols(Locale::getDefault(), status
);
310 status
= U_MEMORY_ALLOCATION_ERROR
;
316 // Uses the default locale's number format pattern if there isn't
321 UResourceBundle
*resource
= ures_open(NULL
, Locale::getDefault().getName(), &status
);
323 resource
= ures_getByKey(resource
, fgNumberPatterns
, resource
, &status
);
324 const UChar
*resStr
= ures_getStringByIndex(resource
, (int32_t)0, &len
, &status
);
325 str
.setTo(TRUE
, resStr
, len
);
327 ures_close(resource
);
330 if (U_FAILURE(status
))
335 if (pattern
->indexOf((UChar
)kCurrencySign
) >= 0) {
336 // If it looks like we are going to use a currency pattern
337 // then do the time consuming lookup.
338 setCurrencyForSymbols();
340 setCurrency(NULL
, status
);
343 applyPattern(*pattern
, FALSE
/*not localized*/,parseErr
, status
);
345 // If it was a currency format, apply the appropriate rounding by
346 // resetting the currency. NOTE: this copies fCurrency on top of itself.
347 if (fIsCurrencyFormat
) {
348 setCurrency(getCurrency(), status
);
352 //------------------------------------------------------------------------------
354 DecimalFormat::~DecimalFormat()
356 // delete fDigitList;
357 delete fPosPrefixPattern
;
358 delete fPosSuffixPattern
;
359 delete fNegPrefixPattern
;
360 delete fNegSuffixPattern
;
361 delete fCurrencyChoice
;
363 delete fRoundingIncrement
;
366 //------------------------------------------------------------------------------
369 DecimalFormat::DecimalFormat(const DecimalFormat
&source
)
370 : NumberFormat(source
),
372 fPosPrefixPattern(NULL
),
373 fPosSuffixPattern(NULL
),
374 fNegPrefixPattern(NULL
),
375 fNegSuffixPattern(NULL
),
376 fCurrencyChoice(NULL
),
378 fRoundingIncrement(NULL
)
383 //------------------------------------------------------------------------------
384 // assignment operator
385 // Note that fDigitList is not considered a significant part of the
386 // DecimalFormat because it's used as a buffer to process the numbers.
388 static void _copy_us_ptr(UnicodeString
** pdest
, const UnicodeString
* source
) {
389 if (source
== NULL
) {
392 } else if (*pdest
== NULL
) {
393 *pdest
= new UnicodeString(*source
);
400 DecimalFormat::operator=(const DecimalFormat
& rhs
)
403 NumberFormat::operator=(rhs
);
404 fPositivePrefix
= rhs
.fPositivePrefix
;
405 fPositiveSuffix
= rhs
.fPositiveSuffix
;
406 fNegativePrefix
= rhs
.fNegativePrefix
;
407 fNegativeSuffix
= rhs
.fNegativeSuffix
;
408 _copy_us_ptr(&fPosPrefixPattern
, rhs
.fPosPrefixPattern
);
409 _copy_us_ptr(&fPosSuffixPattern
, rhs
.fPosSuffixPattern
);
410 _copy_us_ptr(&fNegPrefixPattern
, rhs
.fNegPrefixPattern
);
411 _copy_us_ptr(&fNegSuffixPattern
, rhs
.fNegSuffixPattern
);
412 if (rhs
.fCurrencyChoice
== 0) {
413 delete fCurrencyChoice
;
416 fCurrencyChoice
= (ChoiceFormat
*) rhs
.fCurrencyChoice
->clone();
418 if(rhs
.fRoundingIncrement
== NULL
) {
419 delete fRoundingIncrement
;
420 fRoundingIncrement
= NULL
;
422 else if(fRoundingIncrement
== NULL
) {
423 fRoundingIncrement
= new DigitList(*rhs
.fRoundingIncrement
);
426 *fRoundingIncrement
= *rhs
.fRoundingIncrement
;
428 fRoundingDouble
= rhs
.fRoundingDouble
;
429 fRoundingMode
= rhs
.fRoundingMode
;
430 fMultiplier
= rhs
.fMultiplier
;
431 fGroupingSize
= rhs
.fGroupingSize
;
432 fGroupingSize2
= rhs
.fGroupingSize2
;
433 fDecimalSeparatorAlwaysShown
= rhs
.fDecimalSeparatorAlwaysShown
;
434 if(fSymbols
== NULL
) {
435 fSymbols
= new DecimalFormatSymbols(*rhs
.fSymbols
);
437 *fSymbols
= *rhs
.fSymbols
;
439 fUseExponentialNotation
= rhs
.fUseExponentialNotation
;
440 fExponentSignAlwaysShown
= rhs
.fExponentSignAlwaysShown
;
441 /*Bertrand A. D. Update 98.03.17*/
442 fIsCurrencyFormat
= rhs
.fIsCurrencyFormat
;
444 fMinExponentDigits
= rhs
.fMinExponentDigits
;
445 // if (fDigitList == NULL)
446 // fDigitList = new DigitList();
449 fFormatWidth
= rhs
.fFormatWidth
;
451 fPadPosition
= rhs
.fPadPosition
;
453 fMinSignificantDigits
= rhs
.fMinSignificantDigits
;
454 fMaxSignificantDigits
= rhs
.fMaxSignificantDigits
;
455 fUseSignificantDigits
= rhs
.fUseSignificantDigits
;
460 //------------------------------------------------------------------------------
463 DecimalFormat::operator==(const Format
& that
) const
468 // NumberFormat::operator== guarantees this cast is safe
469 const DecimalFormat
* other
= (DecimalFormat
*)&that
;
472 // This code makes it easy to determine why two format objects that should
475 if (!NumberFormat::operator==(that
)) {
476 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
477 debug("NumberFormat::!=");
479 if (!((fPosPrefixPattern
== other
->fPosPrefixPattern
&& // both null
480 fPositivePrefix
== other
->fPositivePrefix
)
481 || (fPosPrefixPattern
!= 0 && other
->fPosPrefixPattern
!= 0 &&
482 *fPosPrefixPattern
== *other
->fPosPrefixPattern
))) {
483 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
484 debug("Pos Prefix !=");
486 if (!((fPosSuffixPattern
== other
->fPosSuffixPattern
&& // both null
487 fPositiveSuffix
== other
->fPositiveSuffix
)
488 || (fPosSuffixPattern
!= 0 && other
->fPosSuffixPattern
!= 0 &&
489 *fPosSuffixPattern
== *other
->fPosSuffixPattern
))) {
490 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
491 debug("Pos Suffix !=");
493 if (!((fNegPrefixPattern
== other
->fNegPrefixPattern
&& // both null
494 fNegativePrefix
== other
->fNegativePrefix
)
495 || (fNegPrefixPattern
!= 0 && other
->fNegPrefixPattern
!= 0 &&
496 *fNegPrefixPattern
== *other
->fNegPrefixPattern
))) {
497 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
498 debug("Neg Prefix ");
499 if (fNegPrefixPattern
== NULL
) {
501 debugout(fNegativePrefix
);
504 debugout(*fNegPrefixPattern
);
507 if (other
->fNegPrefixPattern
== NULL
) {
509 debugout(other
->fNegativePrefix
);
512 debugout(*other
->fNegPrefixPattern
);
515 if (!((fNegSuffixPattern
== other
->fNegSuffixPattern
&& // both null
516 fNegativeSuffix
== other
->fNegativeSuffix
)
517 || (fNegSuffixPattern
!= 0 && other
->fNegSuffixPattern
!= 0 &&
518 *fNegSuffixPattern
== *other
->fNegSuffixPattern
))) {
519 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
520 debug("Neg Suffix ");
521 if (fNegSuffixPattern
== NULL
) {
523 debugout(fNegativeSuffix
);
526 debugout(*fNegSuffixPattern
);
529 if (other
->fNegSuffixPattern
== NULL
) {
531 debugout(other
->fNegativeSuffix
);
534 debugout(*other
->fNegSuffixPattern
);
537 if (!((fRoundingIncrement
== other
->fRoundingIncrement
) // both null
538 || (fRoundingIncrement
!= NULL
&&
539 other
->fRoundingIncrement
!= NULL
&&
540 *fRoundingIncrement
== *other
->fRoundingIncrement
))) {
541 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
542 debug("Rounding Increment !=");
544 if (fMultiplier
!= other
->fMultiplier
) {
545 if (first
) { printf("[ "); first
= FALSE
; }
546 printf("Multiplier %ld != %ld", fMultiplier
, other
->fMultiplier
);
548 if (fGroupingSize
!= other
->fGroupingSize
) {
549 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
550 printf("Grouping Size %ld != %ld", fGroupingSize
, other
->fGroupingSize
);
552 if (fGroupingSize2
!= other
->fGroupingSize2
) {
553 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
554 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2
, other
->fGroupingSize2
);
556 if (fDecimalSeparatorAlwaysShown
!= other
->fDecimalSeparatorAlwaysShown
) {
557 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
558 printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown
, other
->fDecimalSeparatorAlwaysShown
);
560 if (fUseExponentialNotation
!= other
->fUseExponentialNotation
) {
561 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
564 if (!(!fUseExponentialNotation
||
565 fMinExponentDigits
!= other
->fMinExponentDigits
)) {
566 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
567 debug("Exp Digits !=");
569 if (*fSymbols
!= *(other
->fSymbols
)) {
570 if (first
) { printf("[ "); first
= FALSE
; } else { printf(", "); }
573 // TODO Add debug stuff for significant digits here
574 if (!first
) { printf(" ]"); }
577 return (NumberFormat::operator==(that
) &&
578 ((fPosPrefixPattern
== other
->fPosPrefixPattern
&& // both null
579 fPositivePrefix
== other
->fPositivePrefix
)
580 || (fPosPrefixPattern
!= 0 && other
->fPosPrefixPattern
!= 0 &&
581 *fPosPrefixPattern
== *other
->fPosPrefixPattern
)) &&
582 ((fPosSuffixPattern
== other
->fPosSuffixPattern
&& // both null
583 fPositiveSuffix
== other
->fPositiveSuffix
)
584 || (fPosSuffixPattern
!= 0 && other
->fPosSuffixPattern
!= 0 &&
585 *fPosSuffixPattern
== *other
->fPosSuffixPattern
)) &&
586 ((fNegPrefixPattern
== other
->fNegPrefixPattern
&& // both null
587 fNegativePrefix
== other
->fNegativePrefix
)
588 || (fNegPrefixPattern
!= 0 && other
->fNegPrefixPattern
!= 0 &&
589 *fNegPrefixPattern
== *other
->fNegPrefixPattern
)) &&
590 ((fNegSuffixPattern
== other
->fNegSuffixPattern
&& // both null
591 fNegativeSuffix
== other
->fNegativeSuffix
)
592 || (fNegSuffixPattern
!= 0 && other
->fNegSuffixPattern
!= 0 &&
593 *fNegSuffixPattern
== *other
->fNegSuffixPattern
)) &&
594 ((fRoundingIncrement
== other
->fRoundingIncrement
) // both null
595 || (fRoundingIncrement
!= NULL
&&
596 other
->fRoundingIncrement
!= NULL
&&
597 *fRoundingIncrement
== *other
->fRoundingIncrement
)) &&
598 fMultiplier
== other
->fMultiplier
&&
599 fGroupingSize
== other
->fGroupingSize
&&
600 fGroupingSize2
== other
->fGroupingSize2
&&
601 fDecimalSeparatorAlwaysShown
== other
->fDecimalSeparatorAlwaysShown
&&
602 fUseExponentialNotation
== other
->fUseExponentialNotation
&&
603 (!fUseExponentialNotation
||
604 fMinExponentDigits
== other
->fMinExponentDigits
) &&
605 *fSymbols
== *(other
->fSymbols
) &&
606 fUseSignificantDigits
== other
->fUseSignificantDigits
&&
607 (!fUseSignificantDigits
||
608 (fMinSignificantDigits
== other
->fMinSignificantDigits
&&
609 fMaxSignificantDigits
== other
->fMaxSignificantDigits
)));
612 //------------------------------------------------------------------------------
615 DecimalFormat::clone() const
617 return new DecimalFormat(*this);
620 //------------------------------------------------------------------------------
623 DecimalFormat::format(int32_t number
,
624 UnicodeString
& appendTo
,
625 FieldPosition
& fieldPosition
) const
627 return format((int64_t)number
, appendTo
, fieldPosition
);
630 //------------------------------------------------------------------------------
633 DecimalFormat::format(int64_t number
,
634 UnicodeString
& appendTo
,
635 FieldPosition
& fieldPosition
) const
639 // Clears field positions.
640 fieldPosition
.setBeginIndex(0);
641 fieldPosition
.setEndIndex(0);
643 // If we are to do rounding, we need to move into the BigDecimal
644 // domain in order to do divide/multiply correctly.
646 // In general, long values always represent real finite numbers, so
647 // we don't have to check for +/- Infinity or NaN. However, there
648 // is one case we have to be careful of: The multiplier can push
649 // a number near MIN_VALUE or MAX_VALUE outside the legal range. We
650 // check for this before multiplying, and if it happens we use doubles
651 // instead, trading off accuracy for range.
652 if (fRoundingIncrement
!= NULL
653 || (fMultiplier
> 0 && (number
> U_INT64_MAX
/ fMultiplier
|| number
< U_INT64_MIN
/ fMultiplier
))
654 || (fMultiplier
< 0 && (number
== U_INT64_MIN
|| -number
> U_INT64_MAX
/ -fMultiplier
|| -number
< U_INT64_MIN
/ -fMultiplier
))
657 digits
.set(((double) number
) * fMultiplier
,
659 !fUseExponentialNotation
&& !areSignificantDigitsUsed());
663 digits
.set(number
* fMultiplier
, precision(TRUE
));
666 return subformat(appendTo
, fieldPosition
, digits
, TRUE
);
669 //------------------------------------------------------------------------------
672 DecimalFormat::format( double number
,
673 UnicodeString
& appendTo
,
674 FieldPosition
& fieldPosition
) const
676 // Clears field positions.
677 fieldPosition
.setBeginIndex(0);
678 fieldPosition
.setEndIndex(0);
680 // Special case for NaN, sets the begin and end index to be the
681 // the string length of localized name of NaN.
682 if (uprv_isNaN(number
))
684 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
685 fieldPosition
.setBeginIndex(appendTo
.length());
687 appendTo
+= getConstSymbol(DecimalFormatSymbols::kNaNSymbol
);
689 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
690 fieldPosition
.setEndIndex(appendTo
.length());
692 addPadding(appendTo
, fieldPosition
, 0, 0);
696 // Do this BEFORE checking to see if value is infinite or negative! Sets the
697 // begin and end index to be length of the string composed of
698 // localized name of Infinite and the positive/negative localized
701 number
*= fMultiplier
;
703 /* Detecting whether a double is negative is easy with the exception of
704 * the value -0.0. This is a double which has a zero mantissa (and
705 * exponent), but a negative sign bit. It is semantically distinct from
706 * a zero with a positive sign bit, and this distinction is important
707 * to certain kinds of computations. However, it's a little tricky to
708 * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0). How then, you may
709 * ask, does it behave distinctly from +0.0? Well, 1/(-0.0) ==
710 * -Infinity. Proper detection of -0.0 is needed to deal with the
711 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
713 UBool isNegative
= uprv_isNegative(number
);
715 // Apply rounding after multiplier
716 if (fRoundingIncrement
!= NULL
) {
717 if (isNegative
) // For rounding in the correct direction
719 number
= fRoundingDouble
720 * round(number
/ fRoundingDouble
, fRoundingMode
, isNegative
);
725 // Special case for INFINITE,
726 if (uprv_isInfinite(number
))
728 int32_t prefixLen
= appendAffix(appendTo
, number
, isNegative
, TRUE
);
730 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
731 fieldPosition
.setBeginIndex(appendTo
.length());
733 appendTo
+= getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
);
735 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
736 fieldPosition
.setEndIndex(appendTo
.length());
738 int32_t suffixLen
= appendAffix(appendTo
, number
, isNegative
, FALSE
);
740 addPadding(appendTo
, fieldPosition
, prefixLen
, suffixLen
);
746 // This detects negativity too.
747 if (fRoundingIncrement
== NULL
) {
748 // If we did not round in binary space, round in decimal space
749 digits
.fRoundingMode
= fRoundingMode
;
751 digits
.set(number
, precision(FALSE
),
752 !fUseExponentialNotation
&& !areSignificantDigitsUsed());
754 return subformat(appendTo
, fieldPosition
, digits
, FALSE
);
758 * Round a double value to the nearest integer according to the
760 * @param a the absolute value of the number to be rounded
761 * @param mode a BigDecimal rounding mode
762 * @param isNegative true if the number to be rounded is negative
763 * @return the absolute value of the rounded result
765 double DecimalFormat::round(double a
, ERoundingMode mode
, UBool isNegative
) {
768 return isNegative
? uprv_floor(a
) : uprv_ceil(a
);
770 return isNegative
? uprv_ceil(a
) : uprv_floor(a
);
772 return uprv_floor(a
);
777 double f
= uprv_floor(a
);
778 if ((a
- f
) != 0.5) {
779 return uprv_floor(a
+ 0.5);
782 return (g
== uprv_floor(g
)) ? f
: (f
+ 1.0);
785 return ((a
- uprv_floor(a
)) <= 0.5) ? uprv_floor(a
) : uprv_ceil(a
);
787 return ((a
- uprv_floor(a
)) < 0.5) ? uprv_floor(a
) : uprv_ceil(a
);
793 DecimalFormat::format( const Formattable
& obj
,
794 UnicodeString
& appendTo
,
795 FieldPosition
& fieldPosition
,
796 UErrorCode
& status
) const
798 return NumberFormat::format(obj
, appendTo
, fieldPosition
, status
);
802 * Return true if a grouping separator belongs at the given
803 * position, based on whether grouping is in use and the values of
804 * the primary and secondary grouping interval.
805 * @param pos the number of integer digits to the right of
806 * the current position. Zero indicates the position after the
807 * rightmost integer digit.
808 * @return true if a grouping character belongs at the current
811 UBool
DecimalFormat::isGroupingPosition(int32_t pos
) const {
812 UBool result
= FALSE
;
813 if (isGroupingUsed() && (pos
> 0) && (fGroupingSize
> 0)) {
814 if ((fGroupingSize2
> 0) && (pos
> fGroupingSize
)) {
815 result
= ((pos
- fGroupingSize
) % fGroupingSize2
) == 0;
817 result
= pos
% fGroupingSize
== 0;
823 //------------------------------------------------------------------------------
826 * Complete the formatting of a finite number. On entry, the fDigitList must
827 * be filled in with the correct digits.
830 DecimalFormat::subformat(UnicodeString
& appendTo
,
831 FieldPosition
& fieldPosition
,
833 UBool isInteger
) const
835 // Gets the localized zero Unicode character.
836 UChar32 zero
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
837 int32_t zeroDelta
= zero
- '0'; // '0' is the DigitList representation of zero
838 const UnicodeString
*grouping
;
839 if(fIsCurrencyFormat
) {
840 grouping
= &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol
);
842 grouping
= &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
);
844 const UnicodeString
*decimal
;
845 if(fIsCurrencyFormat
) {
846 decimal
= &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
848 decimal
= &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
850 UBool useSigDig
= areSignificantDigitsUsed();
851 int32_t maxIntDig
= getMaximumIntegerDigits();
852 int32_t minIntDig
= getMinimumIntegerDigits();
854 /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
855 * format as zero. This allows sensible computations and preserves
856 * relations such as signum(1/x) = signum(x), where x is +Infinity or
857 * -Infinity. Prior to this fix, we always formatted zero values as if
858 * they were positive. Liu 7/6/98.
862 digits
.fDecimalAt
= digits
.fCount
= 0; // Normalize
865 // Appends the prefix.
866 double doubleValue
= digits
.getDouble();
867 int32_t prefixLen
= appendAffix(appendTo
, doubleValue
, !digits
.fIsPositive
, TRUE
);
869 if (fUseExponentialNotation
)
871 // Record field information for caller.
872 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
874 fieldPosition
.setBeginIndex(appendTo
.length());
875 fieldPosition
.setEndIndex(-1);
877 else if (fieldPosition
.getField() == NumberFormat::kFractionField
)
879 fieldPosition
.setBeginIndex(-1);
882 int32_t minFracDig
= 0;
884 maxIntDig
= minIntDig
= 1;
885 minFracDig
= getMinimumSignificantDigits() - 1;
887 minFracDig
= getMinimumFractionDigits();
888 if (maxIntDig
> kMaxScientificIntegerDigits
) {
890 if (maxIntDig
< minIntDig
) {
891 maxIntDig
= minIntDig
;
894 if (maxIntDig
> minIntDig
) {
899 // Minimum integer digits are handled in exponential format by
900 // adjusting the exponent. For example, 0.01234 with 3 minimum
901 // integer digits is "123.4E-4".
903 // Maximum integer digits are interpreted as indicating the
904 // repeating range. This is useful for engineering notation, in
905 // which the exponent is restricted to a multiple of 3. For
906 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
907 // If maximum integer digits are defined and are larger than
908 // minimum integer digits, then minimum integer digits are
910 int32_t exponent
= digits
.fDecimalAt
;
911 if (maxIntDig
> 1 && maxIntDig
!= minIntDig
) {
912 // A exponent increment is defined; adjust to it.
913 exponent
= (exponent
> 0) ? (exponent
- 1) / maxIntDig
914 : (exponent
/ maxIntDig
) - 1;
915 exponent
*= maxIntDig
;
917 // No exponent increment is defined; use minimum integer digits.
918 // If none is specified, as in "#E0", generate 1 integer digit.
919 exponent
-= (minIntDig
> 0 || minFracDig
> 0)
923 // We now output a minimum number of digits, and more if there
924 // are more digits, up to the maximum number of digits. We
925 // place the decimal point after the "integer" digits, which
926 // are the first (decimalAt - exponent) digits.
927 int32_t minimumDigits
= minIntDig
+ minFracDig
;
928 // The number of integer digits is handled specially if the number
929 // is zero, since then there may be no digits.
930 int32_t integerDigits
= digits
.isZero() ? minIntDig
:
931 digits
.fDecimalAt
- exponent
;
932 int32_t totalDigits
= digits
.fCount
;
933 if (minimumDigits
> totalDigits
)
934 totalDigits
= minimumDigits
;
935 if (integerDigits
> totalDigits
)
936 totalDigits
= integerDigits
;
938 // totalDigits records total number of digits needs to be processed
940 for (i
=0; i
<totalDigits
; ++i
)
942 if (i
== integerDigits
)
944 // Record field information for caller.
945 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
946 fieldPosition
.setEndIndex(appendTo
.length());
948 appendTo
+= *decimal
;
950 // Record field information for caller.
951 if (fieldPosition
.getField() == NumberFormat::kFractionField
)
952 fieldPosition
.setBeginIndex(appendTo
.length());
954 // Restores the digit character or pads the buffer with zeros.
955 UChar32 c
= (UChar32
)((i
< digits
.fCount
) ?
956 (digits
.fDigits
[i
] + zeroDelta
) :
961 // Record field information
962 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
964 if (fieldPosition
.getEndIndex() < 0)
965 fieldPosition
.setEndIndex(appendTo
.length());
967 else if (fieldPosition
.getField() == NumberFormat::kFractionField
)
969 if (fieldPosition
.getBeginIndex() < 0)
970 fieldPosition
.setBeginIndex(appendTo
.length());
971 fieldPosition
.setEndIndex(appendTo
.length());
974 // The exponent is output using the pattern-specified minimum
975 // exponent digits. There is no maximum limit to the exponent
976 // digits, since truncating the exponent would appendTo in an
977 // unacceptable inaccuracy.
978 appendTo
+= getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
);
980 // For zero values, we force the exponent to zero. We
981 // must do this here, and not earlier, because the value
982 // is used to determine integer digit count above.
987 appendTo
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
988 } else if (fExponentSignAlwaysShown
) {
989 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
993 expDigits
.set(exponent
);
995 int expDig
= fMinExponentDigits
;
996 if (fUseExponentialNotation
&& expDig
< 1) {
999 for (i
=expDigits
.fDecimalAt
; i
<expDig
; ++i
)
1002 for (i
=0; i
<expDigits
.fDecimalAt
; ++i
)
1004 UChar32 c
= (UChar32
)((i
< expDigits
.fCount
) ?
1005 (expDigits
.fDigits
[i
] + zeroDelta
) : zero
);
1009 else // Not using exponential notation
1011 // Record field information for caller.
1012 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
1013 fieldPosition
.setBeginIndex(appendTo
.length());
1015 int32_t sigCount
= 0;
1016 int32_t minSigDig
= getMinimumSignificantDigits();
1017 int32_t maxSigDig
= getMaximumSignificantDigits();
1020 maxSigDig
= INT32_MAX
;
1023 // Output the integer portion. Here 'count' is the total
1024 // number of integer digits we will display, including both
1025 // leading zeros required to satisfy getMinimumIntegerDigits,
1026 // and actual digits present in the number.
1027 int32_t count
= useSigDig
?
1028 _max(1, digits
.fDecimalAt
) : minIntDig
;
1029 if (digits
.fDecimalAt
> 0 && count
< digits
.fDecimalAt
) {
1030 count
= digits
.fDecimalAt
;
1033 // Handle the case where getMaximumIntegerDigits() is smaller
1034 // than the real number of integer digits. If this is so, we
1035 // output the least significant max integer digits. For example,
1036 // the value 1997 printed with 2 max integer digits is just "97".
1038 int32_t digitIndex
= 0; // Index into digitList.fDigits[]
1039 if (count
> maxIntDig
&& maxIntDig
>= 0) {
1041 digitIndex
= digits
.fDecimalAt
- count
;
1044 int32_t sizeBeforeIntegerPart
= appendTo
.length();
1047 for (i
=count
-1; i
>=0; --i
)
1049 if (i
< digits
.fDecimalAt
&& digitIndex
< digits
.fCount
&&
1050 sigCount
< maxSigDig
) {
1051 // Output a real digit
1052 appendTo
+= ((UChar32
)(digits
.fDigits
[digitIndex
++] + zeroDelta
));
1057 // Output a zero (leading or trailing)
1064 // Output grouping separator if necessary.
1065 if (isGroupingPosition(i
)) {
1066 appendTo
.append(*grouping
);
1070 // Record field information for caller.
1071 if (fieldPosition
.getField() == NumberFormat::kIntegerField
)
1072 fieldPosition
.setEndIndex(appendTo
.length());
1074 // Determine whether or not there are any printable fractional
1075 // digits. If we've used up the digits we know there aren't.
1076 UBool fractionPresent
= (!isInteger
&& digitIndex
< digits
.fCount
) ||
1077 (useSigDig
? (sigCount
< minSigDig
) : (getMinimumFractionDigits() > 0));
1079 // If there is no fraction present, and we haven't printed any
1080 // integer digits, then print a zero. Otherwise we won't print
1081 // _any_ digits, and we won't be able to parse this string.
1082 if (!fractionPresent
&& appendTo
.length() == sizeBeforeIntegerPart
)
1085 // Output the decimal separator if we always do so.
1086 if (fDecimalSeparatorAlwaysShown
|| fractionPresent
)
1087 appendTo
+= *decimal
;
1089 // Record field information for caller.
1090 if (fieldPosition
.getField() == NumberFormat::kFractionField
)
1091 fieldPosition
.setBeginIndex(appendTo
.length());
1093 count
= useSigDig
? INT32_MAX
: getMaximumFractionDigits();
1094 if (useSigDig
&& (sigCount
== maxSigDig
||
1095 (sigCount
>= minSigDig
&& digitIndex
== digits
.fCount
))) {
1099 for (i
=0; i
< count
; ++i
) {
1100 // Here is where we escape from the loop. We escape
1101 // if we've output the maximum fraction digits
1102 // (specified in the for expression above). We also
1103 // stop when we've output the minimum digits and
1104 // either: we have an integer, so there is no
1105 // fractional stuff to display, or we're out of
1106 // significant digits.
1107 if (!useSigDig
&& i
>= getMinimumFractionDigits() &&
1108 (isInteger
|| digitIndex
>= digits
.fCount
)) {
1112 // Output leading fractional zeros. These are zeros
1113 // that come after the decimal but before any
1114 // significant digits. These are only output if
1115 // abs(number being formatted) < 1.0.
1116 if (-1-i
> (digits
.fDecimalAt
-1)) {
1121 // Output a digit, if we have any precision left, or a
1122 // zero if we don't. We don't want to output noise digits.
1123 if (!isInteger
&& digitIndex
< digits
.fCount
) {
1124 appendTo
+= ((UChar32
)(digits
.fDigits
[digitIndex
++] + zeroDelta
));
1129 // If we reach the maximum number of significant
1130 // digits, or if we output all the real digits and
1131 // reach the minimum, then we are done.
1134 (sigCount
== maxSigDig
||
1135 (digitIndex
== digits
.fCount
&& sigCount
>= minSigDig
))) {
1140 // Record field information for caller.
1141 if (fieldPosition
.getField() == NumberFormat::kFractionField
)
1142 fieldPosition
.setEndIndex(appendTo
.length());
1145 int32_t suffixLen
= appendAffix(appendTo
, doubleValue
, !digits
.fIsPositive
, FALSE
);
1147 addPadding(appendTo
, fieldPosition
, prefixLen
, suffixLen
);
1152 * Inserts the character fPad as needed to expand result to fFormatWidth.
1153 * @param result the string to be padded
1155 void DecimalFormat::addPadding(UnicodeString
& appendTo
,
1156 FieldPosition
& fieldPosition
,
1158 int32_t suffixLen
) const
1160 if (fFormatWidth
> 0) {
1161 int32_t len
= fFormatWidth
- appendTo
.length();
1163 UnicodeString padding
;
1164 for (int32_t i
=0; i
<len
; ++i
) {
1167 switch (fPadPosition
) {
1168 case kPadAfterPrefix
:
1169 appendTo
.insert(prefixLen
, padding
);
1171 case kPadBeforePrefix
:
1172 appendTo
.insert(0, padding
);
1174 case kPadBeforeSuffix
:
1175 appendTo
.insert(appendTo
.length() - suffixLen
, padding
);
1177 case kPadAfterSuffix
:
1178 appendTo
+= padding
;
1181 if (fPadPosition
== kPadBeforePrefix
||
1182 fPadPosition
== kPadAfterPrefix
) {
1183 fieldPosition
.setBeginIndex(len
+ fieldPosition
.getBeginIndex());
1184 fieldPosition
.setEndIndex(len
+ fieldPosition
.getEndIndex());
1190 //------------------------------------------------------------------------------
1193 DecimalFormat::parse(const UnicodeString
& text
,
1194 Formattable
& result
,
1195 UErrorCode
& status
) const
1197 NumberFormat::parse(text
, result
, status
);
1201 DecimalFormat::parse(const UnicodeString
& text
,
1202 Formattable
& result
,
1203 ParsePosition
& parsePosition
) const {
1204 parse(text
, result
, parsePosition
, FALSE
);
1207 Formattable
& DecimalFormat::parseCurrency(const UnicodeString
& text
,
1208 Formattable
& result
,
1209 ParsePosition
& pos
) const {
1210 parse(text
, result
, pos
, TRUE
);
1215 * Parses the given text as either a number or a currency amount.
1216 * @param text the string to parse
1217 * @param result output parameter for the result
1218 * @param parsePosition input-output position; on input, the
1219 * position within text to match; must have 0 <= pos.getIndex() <
1220 * text.length(); on output, the position after the last matched
1221 * character. If the parse fails, the position in unchanged upon
1223 * @param parseCurrency if true, a currency amount is parsed;
1224 * otherwise a Number is parsed
1226 void DecimalFormat::parse(const UnicodeString
& text
,
1227 Formattable
& result
,
1228 ParsePosition
& parsePosition
,
1229 UBool parseCurrency
) const {
1231 int32_t i
= backup
= parsePosition
.getIndex();
1233 // Handle NaN as a special case:
1235 // Skip padding characters, if around prefix
1236 if (fFormatWidth
> 0 && (fPadPosition
== kPadBeforePrefix
||
1237 fPadPosition
== kPadAfterPrefix
)) {
1238 i
= skipPadding(text
, i
);
1241 if (! isParseStrict()) {
1242 // skip any leading whitespace
1243 i
= backup
= skipUWhiteSpace(text
, i
);
1246 // If the text is composed of the representation of NaN, returns NaN.length
1247 const UnicodeString
*nan
= &getConstSymbol(DecimalFormatSymbols::kNaNSymbol
);
1248 int32_t nanLen
= (text
.compare(i
, nan
->length(), *nan
)
1249 ? 0 : nan
->length());
1252 if (fFormatWidth
> 0 && (fPadPosition
== kPadBeforeSuffix
||
1253 fPadPosition
== kPadAfterSuffix
)) {
1254 i
= skipPadding(text
, i
);
1256 parsePosition
.setIndex(i
);
1257 result
.setDouble(uprv_getNaN());
1261 // NaN parse failed; start over
1263 parsePosition
.setIndex(i
);
1265 // status is used to record whether a number is infinite.
1266 UBool status
[fgStatusLength
];
1268 UChar
* currency
= parseCurrency
? curbuf
: NULL
;
1271 if (!subparse(text
, parsePosition
, digits
, status
, currency
)) {
1272 parsePosition
.setIndex(backup
);
1277 if (status
[fgStatusInfinite
]) {
1278 double inf
= uprv_getInfinity();
1279 result
.setDouble(digits
.fIsPositive
? inf
: -inf
);
1283 // Do as much of the multiplier conversion as possible without
1285 int32_t mult
= fMultiplier
; // Don't modify this.multiplier
1286 while (mult
% 10 == 0) {
1288 --digits
.fDecimalAt
;
1291 // Handle integral values. We want to return the most
1292 // parsimonious type that will accommodate all of the result's
1293 // precision. We therefore only return a long if the result fits
1294 // entirely within a long (taking into account the multiplier) --
1295 // otherwise we fall through and return a double. When more
1296 // numeric types are supported by Formattable (e.g., 64-bit
1297 // integers, bignums) we will extend this logic to include them.
1298 if (digits
.fitsIntoLong(isParseIntegerOnly())) {
1299 int32_t n
= digits
.getLong();
1300 if (n
% mult
== 0) {
1301 result
.setLong(n
/ mult
);
1303 else { // else handle the remainder
1304 result
.setDouble(((double)n
) / mult
);
1307 else if (digits
.fitsIntoInt64(isParseIntegerOnly())) {
1308 int64_t n
= digits
.getInt64();
1309 if (n
% mult
== 0) {
1310 result
.setInt64(n
/ mult
);
1312 else { // else handle the remainder
1313 result
.setDouble(((double)n
) / mult
);
1317 // Handle non-integral or very large values
1318 // Dividing by one is okay and not that costly.
1319 result
.setDouble(digits
.getDouble() / mult
);
1323 if (parseCurrency
) {
1324 UErrorCode ec
= U_ZERO_ERROR
;
1325 Formattable
n(result
);
1326 result
.adoptObject(new CurrencyAmount(n
, curbuf
, ec
));
1327 U_ASSERT(U_SUCCESS(ec
)); // should always succeed
1333 This is an old implimentation that was preparing for 64-bit numbers in ICU.
1334 It is very slow, and 64-bit numbers are not ANSI-C compatible. This code
1335 is here if we change our minds.
1337 ^^^ what is this referring to? remove? ^^^ [alan]
1341 * Parse the given text into a number. The text is parsed beginning at
1342 * parsePosition, until an unparseable character is seen.
1343 * @param text the string to parse.
1344 * @param parsePosition The position at which to being parsing. Upon
1345 * return, the first unparsed character.
1346 * @param digits the DigitList to set to the parsed value.
1347 * @param status output param containing boolean status flags indicating
1348 * whether the value was infinite and whether it was positive.
1349 * @param currency return value for parsed currency, for generic
1350 * currency parsing mode, or NULL for normal parsing. In generic
1351 * currency parsing mode, any currency is parsed, not just the
1352 * currency that this formatter is set to.
1354 UBool
DecimalFormat::subparse(const UnicodeString
& text
, ParsePosition
& parsePosition
,
1355 DigitList
& digits
, UBool
* status
,
1356 UChar
* currency
) const
1358 int32_t position
= parsePosition
.getIndex();
1359 int32_t oldStart
= position
;
1360 UBool strictParse
= isParseStrict();
1362 // Match padding before prefix
1363 if (fFormatWidth
> 0 && fPadPosition
== kPadBeforePrefix
) {
1364 position
= skipPadding(text
, position
);
1367 // Match positive and negative prefixes; prefer longest match.
1368 int32_t posMatch
= compareAffix(text
, position
, FALSE
, TRUE
, currency
);
1369 int32_t negMatch
= compareAffix(text
, position
, TRUE
, TRUE
, currency
);
1370 if (posMatch
>= 0 && negMatch
>= 0) {
1371 if (posMatch
> negMatch
) {
1373 } else if (negMatch
> posMatch
) {
1377 if (posMatch
>= 0) {
1378 position
+= posMatch
;
1379 } else if (negMatch
>= 0) {
1380 position
+= negMatch
;
1381 } else if (strictParse
) {
1382 parsePosition
.setErrorIndex(position
);
1386 // Match padding before prefix
1387 if (fFormatWidth
> 0 && fPadPosition
== kPadAfterPrefix
) {
1388 position
= skipPadding(text
, position
);
1391 if (! strictParse
) {
1392 position
= skipUWhiteSpace(text
, position
);
1395 // process digits or Inf, find decimal position
1396 const UnicodeString
*inf
= &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
);
1397 int32_t infLen
= (text
.compare(position
, inf
->length(), *inf
)
1398 ? 0 : inf
->length());
1399 position
+= infLen
; // infLen is non-zero when it does equal to infinity
1400 status
[fgStatusInfinite
] = infLen
!= 0;
1403 // We now have a string of digits, possibly with grouping symbols,
1404 // and decimal points. We want to process these into a DigitList.
1405 // We don't want to put a bunch of leading zeros into the DigitList
1406 // though, so we keep track of the location of the decimal point,
1407 // put only significant digits into the DigitList, and adjust the
1408 // exponent as needed.
1410 digits
.fDecimalAt
= digits
.fCount
= 0;
1411 UChar32 zero
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
1413 #if CHECK_FOR_LEADING_ZERO | CHECK_FOR_MISPLACED_GROUPING
1414 UBool strictFail
= FALSE
; // did we exit with a strict parse failure?
1417 #if CHECK_FOR_MISPLACED_GROUPING
1418 int32_t lastGroup
= -1; // where did we last see a grouping separator?
1419 int32_t digitStart
= position
;
1420 int32_t gs2
= fGroupingSize2
== 0 ? fGroupingSize
: fGroupingSize2
;
1423 #if CHECK_FOR_LEADING_ZERO
1424 // Strict parsing leading zeroes. If a leading zero would
1425 // be forced by the pattern, then don't fail strict parsing.
1426 UBool strictLeadingZero
= FALSE
;
1427 int32_t leadingZeroPos
= 0;
1428 int32_t leadingZeroCount
= 0;
1431 const UnicodeString
*decimalString
;
1432 if (fIsCurrencyFormat
) {
1433 decimalString
= &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol
);
1435 decimalString
= &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
1437 UChar32 decimalChar
= decimalString
->char32At(0);
1439 const UnicodeString
*groupingString
= &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
);
1440 UChar32 groupingChar
= groupingString
->char32At(0);
1441 UBool sawDecimal
= FALSE
;
1442 UBool sawDigit
= FALSE
;
1443 int32_t backup
= -1;
1445 int32_t textLength
= text
.length(); // One less pointer to follow
1446 int32_t decimalStringLength
= decimalString
->length();
1447 int32_t decimalCharLength
= U16_LENGTH(decimalChar
);
1448 int32_t groupingStringLength
= groupingString
->length();
1449 int32_t groupingCharLength
= U16_LENGTH(groupingChar
);
1451 // equivalent grouping and decimal support
1452 // TODO markdavis Cache these if it makes a difference in performance.
1453 UnicodeSet decimalFallback
;
1454 UnicodeSet
*decimalSet
= NULL
;
1455 UnicodeSet
*groupingSet
= NULL
;
1457 if (! strictParse
) {
1458 if (decimalCharLength
== decimalStringLength
) {
1459 decimalSet
= (UnicodeSet
*) DecimalFormatStaticSets::getSimilarDecimals(decimalChar
, strictParse
, &decimalFallback
)->cloneAsThawed();
1462 if (groupingCharLength
== groupingStringLength
) {
1464 groupingSet
= (UnicodeSet
*) DecimalFormatStaticSets::gStaticSets
->fStrictDefaultGroupingSeparators
->cloneAsThawed();
1466 groupingSet
= (UnicodeSet
*) DecimalFormatStaticSets::gStaticSets
->fDefaultGroupingSeparators
->cloneAsThawed();
1469 groupingSet
->add(groupingChar
);
1471 if (decimalSet
!= NULL
) {
1472 groupingSet
->removeAll(*decimalSet
);
1476 // we are guaranteed that
1477 // decimalSet contains the decimal, and
1478 // groupingSet contains the groupingSeparator
1479 // (unless decimal and grouping are the same, which should never happen. But in that case, groupingSet will just be empty.)
1482 // We have to track digitCount ourselves, because digits.fCount will
1483 // pin when the maximum allowable digits is reached.
1484 int32_t digitCount
= 0;
1486 for (; position
< textLength
; )
1488 UChar32 ch
= text
.char32At(position
);
1490 /* We recognize all digit ranges, not only the Latin digit range
1491 * '0'..'9'. We do so by using the Character.digit() method,
1492 * which converts a valid Unicode digit to the range 0..9.
1494 * The character 'ch' may be a digit. If so, place its value
1495 * from 0 to 9 in 'digit'. First try using the locale digit,
1496 * which may or MAY NOT be a standard Unicode digit range. If
1497 * this fails, try using the standard Unicode digit ranges by
1498 * calling Character.digit(). If this also fails, digit will
1499 * have a value outside the range 0..9.
1502 if (digit
< 0 || digit
> 9)
1504 digit
= u_charDigitValue(ch
);
1507 if (digit
> 0 && digit
<= 9) // digit == 0 handled below
1509 #if CHECK_FOR_MISPLACED_GROUPING
1512 if ((lastGroup
!= -1 && backup
- lastGroup
- 1 != gs2
) ||
1513 (lastGroup
== -1 && position
- digitStart
- 1 > gs2
)) {
1524 // Cancel out backup setting (see grouping handler below)
1528 // output a regular non-zero digit.
1530 digits
.append((char)(digit
+ '0'));
1531 position
+= U16_LENGTH(ch
);
1533 else if (digit
== 0)
1535 // Cancel out backup setting (see grouping handler below)
1537 #if CHECK_FOR_MISPLACED_GROUPING
1538 if (strictParse
&& backup
!= -1) {
1539 // comma followed by digit, so group before comma is a
1540 // secondary group. If there was a group separator
1541 // before that, the group must == the secondary group
1542 // length, else it can be <= the the secondary group
1544 if ((lastGroup
!= -1 && backup
- lastGroup
- 1 != gs2
) ||
1545 (lastGroup
== -1 && position
- digitStart
- 1 > gs2
)) {
1557 // handle leading zeros
1558 if (digits
.fCount
!= 0) {
1560 digits
.append((char) (digit
+ '0'));
1561 } else if (sawDecimal
) {
1562 // If we have seen the decimal, but no significant digits yet,
1563 // then we account for leading zeros by decrementing
1564 // digits.decimalAt into negative values.
1565 digits
.fDecimalAt
-= 1;
1567 #if CHECK_FOR_LEADING_ZERO
1569 // TODO: Not sure we need to check fUseExponentialNotation
1570 if (strictParse
&& !fUseExponentialNotation
) {
1571 if (!strictLeadingZero
) {
1572 leadingZeroPos
= position
+ U16_LENGTH(ch
);
1573 strictLeadingZero
= TRUE
;
1576 leadingZeroCount
+= 1;
1581 position
+= U16_LENGTH(ch
);
1583 else if (matchSymbol(text
, position
, groupingStringLength
, *groupingString
, groupingSet
, ch
) && isGroupingUsed())
1585 #if CHECK_FOR_MISPLACED_GROUPING
1591 if ((!sawDigit
|| backup
!= -1)) {
1592 // leading group, or two group separators in a row
1599 // Ignore grouping characters, if we are using them, but require
1600 // that they be followed by a digit. Otherwise we backup and
1603 position
+= groupingStringLength
;
1605 if (groupingSet
!= NULL
) {
1606 // Once we see a grouping character, we only accept that grouping character from then on.
1607 groupingSet
->set(ch
, ch
);
1610 else if (matchSymbol(text
, position
, decimalStringLength
, *decimalString
, decimalSet
, ch
) && !isParseIntegerOnly() && !sawDecimal
)
1612 #if CHECK_FOR_MISPLACED_GROUPING
1615 (lastGroup
!= -1 && position
- lastGroup
!= fGroupingSize
+ 1)) {
1622 // If we're only parsing integers, or if we ALREADY saw the
1623 // decimal, then don't parse this one.
1624 if (isParseIntegerOnly() || sawDecimal
) {
1628 digits
.fDecimalAt
= digitCount
; // Not digits.fCount!
1629 position
+= decimalStringLength
;
1632 if (decimalSet
!= NULL
) {
1633 // Once we see a decimal character, we only accept that decimal character from then on.
1634 decimalSet
->set(ch
, ch
);
1638 const UnicodeString
*tmp
;
1639 tmp
= &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
);
1640 if (!text
.caseCompare(position
, tmp
->length(), *tmp
, U_FOLD_CASE_DEFAULT
)) // error code is set below if !sawDigit
1642 // Parse sign, if present
1643 int32_t pos
= position
+ tmp
->length();
1644 DigitList exponentDigits
;
1646 if (pos
< textLength
)
1648 tmp
= &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
1649 if (!text
.compare(pos
, tmp
->length(), *tmp
))
1651 pos
+= tmp
->length();
1654 tmp
= &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
1655 if (!text
.compare(pos
, tmp
->length(), *tmp
))
1657 pos
+= tmp
->length();
1658 exponentDigits
.fIsPositive
= FALSE
;
1663 while (pos
< textLength
) {
1664 ch
= text
[(int32_t)pos
];
1667 if (digit
< 0 || digit
> 9) {
1668 digit
= u_charDigitValue(ch
);
1670 if (0 <= digit
&& digit
<= 9) {
1672 exponentDigits
.append((char)(digit
+ '0'));
1678 if (exponentDigits
.fCount
> 0) {
1679 exponentDigits
.fDecimalAt
= exponentDigits
.fCount
;
1680 digits
.fDecimalAt
+= exponentDigits
.getLong();
1681 position
= pos
; // Advance past the exponent
1684 break; // Whether we fail or succeed, we exit this loop
1692 if (! strictParse
) {
1702 #if CHECK_FOR_LEADING_ZERO
1703 // check for strict parse errors
1704 if (strictParse
&& strictLeadingZero
) {
1705 if ((leadingZeroCount
+ digits
.fDecimalAt
) > getMinimumIntegerDigits()) {
1706 parsePosition
.setIndex(oldStart
);
1707 parsePosition
.setErrorIndex(leadingZeroPos
);
1713 #if CHECK_FOR_MISPLACED_GROUPING
1714 if (strictParse
&& !sawDecimal
) {
1715 if (lastGroup
!= -1 && position
- lastGroup
!= fGroupingSize
+ 1) {
1721 #if CHECK_FOR_LEADING_ZERO | CHECK_FOR_MISPLACED_GROUPING
1724 // only set with strictParse and a leading zero error
1725 // leading zeros are an error with strict parsing except
1726 // immediately before nondigit (except group separator
1727 // followed by digit), or end of text.
1729 parsePosition
.setIndex(oldStart
);
1730 parsePosition
.setErrorIndex(position
);
1735 // If there was no decimal point we have an integer
1738 digits
.fDecimalAt
+= digitCount
; // Not digits.fCount!
1741 // If none of the text string was recognized. For example, parse
1742 // "x" with pattern "#0.00" (return index and error index both 0)
1743 // parse "$" with pattern "$#0.00". (return index 0 and error index
1745 if (!sawDigit
&& digitCount
== 0) {
1746 parsePosition
.setIndex(oldStart
);
1747 parsePosition
.setErrorIndex(oldStart
);
1752 // Match padding before suffix
1753 if (fFormatWidth
> 0 && fPadPosition
== kPadBeforeSuffix
) {
1754 position
= skipPadding(text
, position
);
1757 int32_t posSuffixMatch
= -1, negSuffixMatch
= -1;
1759 // Match positive and negative suffixes; prefer longest match.
1760 if (posMatch
>= 0 || (!strictParse
&& negMatch
< 0)) {
1761 posSuffixMatch
= compareAffix(text
, position
, FALSE
, FALSE
, currency
);
1763 if (negMatch
>= 0) {
1764 negSuffixMatch
= compareAffix(text
, position
, TRUE
, FALSE
, currency
);
1766 if (posSuffixMatch
>= 0 && negSuffixMatch
>= 0) {
1767 if (posSuffixMatch
> negSuffixMatch
) {
1768 negSuffixMatch
= -1;
1769 } else if (negSuffixMatch
> posSuffixMatch
) {
1770 posSuffixMatch
= -1;
1774 // Fail if neither or both
1775 if (strictParse
&& ((posSuffixMatch
>= 0) == (negSuffixMatch
>= 0))) {
1776 parsePosition
.setErrorIndex(position
);
1780 position
+= (posSuffixMatch
>= 0 ? posSuffixMatch
: (negSuffixMatch
>= 0? negSuffixMatch
: 0));
1782 // Match padding before suffix
1783 if (fFormatWidth
> 0 && fPadPosition
== kPadAfterSuffix
) {
1784 position
= skipPadding(text
, position
);
1787 parsePosition
.setIndex(position
);
1789 digits
.fIsPositive
= (posSuffixMatch
>= 0 || (!strictParse
&& negMatch
< 0 && negSuffixMatch
< 0));
1791 if(parsePosition
.getIndex() == oldStart
)
1793 parsePosition
.setErrorIndex(position
);
1800 * Starting at position, advance past a run of pad characters, if any.
1801 * Return the index of the first character after position that is not a pad
1802 * character. Result is >= position.
1804 int32_t DecimalFormat::skipPadding(const UnicodeString
& text
, int32_t position
) const {
1805 int32_t padLen
= U16_LENGTH(fPad
);
1806 while (position
< text
.length() &&
1807 text
.char32At(position
) == fPad
) {
1814 * Return the length matched by the given affix, or -1 if none.
1815 * Runs of white space in the affix, match runs of white space in
1816 * the input. Pattern white space and input white space are
1817 * determined differently; see code.
1818 * @param text input text
1819 * @param pos offset into input at which to begin matching
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 * @return length of input that matches, or -1 if match failure
1828 int32_t DecimalFormat::compareAffix(const UnicodeString
& text
,
1832 UChar
* currency
) const
1834 const UnicodeString
*patternToCompare
;
1835 if (fCurrencyChoice
!= NULL
|| currency
!= NULL
) {
1838 patternToCompare
= fNegPrefixPattern
;
1841 patternToCompare
= fNegSuffixPattern
;
1846 patternToCompare
= fPosPrefixPattern
;
1849 patternToCompare
= fPosSuffixPattern
;
1852 if (patternToCompare
!= NULL
) {
1853 return compareComplexAffix(*patternToCompare
, text
, pos
, currency
);
1855 /* else the caller modified the pattern. Fallback to normal behavior. */
1860 patternToCompare
= &fNegativePrefix
;
1863 patternToCompare
= &fNegativeSuffix
;
1868 patternToCompare
= &fPositivePrefix
;
1871 patternToCompare
= &fPositiveSuffix
;
1874 return compareSimpleAffix(*patternToCompare
, text
, pos
, isParseStrict());
1878 * Return the length matched by the given affix, or -1 if none.
1879 * Runs of white space in the affix, match runs of white space in
1880 * the input. Pattern white space and input white space are
1881 * determined differently; see code.
1882 * @param affix pattern string, taken as a literal
1883 * @param input input text
1884 * @param pos offset into input at which to begin matching
1885 * @return length of input that matches, or -1 if match failure
1887 int32_t DecimalFormat::compareSimpleAffix(const UnicodeString
& affix
,
1888 const UnicodeString
& input
,
1891 int32_t start
= pos
;
1894 for (int32_t i
=0; i
<affix
.length(); ) {
1895 UChar32 c
= affix
.char32At(i
);
1896 int32_t len
= U16_LENGTH(c
);
1897 if (uprv_isRuleWhiteSpace(c
)) {
1898 // We may have a pattern like: \u200F \u0020
1899 // and input text like: \u200F \u0020
1900 // Note that U+200F and U+0020 are RuleWhiteSpace but only
1901 // U+0020 is UWhiteSpace. So we have to first do a direct
1902 // match of the run of RULE whitespace in the pattern,
1903 // then match any extra characters.
1904 UBool literalMatch
= FALSE
;
1905 while (pos
< input
.length() &&
1906 input
.char32At(pos
) == c
) {
1907 literalMatch
= TRUE
;
1910 if (i
== affix
.length()) {
1913 c
= affix
.char32At(i
);
1914 len
= U16_LENGTH(c
);
1915 if (!uprv_isRuleWhiteSpace(c
)) {
1920 // Advance over run in pattern
1921 i
= skipRuleWhiteSpace(affix
, i
);
1923 // Advance over run in input text
1924 // Must see at least one white space char in input,
1925 // unless we've already matched some characters literally.
1927 pos
= skipUWhiteSpace(input
, pos
);
1928 if (pos
== s
&& !literalMatch
) {
1932 // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
1933 // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
1934 // is also in the affix.
1935 i
= skipUWhiteSpace(affix
, i
);
1937 if (pos
< input
.length() &&
1938 input
.char32At(pos
) == c
) {
1947 int32_t affixLength
= affix
.length();
1948 int32_t inputLength
= input
.length();
1949 UBool match
= FALSE
;
1951 for (int32_t i
= 0; i
< affixLength
; )
1953 //i = skipRuleWhiteSpace(affix, i);
1954 i
= skipUWhiteSpace(affix
, i
);
1955 pos
= skipUWhiteSpace(input
, pos
);
1957 if (i
>= affixLength
|| pos
>= inputLength
) {
1961 UChar32 c
= affix
.char32At(i
);
1962 int32_t len
= U16_LENGTH(c
);
1964 if (input
.char32At(pos
) != c
) {
1974 if (affixLength
> 0 && ! match
) {
1983 * Skip over a run of zero or more isRuleWhiteSpace() characters at
1986 int32_t DecimalFormat::skipRuleWhiteSpace(const UnicodeString
& text
, int32_t pos
) {
1987 while (pos
< text
.length()) {
1988 UChar32 c
= text
.char32At(pos
);
1989 if (!uprv_isRuleWhiteSpace(c
)) {
1992 pos
+= U16_LENGTH(c
);
1998 * Skip over a run of zero or more isUWhiteSpace() characters at pos
2001 int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString
& text
, int32_t pos
) {
2002 while (pos
< text
.length()) {
2003 UChar32 c
= text
.char32At(pos
);
2004 if (!u_isUWhiteSpace(c
)) {
2007 pos
+= U16_LENGTH(c
);
2013 * Return the length matched by the given affix, or -1 if none.
2014 * @param affixPat pattern string
2015 * @param input input text
2016 * @param pos offset into input at which to begin matching
2017 * @param currency return value for parsed currency, for generic
2018 * currency parsing mode, or null for normal parsing. In generic
2019 * currency parsing mode, any currency is parsed, not just the
2020 * currency that this formatter is set to.
2021 * @return length of input that matches, or -1 if match failure
2023 int32_t DecimalFormat::compareComplexAffix(const UnicodeString
& affixPat
,
2024 const UnicodeString
& text
,
2026 UChar
* currency
) const
2028 int32_t start
= pos
;
2029 U_ASSERT(currency
!= NULL
||
2030 (fCurrencyChoice
!= NULL
&& *getCurrency() != 0));
2032 for (int32_t i
=0; i
<affixPat
.length() && pos
>= 0; ) {
2033 UChar32 c
= affixPat
.char32At(i
);
2037 U_ASSERT(i
<= affixPat
.length());
2038 c
= affixPat
.char32At(i
);
2041 const UnicodeString
* affix
= NULL
;
2044 case kCurrencySign
: {
2045 // If currency != null, then perform generic currency matching.
2046 // Otherwise, do currency choice parsing.
2047 UBool intl
= i
<affixPat
.length() &&
2048 affixPat
.char32At(i
) == kCurrencySign
;
2049 // Parse generic currency -- anything for which we
2050 // have a display name, or any 3-letter ISO code.
2051 if (currency
!= NULL
) {
2052 // Try to parse display name for our locale; first
2053 // determine our locale.
2054 UErrorCode ec
= U_ZERO_ERROR
;
2055 const char* loc
= getLocaleID(ULOC_VALID_LOCALE
, ec
);
2056 if (U_FAILURE(ec
) || loc
== NULL
|| *loc
== 0) {
2057 // applyPattern has been called; use the symbols
2058 if (fSymbols
== NULL
) {
2059 ec
= U_MEMORY_ALLOCATION_ERROR
;
2062 loc
= fSymbols
->getLocale().getName();
2065 // Delegate parse of display name => ISO code to Currency
2066 ParsePosition
ppos(pos
);
2068 uprv_parseCurrency(loc
, text
, ppos
, curr
, ec
);
2070 // If parse succeeds, populate currency[0]
2071 if (U_SUCCESS(ec
) && ppos
.getIndex() != pos
) {
2072 u_strcpy(currency
, curr
);
2073 pos
= ppos
.getIndex();
2074 } else if (isParseStrict()) {
2080 pos
= match(text
, pos
, getCurrency());
2082 ParsePosition
ppos(pos
);
2084 fCurrencyChoice
->parse(text
, result
, ppos
);
2085 pos
= (ppos
.getIndex() == pos
) ? -1 : ppos
.getIndex();
2090 case kPatternPercent
:
2091 affix
= &getConstSymbol(DecimalFormatSymbols::kPercentSymbol
);
2093 case kPatternPerMill
:
2094 affix
= &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
);
2097 affix
= &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
2100 affix
= &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
2103 // fall through to affix!=0 test, which will fail
2107 if (affix
!= NULL
) {
2108 pos
= match(text
, pos
, *affix
);
2113 pos
= match(text
, pos
, c
);
2114 if (uprv_isRuleWhiteSpace(c
)) {
2115 i
= skipRuleWhiteSpace(affixPat
, i
);
2122 * Match a single character at text[pos] and return the index of the
2123 * next character upon success. Return -1 on failure. If
2124 * isRuleWhiteSpace(ch) then match a run of white space in text.
2126 int32_t DecimalFormat::match(const UnicodeString
& text
, int32_t pos
, UChar32 ch
) {
2127 if (uprv_isRuleWhiteSpace(ch
)) {
2128 // Advance over run of white space in input text
2129 // Must see at least one white space char in input
2131 pos
= skipUWhiteSpace(text
, pos
);
2137 return (pos
>= 0 && text
.char32At(pos
) == ch
) ?
2138 (pos
+ U16_LENGTH(ch
)) : -1;
2142 * Match a string at text[pos] and return the index of the next
2143 * character upon success. Return -1 on failure. Match a run of
2144 * white space in str with a run of white space in text.
2146 int32_t DecimalFormat::match(const UnicodeString
& text
, int32_t pos
, const UnicodeString
& str
) {
2147 for (int32_t i
=0; i
<str
.length() && pos
>= 0; ) {
2148 UChar32 ch
= str
.char32At(i
);
2149 i
+= U16_LENGTH(ch
);
2150 if (uprv_isRuleWhiteSpace(ch
)) {
2151 i
= skipRuleWhiteSpace(str
, i
);
2153 pos
= match(text
, pos
, ch
);
2158 UBool
DecimalFormat::matchSymbol(const UnicodeString
&text
, int32_t position
, int32_t length
, const UnicodeString
&symbol
,
2159 UnicodeSet
*sset
, UChar32 schar
)
2162 return sset
->contains(schar
);
2165 return text
.compare(position
, length
, symbol
) == 0;
2168 //------------------------------------------------------------------------------
2169 // Gets the pointer to the localized decimal format symbols
2171 const DecimalFormatSymbols
*
2172 DecimalFormat::getDecimalFormatSymbols() const
2177 //------------------------------------------------------------------------------
2178 // De-owning the current localized symbols and adopt the new symbols.
2181 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols
* symbolsToAdopt
)
2183 if (symbolsToAdopt
== NULL
) {
2184 return; // do not allow caller to set fSymbols to NULL
2187 UBool sameSymbols
= FALSE
;
2188 if (fSymbols
!= NULL
) {
2189 sameSymbols
= (UBool
)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) ==
2190 symbolsToAdopt
->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) &&
2191 getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
) ==
2192 symbolsToAdopt
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
));
2196 fSymbols
= symbolsToAdopt
;
2198 // If the currency symbols are the same, there is no need to recalculate.
2199 setCurrencyForSymbols();
2203 //------------------------------------------------------------------------------
2204 // Setting the symbols is equlivalent to adopting a newly created localized
2208 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols
& symbols
)
2210 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols
));
2214 * Update the currency object to match the symbols. This method
2215 * is used only when the caller has passed in a symbols object
2216 * that may not be the default object for its locale.
2219 DecimalFormat::setCurrencyForSymbols() {
2221 Update the affix strings accroding to symbols in order to keep
2222 the affix strings up to date.
2226 // With the introduction of the Currency object, the currency
2227 // symbols in the DFS object are ignored. For backward
2228 // compatibility, we check any explicitly set DFS object. If it
2229 // is a default symbols object for its locale, we change the
2230 // currency object to one for that locale. If it is custom,
2231 // we set the currency to null.
2232 UErrorCode ec
= U_ZERO_ERROR
;
2233 const UChar
* c
= NULL
;
2234 const char* loc
= fSymbols
->getLocale().getName();
2235 UChar intlCurrencySymbol
[4];
2236 ucurr_forLocale(loc
, intlCurrencySymbol
, 4, &ec
);
2237 UnicodeString currencySymbol
;
2239 uprv_getStaticCurrencyName(intlCurrencySymbol
, loc
, currencySymbol
, ec
);
2241 && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
) == currencySymbol
2242 && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
) == intlCurrencySymbol
)
2244 // Trap an error in mapping locale to currency. If we can't
2245 // map, then don't fail and set the currency to "".
2246 c
= intlCurrencySymbol
;
2248 ec
= U_ZERO_ERROR
; // reset local error code!
2253 //------------------------------------------------------------------------------
2254 // Gets the positive prefix of the number pattern.
2257 DecimalFormat::getPositivePrefix(UnicodeString
& result
) const
2259 result
= fPositivePrefix
;
2263 //------------------------------------------------------------------------------
2264 // Sets the positive prefix of the number pattern.
2267 DecimalFormat::setPositivePrefix(const UnicodeString
& newValue
)
2269 fPositivePrefix
= newValue
;
2270 delete fPosPrefixPattern
;
2271 fPosPrefixPattern
= 0;
2274 //------------------------------------------------------------------------------
2275 // Gets the negative prefix of the number pattern.
2278 DecimalFormat::getNegativePrefix(UnicodeString
& result
) const
2280 result
= fNegativePrefix
;
2284 //------------------------------------------------------------------------------
2285 // Gets the negative prefix of the number pattern.
2288 DecimalFormat::setNegativePrefix(const UnicodeString
& newValue
)
2290 fNegativePrefix
= newValue
;
2291 delete fNegPrefixPattern
;
2292 fNegPrefixPattern
= 0;
2295 //------------------------------------------------------------------------------
2296 // Gets the positive suffix of the number pattern.
2299 DecimalFormat::getPositiveSuffix(UnicodeString
& result
) const
2301 result
= fPositiveSuffix
;
2305 //------------------------------------------------------------------------------
2306 // Sets the positive suffix of the number pattern.
2309 DecimalFormat::setPositiveSuffix(const UnicodeString
& newValue
)
2311 fPositiveSuffix
= newValue
;
2312 delete fPosSuffixPattern
;
2313 fPosSuffixPattern
= 0;
2316 //------------------------------------------------------------------------------
2317 // Gets the negative suffix of the number pattern.
2320 DecimalFormat::getNegativeSuffix(UnicodeString
& result
) const
2322 result
= fNegativeSuffix
;
2326 //------------------------------------------------------------------------------
2327 // Sets the negative suffix of the number pattern.
2330 DecimalFormat::setNegativeSuffix(const UnicodeString
& newValue
)
2332 fNegativeSuffix
= newValue
;
2333 delete fNegSuffixPattern
;
2334 fNegSuffixPattern
= 0;
2337 //------------------------------------------------------------------------------
2338 // Gets the multiplier of the number pattern.
2340 int32_t DecimalFormat::getMultiplier() const
2345 //------------------------------------------------------------------------------
2346 // Sets the multiplier of the number pattern.
2348 DecimalFormat::setMultiplier(int32_t newValue
)
2350 // if (newValue == 0) {
2351 // throw new IllegalArgumentException("Bad multiplier: " + newValue);
2353 if (newValue
!= 0) {
2354 fMultiplier
= newValue
;
2356 // else No way to return an error.
2360 * Get the rounding increment.
2361 * @return A positive rounding increment, or 0.0 if rounding
2363 * @see #setRoundingIncrement
2364 * @see #getRoundingMode
2365 * @see #setRoundingMode
2367 double DecimalFormat::getRoundingIncrement() const {
2368 return fRoundingDouble
;
2372 * Set the rounding increment. This method also controls whether
2373 * rounding is enabled.
2374 * @param newValue A positive rounding increment, or 0.0 to disable rounding.
2375 * Negative increments are equivalent to 0.0.
2376 * @see #getRoundingIncrement
2377 * @see #getRoundingMode
2378 * @see #setRoundingMode
2380 void DecimalFormat::setRoundingIncrement(double newValue
) {
2381 if (newValue
> 0.0) {
2382 if (fRoundingIncrement
== NULL
) {
2383 fRoundingIncrement
= new DigitList();
2385 if (fRoundingIncrement
!= NULL
) {
2386 fRoundingIncrement
->set((int32_t)newValue
);
2387 fRoundingDouble
= newValue
;
2391 // These statements are executed if newValue is less than 0.0
2392 // or fRoundingIncrement could not be created.
2393 delete fRoundingIncrement
;
2394 fRoundingIncrement
= NULL
;
2395 fRoundingDouble
= 0.0;
2399 * Get the rounding mode.
2400 * @return A rounding mode
2401 * @see #setRoundingIncrement
2402 * @see #getRoundingIncrement
2403 * @see #setRoundingMode
2405 DecimalFormat::ERoundingMode
DecimalFormat::getRoundingMode() const {
2406 return fRoundingMode
;
2410 * Set the rounding mode. This has no effect unless the rounding
2411 * increment is greater than zero.
2412 * @param roundingMode A rounding mode
2413 * @see #setRoundingIncrement
2414 * @see #getRoundingIncrement
2415 * @see #getRoundingMode
2417 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode
) {
2418 fRoundingMode
= roundingMode
;
2422 * Get the width to which the output of <code>format()</code> is padded.
2423 * @return the format width, or zero if no padding is in effect
2424 * @see #setFormatWidth
2425 * @see #getPadCharacter
2426 * @see #setPadCharacter
2427 * @see #getPadPosition
2428 * @see #setPadPosition
2430 int32_t DecimalFormat::getFormatWidth() const {
2431 return fFormatWidth
;
2435 * Set the width to which the output of <code>format()</code> is padded.
2436 * This method also controls whether padding is enabled.
2437 * @param width the width to which to pad the result of
2438 * <code>format()</code>, or zero to disable padding. A negative
2439 * width is equivalent to 0.
2440 * @see #getFormatWidth
2441 * @see #getPadCharacter
2442 * @see #setPadCharacter
2443 * @see #getPadPosition
2444 * @see #setPadPosition
2446 void DecimalFormat::setFormatWidth(int32_t width
) {
2447 fFormatWidth
= (width
> 0) ? width
: 0;
2450 UnicodeString
DecimalFormat::getPadCharacterString() const {
2454 void DecimalFormat::setPadCharacter(const UnicodeString
&padChar
) {
2455 if (padChar
.length() > 0) {
2456 fPad
= padChar
.char32At(0);
2464 * Get the position at which padding will take place. This is the location
2465 * at which padding will be inserted if the result of <code>format()</code>
2466 * is shorter than the format width.
2467 * @return the pad position, one of <code>kPadBeforePrefix</code>,
2468 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2469 * <code>kPadAfterSuffix</code>.
2470 * @see #setFormatWidth
2471 * @see #getFormatWidth
2472 * @see #setPadCharacter
2473 * @see #getPadCharacter
2474 * @see #setPadPosition
2475 * @see #kPadBeforePrefix
2476 * @see #kPadAfterPrefix
2477 * @see #kPadBeforeSuffix
2478 * @see #kPadAfterSuffix
2480 DecimalFormat::EPadPosition
DecimalFormat::getPadPosition() const {
2481 return fPadPosition
;
2485 * <strong><font face=helvetica color=red>NEW</font></strong>
2486 * Set the position at which padding will take place. This is the location
2487 * at which padding will be inserted if the result of <code>format()</code>
2488 * is shorter than the format width. This has no effect unless padding is
2490 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
2491 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
2492 * <code>kPadAfterSuffix</code>.
2493 * @see #setFormatWidth
2494 * @see #getFormatWidth
2495 * @see #setPadCharacter
2496 * @see #getPadCharacter
2497 * @see #getPadPosition
2498 * @see #kPadBeforePrefix
2499 * @see #kPadAfterPrefix
2500 * @see #kPadBeforeSuffix
2501 * @see #kPadAfterSuffix
2503 void DecimalFormat::setPadPosition(EPadPosition padPos
) {
2504 fPadPosition
= padPos
;
2508 * Return whether or not scientific notation is used.
2509 * @return TRUE if this object formats and parses scientific notation
2510 * @see #setScientificNotation
2511 * @see #getMinimumExponentDigits
2512 * @see #setMinimumExponentDigits
2513 * @see #isExponentSignAlwaysShown
2514 * @see #setExponentSignAlwaysShown
2516 UBool
DecimalFormat::isScientificNotation() {
2517 return fUseExponentialNotation
;
2521 * Set whether or not scientific notation is used.
2522 * @param useScientific TRUE if this object formats and parses scientific
2524 * @see #isScientificNotation
2525 * @see #getMinimumExponentDigits
2526 * @see #setMinimumExponentDigits
2527 * @see #isExponentSignAlwaysShown
2528 * @see #setExponentSignAlwaysShown
2530 void DecimalFormat::setScientificNotation(UBool useScientific
) {
2531 fUseExponentialNotation
= useScientific
;
2535 * Return the minimum exponent digits that will be shown.
2536 * @return the minimum exponent digits that will be shown
2537 * @see #setScientificNotation
2538 * @see #isScientificNotation
2539 * @see #setMinimumExponentDigits
2540 * @see #isExponentSignAlwaysShown
2541 * @see #setExponentSignAlwaysShown
2543 int8_t DecimalFormat::getMinimumExponentDigits() const {
2544 return fMinExponentDigits
;
2548 * Set the minimum exponent digits that will be shown. This has no
2549 * effect unless scientific notation is in use.
2550 * @param minExpDig a value >= 1 indicating the fewest exponent digits
2551 * that will be shown. Values less than 1 will be treated as 1.
2552 * @see #setScientificNotation
2553 * @see #isScientificNotation
2554 * @see #getMinimumExponentDigits
2555 * @see #isExponentSignAlwaysShown
2556 * @see #setExponentSignAlwaysShown
2558 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig
) {
2559 fMinExponentDigits
= (int8_t)((minExpDig
> 0) ? minExpDig
: 1);
2563 * Return whether the exponent sign is always shown.
2564 * @return TRUE if the exponent is always prefixed with either the
2565 * localized minus sign or the localized plus sign, false if only negative
2566 * exponents are prefixed with the localized minus sign.
2567 * @see #setScientificNotation
2568 * @see #isScientificNotation
2569 * @see #setMinimumExponentDigits
2570 * @see #getMinimumExponentDigits
2571 * @see #setExponentSignAlwaysShown
2573 UBool
DecimalFormat::isExponentSignAlwaysShown() {
2574 return fExponentSignAlwaysShown
;
2578 * Set whether the exponent sign is always shown. This has no effect
2579 * unless scientific notation is in use.
2580 * @param expSignAlways TRUE if the exponent is always prefixed with either
2581 * the localized minus sign or the localized plus sign, false if only
2582 * negative exponents are prefixed with the localized minus sign.
2583 * @see #setScientificNotation
2584 * @see #isScientificNotation
2585 * @see #setMinimumExponentDigits
2586 * @see #getMinimumExponentDigits
2587 * @see #isExponentSignAlwaysShown
2589 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways
) {
2590 fExponentSignAlwaysShown
= expSignAlways
;
2593 //------------------------------------------------------------------------------
2594 // Gets the grouping size of the number pattern. For example, thousand or 10
2595 // thousand groupings.
2598 DecimalFormat::getGroupingSize() const
2600 return fGroupingSize
;
2603 //------------------------------------------------------------------------------
2604 // Gets the grouping size of the number pattern.
2607 DecimalFormat::setGroupingSize(int32_t newValue
)
2609 fGroupingSize
= newValue
;
2612 //------------------------------------------------------------------------------
2615 DecimalFormat::getSecondaryGroupingSize() const
2617 return fGroupingSize2
;
2620 //------------------------------------------------------------------------------
2623 DecimalFormat::setSecondaryGroupingSize(int32_t newValue
)
2625 fGroupingSize2
= newValue
;
2628 //------------------------------------------------------------------------------
2629 // Checks if to show the decimal separator.
2632 DecimalFormat::isDecimalSeparatorAlwaysShown() const
2634 return fDecimalSeparatorAlwaysShown
;
2637 //------------------------------------------------------------------------------
2638 // Sets to always show the decimal separator.
2641 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue
)
2643 fDecimalSeparatorAlwaysShown
= newValue
;
2646 //------------------------------------------------------------------------------
2647 // Emits the pattern of this DecimalFormat instance.
2650 DecimalFormat::toPattern(UnicodeString
& result
) const
2652 return toPattern(result
, FALSE
);
2655 //------------------------------------------------------------------------------
2656 // Emits the localized pattern this DecimalFormat instance.
2659 DecimalFormat::toLocalizedPattern(UnicodeString
& result
) const
2661 return toPattern(result
, TRUE
);
2664 //------------------------------------------------------------------------------
2666 * Expand the affix pattern strings into the expanded affix strings. If any
2667 * affix pattern string is null, do not expand it. This method should be
2668 * called any time the symbols or the affix patterns change in order to keep
2669 * the expanded affix strings up to date.
2671 void DecimalFormat::expandAffixes() {
2672 if (fPosPrefixPattern
!= 0) {
2673 expandAffix(*fPosPrefixPattern
, fPositivePrefix
, 0, FALSE
);
2675 if (fPosSuffixPattern
!= 0) {
2676 expandAffix(*fPosSuffixPattern
, fPositiveSuffix
, 0, FALSE
);
2678 if (fNegPrefixPattern
!= 0) {
2679 expandAffix(*fNegPrefixPattern
, fNegativePrefix
, 0, FALSE
);
2681 if (fNegSuffixPattern
!= 0) {
2682 expandAffix(*fNegSuffixPattern
, fNegativeSuffix
, 0, FALSE
);
2687 .append(*fPosPrefixPattern
).append("|").append(*fPosSuffixPattern
)
2688 .append(";") .append(*fNegPrefixPattern
).append("|").append(*fNegSuffixPattern
)
2690 .append(fPositivePrefix
).append("|").append(fPositiveSuffix
)
2691 .append(";") .append(fNegativePrefix
).append("|").append(fNegativeSuffix
)
2698 * Expand an affix pattern into an affix string. All characters in the
2699 * pattern are literal unless prefixed by kQuote. The following characters
2700 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
2701 * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote +
2702 * kCurrencySign + kCurrencySign), it is interpreted as an international
2703 * currency sign. Any other character after a kQuote represents itself.
2704 * kQuote must be followed by another character; kQuote may not occur by
2705 * itself at the end of the pattern.
2707 * This method is used in two distinct ways. First, it is used to expand
2708 * the stored affix patterns into actual affixes. For this usage, doFormat
2709 * must be false. Second, it is used to expand the stored affix patterns
2710 * given a specific number (doFormat == true), for those rare cases in
2711 * which a currency format references a ChoiceFormat (e.g., en_IN display
2712 * name for INR). The number itself is taken from digitList.
2714 * When used in the first way, this method has a side effect: It sets
2715 * currencyChoice to a ChoiceFormat object, if the currency's display name
2716 * in this locale is a ChoiceFormat pattern (very rare). It only does this
2717 * if currencyChoice is null to start with.
2719 * @param pattern the non-null, fPossibly empty pattern
2720 * @param affix string to receive the expanded equivalent of pattern.
2721 * Previous contents are deleted.
2722 * @param doFormat if false, then the pattern will be expanded, and if a
2723 * currency symbol is encountered that expands to a ChoiceFormat, the
2724 * currencyChoice member variable will be initialized if it is null. If
2725 * doFormat is true, then it is assumed that the currencyChoice has been
2726 * created, and it will be used to format the value in digitList.
2728 void DecimalFormat::expandAffix(const UnicodeString
& pattern
,
2729 UnicodeString
& affix
,
2731 UBool doFormat
) const {
2733 for (int i
=0; i
<pattern
.length(); ) {
2734 UChar32 c
= pattern
.char32At(i
);
2737 c
= pattern
.char32At(i
);
2740 case kCurrencySign
: {
2741 // As of ICU 2.2 we use the currency object, and
2742 // ignore the currency symbols in the DFS, unless
2743 // we have a null currency object. This occurs if
2744 // resurrecting a pre-2.2 object or if the user
2745 // sets a custom DFS.
2746 UBool intl
= i
<pattern
.length() &&
2747 pattern
.char32At(i
) == kCurrencySign
;
2751 const UChar
* currencyUChars
= getCurrency();
2752 if (currencyUChars
[0] != 0) {
2753 UErrorCode ec
= U_ZERO_ERROR
;
2755 affix
+= currencyUChars
;
2758 UBool isChoiceFormat
;
2759 // If fSymbols is NULL, use default locale
2760 const UChar
* s
= ucurr_getName(currencyUChars
, fSymbols
!= NULL
? fSymbols
->getLocale().getName() : Locale::getDefault().getName(),
2761 UCURR_SYMBOL_NAME
, &isChoiceFormat
, &len
, &ec
);
2762 if (isChoiceFormat
) {
2763 // Two modes here: If doFormat is false, we set up
2764 // currencyChoice. If doFormat is true, we use the
2765 // previously created currencyChoice to format the
2766 // value in digitList.
2768 // If the currency is handled by a ChoiceFormat,
2769 // then we're not going to use the expanded
2770 // patterns. Instantiate the ChoiceFormat and
2772 if (fCurrencyChoice
== NULL
) {
2773 // TODO Replace double-check with proper thread-safe code
2774 ChoiceFormat
* fmt
= new ChoiceFormat(s
, ec
);
2775 if (U_SUCCESS(ec
)) {
2777 if (fCurrencyChoice
== NULL
) {
2779 ((DecimalFormat
*)this)->fCurrencyChoice
= fmt
;
2786 // We could almost return null or "" here, since the
2787 // expanded affixes are almost not used at all
2788 // in this situation. However, one method --
2789 // toPattern() -- still does use the expanded
2790 // affixes, in order to set up a padding
2791 // pattern. We use the CURRENCY_SIGN as a
2793 affix
.append(kCurrencySign
);
2795 if (fCurrencyChoice
!= NULL
) {
2796 FieldPosition
pos(0); // ignored
2800 fCurrencyChoice
->format(number
, affix
, pos
);
2802 // We only arrive here if the currency choice
2803 // format in the locale data is INVALID.
2804 affix
+= currencyUChars
;
2809 affix
+= UnicodeString(s
, len
);
2813 affix
+= getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
2815 affix
+= getConstSymbol(DecimalFormatSymbols::kCurrencySymbol
);
2820 case kPatternPercent
:
2821 affix
+= getConstSymbol(DecimalFormatSymbols::kPercentSymbol
);
2823 case kPatternPerMill
:
2824 affix
+= getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
);
2827 affix
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
2830 affix
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
2844 * Append an affix to the given StringBuffer.
2845 * @param buf buffer to append to
2849 int32_t DecimalFormat::appendAffix(UnicodeString
& buf
, double number
,
2850 UBool isNegative
, UBool isPrefix
) const {
2851 if (fCurrencyChoice
!= 0) {
2852 const UnicodeString
* affixPat
;
2854 affixPat
= isNegative
? fNegPrefixPattern
: fPosPrefixPattern
;
2856 affixPat
= isNegative
? fNegSuffixPattern
: fPosSuffixPattern
;
2859 UnicodeString affixBuf
;
2860 expandAffix(*affixPat
, affixBuf
, number
, TRUE
);
2861 buf
.append(affixBuf
);
2862 return affixBuf
.length();
2864 // else someone called a function that reset the pattern.
2867 const UnicodeString
* affix
;
2869 affix
= isNegative
? &fNegativePrefix
: &fPositivePrefix
;
2871 affix
= isNegative
? &fNegativeSuffix
: &fPositiveSuffix
;
2874 return affix
->length();
2878 * Appends an affix pattern to the given StringBuffer, quoting special
2879 * characters as needed. Uses the internal affix pattern, if that exists,
2880 * or the literal affix, if the internal affix pattern is null. The
2881 * appended string will generate the same affix pattern (or literal affix)
2882 * when passed to toPattern().
2884 * @param appendTo the affix string is appended to this
2885 * @param affixPattern a pattern such as fPosPrefixPattern; may be null
2886 * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
2887 * Ignored unless affixPattern is null. If affixPattern is null, then
2888 * expAffix is appended as a literal affix.
2889 * @param localized true if the appended pattern should contain localized
2890 * pattern characters; otherwise, non-localized pattern chars are appended
2892 void DecimalFormat::appendAffixPattern(UnicodeString
& appendTo
,
2893 const UnicodeString
* affixPattern
,
2894 const UnicodeString
& expAffix
,
2895 UBool localized
) const {
2896 if (affixPattern
== 0) {
2897 appendAffixPattern(appendTo
, expAffix
, localized
);
2900 for (int pos
=0; pos
<affixPattern
->length(); pos
=i
) {
2901 i
= affixPattern
->indexOf(kQuote
, pos
);
2904 affixPattern
->extractBetween(pos
, affixPattern
->length(), s
);
2905 appendAffixPattern(appendTo
, s
, localized
);
2910 affixPattern
->extractBetween(pos
, i
, s
);
2911 appendAffixPattern(appendTo
, s
, localized
);
2913 UChar32 c
= affixPattern
->char32At(++i
);
2916 appendTo
.append(c
).append(c
);
2917 // Fall through and append another kQuote below
2918 } else if (c
== kCurrencySign
&&
2919 i
<affixPattern
->length() &&
2920 affixPattern
->char32At(i
) == kCurrencySign
) {
2922 appendTo
.append(c
).append(c
);
2923 } else if (localized
) {
2925 case kPatternPercent
:
2926 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPercentSymbol
);
2928 case kPatternPerMill
:
2929 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
);
2932 appendTo
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
2935 appendTo
+= getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
);
2948 * Append an affix to the given StringBuffer, using quotes if
2949 * there are special characters. Single quotes themselves must be
2950 * escaped in either case.
2953 DecimalFormat::appendAffixPattern(UnicodeString
& appendTo
,
2954 const UnicodeString
& affix
,
2955 UBool localized
) const {
2958 needQuote
= affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
)) >= 0
2959 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
)) >= 0
2960 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
)) >= 0
2961 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
)) >= 0
2962 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
)) >= 0
2963 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
)) >= 0
2964 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
)) >= 0
2965 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
)) >= 0
2966 || affix
.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)) >= 0
2967 || affix
.indexOf(kCurrencySign
) >= 0;
2970 needQuote
= affix
.indexOf(kPatternZeroDigit
) >= 0
2971 || affix
.indexOf(kPatternGroupingSeparator
) >= 0
2972 || affix
.indexOf(kPatternDecimalSeparator
) >= 0
2973 || affix
.indexOf(kPatternPercent
) >= 0
2974 || affix
.indexOf(kPatternPerMill
) >= 0
2975 || affix
.indexOf(kPatternDigit
) >= 0
2976 || affix
.indexOf(kPatternSeparator
) >= 0
2977 || affix
.indexOf(kPatternExponent
) >= 0
2978 || affix
.indexOf(kPatternPlus
) >= 0
2979 || affix
.indexOf(kPatternMinus
) >= 0
2980 || affix
.indexOf(kCurrencySign
) >= 0;
2983 appendTo
+= (UChar
)0x0027 /*'\''*/;
2984 if (affix
.indexOf((UChar
)0x0027 /*'\''*/) < 0)
2987 for (int32_t j
= 0; j
< affix
.length(); ) {
2988 UChar32 c
= affix
.char32At(j
);
2991 if (c
== 0x0027 /*'\''*/)
2996 appendTo
+= (UChar
)0x0027 /*'\''*/;
2999 //------------------------------------------------------------------------------
3002 DecimalFormat::toPattern(UnicodeString
& result
, UBool localized
) const
3005 UChar32 zero
, sigDigit
= kPatternSignificantDigit
;
3006 UnicodeString digit
, group
;
3008 int32_t roundingDecimalPos
= 0; // Pos of decimal in roundingDigits
3009 UnicodeString roundingDigits
;
3010 int32_t padPos
= (fFormatWidth
> 0) ? fPadPosition
: -1;
3011 UnicodeString padSpec
;
3012 UBool useSigDig
= areSignificantDigitsUsed();
3015 digit
.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
));
3016 group
.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
));
3017 zero
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
3019 sigDigit
= getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
).char32At(0);
3023 digit
.append((UChar
)kPatternDigit
);
3024 group
.append((UChar
)kPatternGroupingSeparator
);
3025 zero
= (UChar32
)kPatternZeroDigit
;
3027 if (fFormatWidth
> 0) {
3029 padSpec
.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
));
3032 padSpec
.append((UChar
)kPatternPadEscape
);
3034 padSpec
.append(fPad
);
3036 if (fRoundingIncrement
!= NULL
) {
3037 for(i
=0; i
<fRoundingIncrement
->fCount
; ++i
) {
3038 roundingDigits
.append((UChar
)fRoundingIncrement
->fDigits
[i
]);
3040 roundingDecimalPos
= fRoundingIncrement
->fDecimalAt
;
3042 for (int32_t part
=0; part
<2; ++part
) {
3043 if (padPos
== kPadBeforePrefix
) {
3044 result
.append(padSpec
);
3046 appendAffixPattern(result
,
3047 (part
==0 ? fPosPrefixPattern
: fNegPrefixPattern
),
3048 (part
==0 ? fPositivePrefix
: fNegativePrefix
),
3050 if (padPos
== kPadAfterPrefix
&& ! padSpec
.isEmpty()) {
3051 result
.append(padSpec
);
3053 int32_t sub0Start
= result
.length();
3054 int32_t g
= isGroupingUsed() ? _max(0, fGroupingSize
) : 0;
3055 if (g
> 0 && fGroupingSize2
> 0 && fGroupingSize2
!= fGroupingSize
) {
3056 g
+= fGroupingSize2
;
3058 int32_t maxDig
= 0, minDig
= 0, maxSigDig
= 0;
3060 minDig
= getMinimumSignificantDigits();
3061 maxDig
= maxSigDig
= getMaximumSignificantDigits();
3063 minDig
= getMinimumIntegerDigits();
3064 maxDig
= getMaximumIntegerDigits();
3066 if (fUseExponentialNotation
) {
3067 if (maxDig
> kMaxScientificIntegerDigits
) {
3070 } else if (useSigDig
) {
3071 maxDig
= _max(maxDig
, g
+1);
3073 maxDig
= _max(_max(g
, getMinimumIntegerDigits()),
3074 roundingDecimalPos
) + 1;
3076 for (i
= maxDig
; i
> 0; --i
) {
3077 if (!fUseExponentialNotation
&& i
<maxDig
&&
3078 isGroupingPosition(i
)) {
3079 result
.append(group
);
3082 // #@,@### (maxSigDig == 5, minSigDig == 2)
3083 // 65 4321 (1-based pos, count from the right)
3084 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
3085 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
3086 if (maxSigDig
>= i
&& i
> (maxSigDig
- minDig
)) {
3087 result
.append(sigDigit
);
3089 result
.append(digit
);
3092 if (! roundingDigits
.isEmpty()) {
3093 int32_t pos
= roundingDecimalPos
- i
;
3094 if (pos
>= 0 && pos
< roundingDigits
.length()) {
3095 result
.append((UChar
) (roundingDigits
.char32At(pos
) - kPatternZeroDigit
+ zero
));
3100 result
.append(zero
);
3102 result
.append(digit
);
3107 if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown
) {
3109 result
+= getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
);
3112 result
.append((UChar
)kPatternDecimalSeparator
);
3115 int32_t pos
= roundingDecimalPos
;
3116 for (i
= 0; i
< getMaximumFractionDigits(); ++i
) {
3117 if (! roundingDigits
.isEmpty() && pos
< roundingDigits
.length()) {
3119 result
.append(zero
);
3122 result
.append((UChar
)(roundingDigits
.char32At(pos
) - kPatternZeroDigit
+ zero
));
3127 if (i
<getMinimumFractionDigits()) {
3128 result
.append(zero
);
3131 result
.append(digit
);
3135 if (fUseExponentialNotation
) {
3137 result
+= getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
);
3140 result
.append((UChar
)kPatternExponent
);
3142 if (fExponentSignAlwaysShown
) {
3144 result
+= getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
);
3147 result
.append((UChar
)kPatternPlus
);
3150 for (i
=0; i
<fMinExponentDigits
; ++i
) {
3151 result
.append(zero
);
3154 if (! padSpec
.isEmpty() && !fUseExponentialNotation
) {
3155 int32_t add
= fFormatWidth
- result
.length() + sub0Start
3157 ? fPositivePrefix
.length() + fPositiveSuffix
.length()
3158 : fNegativePrefix
.length() + fNegativeSuffix
.length());
3160 result
.insert(sub0Start
, digit
);
3163 // Only add a grouping separator if we have at least
3164 // 2 additional characters to be added, so we don't
3165 // end up with ",###".
3166 if (add
>1 && isGroupingPosition(maxDig
)) {
3167 result
.insert(sub0Start
, group
);
3172 if (fPadPosition
== kPadBeforeSuffix
&& ! padSpec
.isEmpty()) {
3173 result
.append(padSpec
);
3176 appendAffixPattern(result
, fPosSuffixPattern
, fPositiveSuffix
, localized
);
3177 if (fPadPosition
== kPadAfterSuffix
&& ! padSpec
.isEmpty()) {
3178 result
.append(padSpec
);
3180 UBool isDefault
= FALSE
;
3181 if ((fNegSuffixPattern
== fPosSuffixPattern
&& // both null
3182 fNegativeSuffix
== fPositiveSuffix
)
3183 || (fNegSuffixPattern
!= 0 && fPosSuffixPattern
!= 0 &&
3184 *fNegSuffixPattern
== *fPosSuffixPattern
))
3186 if (fNegPrefixPattern
!= NULL
&& fPosPrefixPattern
!= NULL
)
3188 int32_t length
= fPosPrefixPattern
->length();
3189 isDefault
= fNegPrefixPattern
->length() == (length
+2) &&
3190 (*fNegPrefixPattern
)[(int32_t)0] == kQuote
&&
3191 (*fNegPrefixPattern
)[(int32_t)1] == kPatternMinus
&&
3192 fNegPrefixPattern
->compare(2, length
, *fPosPrefixPattern
, 0, length
) == 0;
3195 fNegPrefixPattern
== NULL
&& fPosPrefixPattern
== NULL
)
3197 int32_t length
= fPositivePrefix
.length();
3198 isDefault
= fNegativePrefix
.length() == (length
+1) &&
3199 fNegativePrefix
.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
)) == 0 &&
3200 fNegativePrefix
.compare(1, length
, fPositivePrefix
, 0, length
) == 0;
3204 break; // Don't output default negative subpattern
3207 result
+= getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
);
3210 result
.append((UChar
)kPatternSeparator
);
3214 appendAffixPattern(result
, fNegSuffixPattern
, fNegativeSuffix
, localized
);
3215 if (fPadPosition
== kPadAfterSuffix
&& ! padSpec
.isEmpty()) {
3216 result
.append(padSpec
);
3224 //------------------------------------------------------------------------------
3227 DecimalFormat::applyPattern(const UnicodeString
& pattern
, UErrorCode
& status
)
3229 UParseError parseError
;
3230 applyPattern(pattern
, FALSE
, parseError
, status
);
3233 //------------------------------------------------------------------------------
3236 DecimalFormat::applyPattern(const UnicodeString
& pattern
,
3237 UParseError
& parseError
,
3240 applyPattern(pattern
, FALSE
, parseError
, status
);
3242 //------------------------------------------------------------------------------
3245 DecimalFormat::applyLocalizedPattern(const UnicodeString
& pattern
, UErrorCode
& status
)
3247 UParseError parseError
;
3248 applyPattern(pattern
, TRUE
,parseError
,status
);
3251 //------------------------------------------------------------------------------
3254 DecimalFormat::applyLocalizedPattern(const UnicodeString
& pattern
,
3255 UParseError
& parseError
,
3258 applyPattern(pattern
, TRUE
,parseError
,status
);
3261 //------------------------------------------------------------------------------
3264 DecimalFormat::applyPattern(const UnicodeString
& pattern
,
3266 UParseError
& parseError
,
3269 if (U_FAILURE(status
))
3273 // Clear error struct
3274 parseError
.offset
= -1;
3275 parseError
.preContext
[0] = parseError
.postContext
[0] = (UChar
)0;
3277 // Set the significant pattern symbols
3278 UChar32 zeroDigit
= kPatternZeroDigit
; // '0'
3279 UChar32 sigDigit
= kPatternSignificantDigit
; // '@'
3280 UnicodeString
groupingSeparator ((UChar
)kPatternGroupingSeparator
);
3281 UnicodeString
decimalSeparator ((UChar
)kPatternDecimalSeparator
);
3282 UnicodeString
percent ((UChar
)kPatternPercent
);
3283 UnicodeString
perMill ((UChar
)kPatternPerMill
);
3284 UnicodeString
digit ((UChar
)kPatternDigit
); // '#'
3285 UnicodeString
separator ((UChar
)kPatternSeparator
);
3286 UnicodeString
exponent ((UChar
)kPatternExponent
);
3287 UnicodeString
plus ((UChar
)kPatternPlus
);
3288 UnicodeString
minus ((UChar
)kPatternMinus
);
3289 UnicodeString
padEscape ((UChar
)kPatternPadEscape
);
3290 // Substitute with the localized symbols if necessary
3292 zeroDigit
= getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol
).char32At(0);
3293 sigDigit
= getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol
).char32At(0);
3294 groupingSeparator
. remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol
));
3295 decimalSeparator
. remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol
));
3296 percent
. remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol
));
3297 perMill
. remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
));
3298 digit
. remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol
));
3299 separator
. remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol
));
3300 exponent
. remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol
));
3301 plus
. remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
));
3302 minus
. remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
));
3303 padEscape
. remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol
));
3305 UChar nineDigit
= (UChar
)(zeroDigit
+ 9);
3306 int32_t digitLen
= digit
.length();
3307 int32_t groupSepLen
= groupingSeparator
.length();
3308 int32_t decimalSepLen
= decimalSeparator
.length();
3311 int32_t patLen
= pattern
.length();
3312 // Part 0 is the positive pattern. Part 1, if present, is the negative
3314 for (int32_t part
=0; part
<2 && pos
<patLen
; ++part
) {
3315 // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
3316 // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is
3317 // between the prefix and suffix, and consists of pattern
3318 // characters. In the prefix and suffix, percent, perMill, and
3319 // currency symbols are recognized and translated.
3320 int32_t subpart
= 1, sub0Start
= 0, sub0Limit
= 0, sub2Limit
= 0;
3322 // It's important that we don't change any fields of this object
3323 // prematurely. We set the following variables for the multiplier,
3324 // grouping, etc., and then only change the actual object fields if
3325 // everything parses correctly. This also lets us register
3326 // the data from part 0 and ignore the part 1, except for the
3327 // prefix and suffix.
3328 UnicodeString prefix
;
3329 UnicodeString suffix
;
3330 int32_t decimalPos
= -1;
3331 int32_t multiplier
= 1;
3332 int32_t digitLeftCount
= 0, zeroDigitCount
= 0, digitRightCount
= 0, sigDigitCount
= 0;
3333 int8_t groupingCount
= -1;
3334 int8_t groupingCount2
= -1;
3335 int32_t padPos
= -1;
3336 UChar32 padChar
= 0;
3337 int32_t roundingPos
= -1;
3338 DigitList roundingInc
;
3339 int8_t expDigits
= -1;
3340 UBool expSignAlways
= FALSE
;
3341 UBool isCurrency
= FALSE
;
3343 // The affix is either the prefix or the suffix.
3344 UnicodeString
* affix
= &prefix
;
3346 int32_t start
= pos
;
3347 UBool isPartDone
= FALSE
;
3350 for (; !isPartDone
&& pos
< patLen
; ) {
3351 // Todo: account for surrogate pairs
3352 ch
= pattern
.char32At(pos
);
3354 case 0: // Pattern proper subpart (between prefix & suffix)
3355 // Process the digits, decimal, and grouping characters. We
3356 // record five pieces of information. We expect the digits
3357 // to occur in the pattern ####00.00####, and we record the
3358 // number of left digits, zero (central) digits, and right
3359 // digits. The position of the last grouping character is
3360 // recorded (should be somewhere within the first two blocks
3361 // of characters), as is the position of the decimal point,
3362 // if any (should be in the zero digits). If there is no
3363 // decimal point, then there should be no right digits.
3364 if (pattern
.compare(pos
, digitLen
, digit
) == 0) {
3365 if (zeroDigitCount
> 0 || sigDigitCount
> 0) {
3370 if (groupingCount
>= 0 && decimalPos
< 0) {
3374 } else if ((ch
>= zeroDigit
&& ch
<= nineDigit
) ||
3376 if (digitRightCount
> 0) {
3378 debug("Unexpected '0'")
3379 status
= U_UNEXPECTED_TOKEN
;
3380 syntaxError(pattern
,pos
,parseError
);
3383 if (ch
== sigDigit
) {
3387 if (ch
!= zeroDigit
&& roundingPos
< 0) {
3388 roundingPos
= digitLeftCount
+ zeroDigitCount
;
3390 if (roundingPos
>= 0) {
3391 roundingInc
.append((char)(ch
- zeroDigit
+ '0'));
3394 if (groupingCount
>= 0 && decimalPos
< 0) {
3397 pos
+= U16_LENGTH(ch
);
3398 } else if (pattern
.compare(pos
, groupSepLen
, groupingSeparator
) == 0) {
3399 if (decimalPos
>= 0) {
3400 // Grouping separator after decimal
3401 debug("Grouping separator after decimal")
3402 status
= U_UNEXPECTED_TOKEN
;
3403 syntaxError(pattern
,pos
,parseError
);
3406 groupingCount2
= groupingCount
;
3409 } else if (pattern
.compare(pos
, decimalSepLen
, decimalSeparator
) == 0) {
3410 if (decimalPos
>= 0) {
3411 // Multiple decimal separators
3412 debug("Multiple decimal separators")
3413 status
= U_MULTIPLE_DECIMAL_SEPARATORS
;
3414 syntaxError(pattern
,pos
,parseError
);
3417 // Intentionally incorporate the digitRightCount,
3418 // even though it is illegal for this to be > 0
3419 // at this point. We check pattern syntax below.
3420 decimalPos
= digitLeftCount
+ zeroDigitCount
+ digitRightCount
;
3421 pos
+= decimalSepLen
;
3423 if (pattern
.compare(pos
, exponent
.length(), exponent
) == 0) {
3424 if (expDigits
>= 0) {
3425 // Multiple exponential symbols
3426 debug("Multiple exponential symbols")
3427 status
= U_MULTIPLE_EXPONENTIAL_SYMBOLS
;
3428 syntaxError(pattern
,pos
,parseError
);
3431 if (groupingCount
>= 0) {
3432 // Grouping separator in exponential pattern
3433 debug("Grouping separator in exponential pattern")
3434 status
= U_MALFORMED_EXPONENTIAL_PATTERN
;
3435 syntaxError(pattern
,pos
,parseError
);
3438 pos
+= exponent
.length();
3439 // Check for positive prefix
3441 && pattern
.compare(pos
, plus
.length(), plus
) == 0) {
3442 expSignAlways
= TRUE
;
3443 pos
+= plus
.length();
3445 // Use lookahead to parse out the exponential part of the
3446 // pattern, then jump into suffix subpart.
3448 while (pos
< patLen
&&
3449 pattern
.char32At(pos
) == zeroDigit
) {
3451 pos
+= U16_LENGTH(zeroDigit
);
3454 // 1. Require at least one mantissa pattern digit
3455 // 2. Disallow "#+ @" in mantissa
3456 // 3. Require at least one exponent pattern digit
3457 if (((digitLeftCount
+ zeroDigitCount
) < 1 &&
3458 (sigDigitCount
+ digitRightCount
) < 1) ||
3459 (sigDigitCount
> 0 && digitLeftCount
> 0) ||
3461 // Malformed exponential pattern
3462 debug("Malformed exponential pattern")
3463 status
= U_MALFORMED_EXPONENTIAL_PATTERN
;
3464 syntaxError(pattern
,pos
,parseError
);
3468 // Transition to suffix subpart
3469 subpart
= 2; // suffix subpart
3475 case 1: // Prefix subpart
3476 case 2: // Suffix subpart
3477 // Process the prefix / suffix characters
3478 // Process unquoted characters seen in prefix or suffix
3481 // Several syntax characters implicitly begins the
3482 // next subpart if we are in the prefix; otherwise
3483 // they are illegal if unquoted.
3484 if (!pattern
.compare(pos
, digitLen
, digit
) ||
3485 !pattern
.compare(pos
, groupSepLen
, groupingSeparator
) ||
3486 !pattern
.compare(pos
, decimalSepLen
, decimalSeparator
) ||
3487 (ch
>= zeroDigit
&& ch
<= nineDigit
) ||
3489 if (subpart
== 1) { // prefix subpart
3490 subpart
= 0; // pattern proper subpart
3491 sub0Start
= pos
; // Reprocess this character
3494 status
= U_UNQUOTED_SPECIAL
;
3495 syntaxError(pattern
,pos
,parseError
);
3498 } else if (ch
== kCurrencySign
) {
3499 affix
->append(kQuote
); // Encode currency
3500 // Use lookahead to determine if the currency sign is
3502 U_ASSERT(U16_LENGTH(kCurrencySign
) == 1);
3503 if ((pos
+1) < pattern
.length() && pattern
[pos
+1] == kCurrencySign
) {
3504 affix
->append(kCurrencySign
);
3505 ++pos
; // Skip over the doubled character
3508 // Fall through to append(ch)
3509 } else if (ch
== kQuote
) {
3510 // A quote outside quotes indicates either the opening
3511 // quote or two quotes, which is a quote literal. That is,
3512 // we have the first quote in 'do' or o''clock.
3513 U_ASSERT(U16_LENGTH(kQuote
) == 1);
3515 if (pos
< pattern
.length() && pattern
[pos
] == kQuote
) {
3516 affix
->append(kQuote
); // Encode quote
3517 // Fall through to append(ch)
3519 subpart
+= 2; // open quote
3522 } else if (pattern
.compare(pos
, separator
.length(), separator
) == 0) {
3523 // Don't allow separators in the prefix, and don't allow
3524 // separators in the second pattern (part == 1).
3525 if (subpart
== 1 || part
== 1) {
3526 // Unexpected separator
3527 debug("Unexpected separator")
3528 status
= U_UNEXPECTED_TOKEN
;
3529 syntaxError(pattern
,pos
,parseError
);
3533 isPartDone
= TRUE
; // Go to next part
3534 pos
+= separator
.length();
3536 } else if (pattern
.compare(pos
, percent
.length(), percent
) == 0) {
3537 // Next handle characters which are appended directly.
3538 if (multiplier
!= 1) {
3539 // Too many percent/perMill characters
3540 debug("Too many percent characters")
3541 status
= U_MULTIPLE_PERCENT_SYMBOLS
;
3542 syntaxError(pattern
,pos
,parseError
);
3545 affix
->append(kQuote
); // Encode percent/perMill
3546 affix
->append(kPatternPercent
); // Use unlocalized pattern char
3548 pos
+= percent
.length();
3550 } else if (pattern
.compare(pos
, perMill
.length(), perMill
) == 0) {
3551 // Next handle characters which are appended directly.
3552 if (multiplier
!= 1) {
3553 // Too many percent/perMill characters
3554 debug("Too many perMill characters")
3555 status
= U_MULTIPLE_PERMILL_SYMBOLS
;
3556 syntaxError(pattern
,pos
,parseError
);
3559 affix
->append(kQuote
); // Encode percent/perMill
3560 affix
->append(kPatternPerMill
); // Use unlocalized pattern char
3562 pos
+= perMill
.length();
3564 } else if (pattern
.compare(pos
, padEscape
.length(), padEscape
) == 0) {
3565 if (padPos
>= 0 || // Multiple pad specifiers
3566 (pos
+1) == pattern
.length()) { // Nothing after padEscape
3567 debug("Multiple pad specifiers")
3568 status
= U_MULTIPLE_PAD_SPECIFIERS
;
3569 syntaxError(pattern
,pos
,parseError
);
3573 pos
+= padEscape
.length();
3574 padChar
= pattern
.char32At(pos
);
3575 pos
+= U16_LENGTH(padChar
);
3577 } else if (pattern
.compare(pos
, minus
.length(), minus
) == 0) {
3578 affix
->append(kQuote
); // Encode minus
3579 affix
->append(kPatternMinus
);
3580 pos
+= minus
.length();
3582 } else if (pattern
.compare(pos
, plus
.length(), plus
) == 0) {
3583 affix
->append(kQuote
); // Encode plus
3584 affix
->append(kPatternPlus
);
3585 pos
+= plus
.length();
3588 // Unquoted, non-special characters fall through to here, as
3589 // well as other code which needs to append something to the
3592 pos
+= U16_LENGTH(ch
);
3594 case 3: // Prefix subpart, in quote
3595 case 4: // Suffix subpart, in quote
3596 // A quote within quotes indicates either the closing
3597 // quote or two quotes, which is a quote literal. That is,
3598 // we have the second quote in 'do' or 'don''t'.
3601 if (pos
< pattern
.length() && pattern
[pos
] == kQuote
) {
3602 affix
->append(kQuote
); // Encode quote
3603 // Fall through to append(ch)
3605 subpart
-= 2; // close quote
3610 pos
+= U16_LENGTH(ch
);
3615 if (sub0Limit
== 0) {
3616 sub0Limit
= pattern
.length();
3619 if (sub2Limit
== 0) {
3620 sub2Limit
= pattern
.length();
3623 /* Handle patterns with no '0' pattern character. These patterns
3624 * are legal, but must be recodified to make sense. "##.###" ->
3625 * "#0.###". ".###" -> ".0##".
3627 * We allow patterns of the form "####" to produce a zeroDigitCount
3628 * of zero (got that?); although this seems like it might make it
3629 * possible for format() to produce empty strings, format() checks
3630 * for this condition and outputs a zero digit in this situation.
3631 * Having a zeroDigitCount of zero yields a minimum integer digits
3632 * of zero, which allows proper round-trip patterns. We don't want
3633 * "#" to become "#0" when toPattern() is called (even though that's
3634 * what it really is, semantically).
3636 if (zeroDigitCount
== 0 && sigDigitCount
== 0 &&
3637 digitLeftCount
> 0 && decimalPos
>= 0) {
3638 // Handle "###.###" and "###." and ".###"
3641 ++n
; // Handle ".###"
3642 digitRightCount
= digitLeftCount
- n
;
3643 digitLeftCount
= n
- 1;
3647 // Do syntax checking on the digits, decimal points, and quotes.
3648 if ((decimalPos
< 0 && digitRightCount
> 0 && sigDigitCount
== 0) ||
3650 (sigDigitCount
> 0 ||
3651 decimalPos
< digitLeftCount
||
3652 decimalPos
> (digitLeftCount
+ zeroDigitCount
))) ||
3653 groupingCount
== 0 || groupingCount2
== 0 ||
3654 (sigDigitCount
> 0 && zeroDigitCount
> 0) ||
3656 { // subpart > 2 == unmatched quote
3657 debug("Syntax error")
3658 status
= U_PATTERN_SYNTAX_ERROR
;
3659 syntaxError(pattern
,pos
,parseError
);
3663 // Make sure pad is at legal position before or after affix.
3665 if (padPos
== start
) {
3666 padPos
= kPadBeforePrefix
;
3667 } else if (padPos
+2 == sub0Start
) {
3668 padPos
= kPadAfterPrefix
;
3669 } else if (padPos
== sub0Limit
) {
3670 padPos
= kPadBeforeSuffix
;
3671 } else if (padPos
+2 == sub2Limit
) {
3672 padPos
= kPadAfterSuffix
;
3674 // Illegal pad position
3675 debug("Illegal pad position")
3676 status
= U_ILLEGAL_PAD_POSITION
;
3677 syntaxError(pattern
,pos
,parseError
);
3683 delete fPosPrefixPattern
;
3684 delete fPosSuffixPattern
;
3685 delete fNegPrefixPattern
;
3686 delete fNegSuffixPattern
;
3687 fPosPrefixPattern
= new UnicodeString(prefix
);
3689 if (fPosPrefixPattern
== 0) {
3690 status
= U_MEMORY_ALLOCATION_ERROR
;
3693 fPosSuffixPattern
= new UnicodeString(suffix
);
3695 if (fPosSuffixPattern
== 0) {
3696 status
= U_MEMORY_ALLOCATION_ERROR
;
3697 delete fPosPrefixPattern
;
3700 fNegPrefixPattern
= 0;
3701 fNegSuffixPattern
= 0;
3703 fUseExponentialNotation
= (expDigits
>= 0);
3704 if (fUseExponentialNotation
) {
3705 fMinExponentDigits
= expDigits
;
3707 fExponentSignAlwaysShown
= expSignAlways
;
3708 fIsCurrencyFormat
= isCurrency
;
3709 int32_t digitTotalCount
= digitLeftCount
+ zeroDigitCount
+ digitRightCount
;
3710 // The effectiveDecimalPos is the position the decimal is at or
3711 // would be at if there is no decimal. Note that if
3712 // decimalPos<0, then digitTotalCount == digitLeftCount +
3714 int32_t effectiveDecimalPos
= decimalPos
>= 0 ? decimalPos
: digitTotalCount
;
3715 UBool isSigDig
= (sigDigitCount
> 0);
3716 setSignificantDigitsUsed(isSigDig
);
3718 setMinimumSignificantDigits(sigDigitCount
);
3719 setMaximumSignificantDigits(sigDigitCount
+ digitRightCount
);
3721 int32_t minInt
= effectiveDecimalPos
- digitLeftCount
;
3722 setMinimumIntegerDigits(minInt
);
3723 setMaximumIntegerDigits(fUseExponentialNotation
3724 ? digitLeftCount
+ getMinimumIntegerDigits()
3725 : kDoubleIntegerDigits
);
3726 setMaximumFractionDigits(decimalPos
>= 0
3727 ? (digitTotalCount
- decimalPos
) : 0);
3728 setMinimumFractionDigits(decimalPos
>= 0
3729 ? (digitLeftCount
+ zeroDigitCount
- decimalPos
) : 0);
3731 setGroupingUsed(groupingCount
> 0);
3732 fGroupingSize
= (groupingCount
> 0) ? groupingCount
: 0;
3733 fGroupingSize2
= (groupingCount2
> 0 && groupingCount2
!= groupingCount
)
3734 ? groupingCount2
: 0;
3735 fMultiplier
= multiplier
;
3736 setDecimalSeparatorAlwaysShown(decimalPos
== 0
3737 || decimalPos
== digitTotalCount
);
3739 fPadPosition
= (EPadPosition
) padPos
;
3740 // To compute the format width, first set up sub0Limit -
3741 // sub0Start. Add in prefix/suffix length later.
3743 // fFormatWidth = prefix.length() + suffix.length() +
3744 // sub0Limit - sub0Start;
3745 fFormatWidth
= sub0Limit
- sub0Start
;
3750 if (roundingPos
>= 0) {
3751 roundingInc
.fDecimalAt
= effectiveDecimalPos
- roundingPos
;
3752 if (fRoundingIncrement
!= NULL
) {
3753 *fRoundingIncrement
= roundingInc
;
3755 fRoundingIncrement
= new DigitList(roundingInc
);
3757 if (fRoundingIncrement
== 0) {
3758 status
= U_MEMORY_ALLOCATION_ERROR
;
3759 delete fPosPrefixPattern
;
3760 delete fPosSuffixPattern
;
3764 fRoundingDouble
= fRoundingIncrement
->getDouble();
3765 fRoundingMode
= kRoundHalfEven
;
3767 setRoundingIncrement(0.0);
3770 fNegPrefixPattern
= new UnicodeString(prefix
);
3772 if (fNegPrefixPattern
== 0) {
3773 status
= U_MEMORY_ALLOCATION_ERROR
;
3776 fNegSuffixPattern
= new UnicodeString(suffix
);
3778 if (fNegSuffixPattern
== 0) {
3779 delete fNegPrefixPattern
;
3780 status
= U_MEMORY_ALLOCATION_ERROR
;
3786 if (pattern
.length() == 0) {
3787 delete fNegPrefixPattern
;
3788 delete fNegSuffixPattern
;
3789 fNegPrefixPattern
= NULL
;
3790 fNegSuffixPattern
= NULL
;
3791 if (fPosPrefixPattern
!= NULL
) {
3792 fPosPrefixPattern
->remove();
3794 fPosPrefixPattern
= new UnicodeString();
3796 if (fPosPrefixPattern
== 0) {
3797 status
= U_MEMORY_ALLOCATION_ERROR
;
3801 if (fPosSuffixPattern
!= NULL
) {
3802 fPosSuffixPattern
->remove();
3804 fPosSuffixPattern
= new UnicodeString();
3806 if (fPosSuffixPattern
== 0) {
3807 delete fPosPrefixPattern
;
3808 status
= U_MEMORY_ALLOCATION_ERROR
;
3813 setMinimumIntegerDigits(0);
3814 setMaximumIntegerDigits(kDoubleIntegerDigits
);
3815 setMinimumFractionDigits(0);
3816 setMaximumFractionDigits(kDoubleFractionDigits
);
3818 fUseExponentialNotation
= FALSE
;
3819 fIsCurrencyFormat
= FALSE
;
3820 setGroupingUsed(FALSE
);
3824 setDecimalSeparatorAlwaysShown(FALSE
);
3826 setRoundingIncrement(0.0);
3829 // If there was no negative pattern, or if the negative pattern is
3830 // identical to the positive pattern, then prepend the minus sign to the
3831 // positive pattern to form the negative pattern.
3832 if (fNegPrefixPattern
== NULL
||
3833 (*fNegPrefixPattern
== *fPosPrefixPattern
3834 && *fNegSuffixPattern
== *fPosSuffixPattern
)) {
3835 _copy_us_ptr(&fNegSuffixPattern
, fPosSuffixPattern
);
3836 if (fNegPrefixPattern
== NULL
) {
3837 fNegPrefixPattern
= new UnicodeString();
3839 if (fNegPrefixPattern
== 0) {
3840 status
= U_MEMORY_ALLOCATION_ERROR
;
3844 fNegPrefixPattern
->remove();
3846 fNegPrefixPattern
->append(kQuote
).append(kPatternMinus
)
3847 .append(*fPosPrefixPattern
);
3851 s
.append("\"").append(pattern
).append("\"->");
3855 if (fFormatWidth
> 0) {
3856 // Finish computing format width (see above)
3857 fFormatWidth
+= fPositivePrefix
.length() + fPositiveSuffix
.length();
3862 * Sets the maximum number of digits allowed in the integer portion of a
3863 * number. This override limits the integer digit count to 309.
3864 * @see NumberFormat#setMaximumIntegerDigits
3866 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue
) {
3867 NumberFormat::setMaximumIntegerDigits(_min(newValue
, kDoubleIntegerDigits
));
3871 * Sets the minimum number of digits allowed in the integer portion of a
3872 * number. This override limits the integer digit count to 309.
3873 * @see NumberFormat#setMinimumIntegerDigits
3875 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue
) {
3876 NumberFormat::setMinimumIntegerDigits(_min(newValue
, kDoubleIntegerDigits
));
3880 * Sets the maximum number of digits allowed in the fraction portion of a
3881 * number. This override limits the fraction digit count to 340.
3882 * @see NumberFormat#setMaximumFractionDigits
3884 void DecimalFormat::setMaximumFractionDigits(int32_t newValue
) {
3885 NumberFormat::setMaximumFractionDigits(_min(newValue
, kDoubleFractionDigits
));
3889 * Sets the minimum number of digits allowed in the fraction portion of a
3890 * number. This override limits the fraction digit count to 340.
3891 * @see NumberFormat#setMinimumFractionDigits
3893 void DecimalFormat::setMinimumFractionDigits(int32_t newValue
) {
3894 NumberFormat::setMinimumFractionDigits(_min(newValue
, kDoubleFractionDigits
));
3897 int32_t DecimalFormat::getMinimumSignificantDigits() const {
3898 return fMinSignificantDigits
;
3901 int32_t DecimalFormat::getMaximumSignificantDigits() const {
3902 return fMaxSignificantDigits
;
3905 void DecimalFormat::setMinimumSignificantDigits(int32_t min
) {
3909 // pin max sig dig to >= min
3910 int32_t max
= _max(fMaxSignificantDigits
, min
);
3911 fMinSignificantDigits
= min
;
3912 fMaxSignificantDigits
= max
;
3915 void DecimalFormat::setMaximumSignificantDigits(int32_t max
) {
3919 // pin min sig dig to 1..max
3920 U_ASSERT(fMinSignificantDigits
>= 1);
3921 int32_t min
= _min(fMinSignificantDigits
, max
);
3922 fMinSignificantDigits
= min
;
3923 fMaxSignificantDigits
= max
;
3926 UBool
DecimalFormat::areSignificantDigitsUsed() const {
3927 return fUseSignificantDigits
;
3930 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits
) {
3931 fUseSignificantDigits
= useSignificantDigits
;
3934 void DecimalFormat::setCurrency(const UChar
* theCurrency
, UErrorCode
& ec
) {
3935 // If we are a currency format, then modify our affixes to
3936 // encode the currency symbol for the given currency in our
3937 // locale, and adjust the decimal digits and rounding for the
3940 // Note: The code is ordered so that this object is *not changed*
3941 // until we are sure we are going to succeed.
3943 // NULL or empty currency is *legal* and indicates no currency.
3944 UBool isCurr
= (theCurrency
&& *theCurrency
);
3946 double rounding
= 0.0;
3948 if (fIsCurrencyFormat
&& isCurr
) {
3949 rounding
= ucurr_getRoundingIncrement(theCurrency
, &ec
);
3950 frac
= ucurr_getDefaultFractionDigits(theCurrency
, &ec
);
3953 NumberFormat::setCurrency(theCurrency
, ec
);
3954 if (U_FAILURE(ec
)) return;
3956 if (fIsCurrencyFormat
) {
3957 // NULL or empty currency is *legal* and indicates no currency.
3959 setRoundingIncrement(rounding
);
3960 setMinimumFractionDigits(frac
);
3961 setMaximumFractionDigits(frac
);
3967 // Deprecated variant with no UErrorCode parameter
3968 void DecimalFormat::setCurrency(const UChar
* theCurrency
) {
3969 UErrorCode ec
= U_ZERO_ERROR
;
3970 setCurrency(theCurrency
, ec
);
3973 void DecimalFormat::getEffectiveCurrency(UChar
* result
, UErrorCode
& ec
) const {
3974 if (fSymbols
== NULL
) {
3975 ec
= U_MEMORY_ALLOCATION_ERROR
;
3979 const UChar
* c
= getCurrency();
3981 const UnicodeString
&intl
=
3982 fSymbols
->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol
);
3983 c
= intl
.getBuffer(); // ok for intl to go out of scope
3985 u_strncpy(result
, c
, 3);
3990 * Return the number of fraction digits to display, or the total
3991 * number of digits for significant digit formats and exponential
3995 DecimalFormat::precision(UBool isIntegral
) const {
3996 if (areSignificantDigitsUsed()) {
3997 return getMaximumSignificantDigits();
3998 } else if (fUseExponentialNotation
) {
3999 return getMinimumIntegerDigits() + getMaximumFractionDigits();
4001 return isIntegral
? 0 : getMaximumFractionDigits();
4007 #endif /* #if !UCONFIG_NO_FORMATTING */