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