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