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