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