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