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