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