]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/decimfmt.cpp
ICU-461.18.tar.gz
[apple/icu.git] / icuSources / i18n / decimfmt.cpp
1 /*
2 *******************************************************************************
3 * Copyright (C) 1997-2011, 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 "fphdlimp.h"
45 #include "unicode/decimfmt.h"
46 #include "unicode/choicfmt.h"
47 #include "unicode/ucurr.h"
48 #include "unicode/ustring.h"
49 #include "unicode/dcfmtsym.h"
50 #include "unicode/ures.h"
51 #include "unicode/uchar.h"
52 #include "unicode/uniset.h"
53 #include "unicode/curramt.h"
54 #include "unicode/currpinf.h"
55 #include "unicode/plurrule.h"
56 #include "decfmtst.h"
57 #include "ucurrimp.h"
58 #include "charstr.h"
59 #include "cmemory.h"
60 #include "util.h"
61 #include "digitlst.h"
62 #include "cstring.h"
63 #include "umutex.h"
64 #include "uassert.h"
65 #include "putilimp.h"
66 #include <math.h>
67 #include "hash.h"
68
69
70 U_NAMESPACE_BEGIN
71
72 /* For currency parsing purose,
73 * Need to remember all prefix patterns and suffix patterns of
74 * every currency format pattern,
75 * including the pattern of default currecny style
76 * and plural currency style. And the patterns are set through applyPattern.
77 */
78 struct AffixPatternsForCurrency : public UMemory {
79 // negative prefix pattern
80 UnicodeString negPrefixPatternForCurrency;
81 // negative suffix pattern
82 UnicodeString negSuffixPatternForCurrency;
83 // positive prefix pattern
84 UnicodeString posPrefixPatternForCurrency;
85 // positive suffix pattern
86 UnicodeString posSuffixPatternForCurrency;
87 int8_t patternType;
88
89 AffixPatternsForCurrency(const UnicodeString& negPrefix,
90 const UnicodeString& negSuffix,
91 const UnicodeString& posPrefix,
92 const UnicodeString& posSuffix,
93 int8_t type) {
94 negPrefixPatternForCurrency = negPrefix;
95 negSuffixPatternForCurrency = negSuffix;
96 posPrefixPatternForCurrency = posPrefix;
97 posSuffixPatternForCurrency = posSuffix;
98 patternType = type;
99 }
100 };
101
102 /* affix for currency formatting when the currency sign in the pattern
103 * equals to 3, such as the pattern contains 3 currency sign or
104 * the formatter style is currency plural format style.
105 */
106 struct AffixesForCurrency : public UMemory {
107 // negative prefix
108 UnicodeString negPrefixForCurrency;
109 // negative suffix
110 UnicodeString negSuffixForCurrency;
111 // positive prefix
112 UnicodeString posPrefixForCurrency;
113 // positive suffix
114 UnicodeString posSuffixForCurrency;
115
116 int32_t formatWidth;
117
118 AffixesForCurrency(const UnicodeString& negPrefix,
119 const UnicodeString& negSuffix,
120 const UnicodeString& posPrefix,
121 const UnicodeString& posSuffix) {
122 negPrefixForCurrency = negPrefix;
123 negSuffixForCurrency = negSuffix;
124 posPrefixForCurrency = posPrefix;
125 posSuffixForCurrency = posSuffix;
126 }
127 };
128
129 U_CDECL_BEGIN
130
131 /**
132 * @internal ICU 4.2
133 */
134 static UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2);
135
136 /**
137 * @internal ICU 4.2
138 */
139 static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2);
140
141
142 static UBool
143 U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2) {
144 const AffixesForCurrency* affix_1 =
145 (AffixesForCurrency*)val1.pointer;
146 const AffixesForCurrency* affix_2 =
147 (AffixesForCurrency*)val2.pointer;
148 return affix_1->negPrefixForCurrency == affix_2->negPrefixForCurrency &&
149 affix_1->negSuffixForCurrency == affix_2->negSuffixForCurrency &&
150 affix_1->posPrefixForCurrency == affix_2->posPrefixForCurrency &&
151 affix_1->posSuffixForCurrency == affix_2->posSuffixForCurrency;
152 }
153
154
155 static UBool
156 U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) {
157 const AffixPatternsForCurrency* affix_1 =
158 (AffixPatternsForCurrency*)val1.pointer;
159 const AffixPatternsForCurrency* affix_2 =
160 (AffixPatternsForCurrency*)val2.pointer;
161 return affix_1->negPrefixPatternForCurrency ==
162 affix_2->negPrefixPatternForCurrency &&
163 affix_1->negSuffixPatternForCurrency ==
164 affix_2->negSuffixPatternForCurrency &&
165 affix_1->posPrefixPatternForCurrency ==
166 affix_2->posPrefixPatternForCurrency &&
167 affix_1->posSuffixPatternForCurrency ==
168 affix_2->posSuffixPatternForCurrency &&
169 affix_1->patternType == affix_2->patternType;
170 }
171
172 U_CDECL_END
173
174
175 //#define FMT_DEBUG
176
177 #ifdef FMT_DEBUG
178 #include <stdio.h>
179 static void debugout(UnicodeString s) {
180 char buf[2000];
181 s.extract((int32_t) 0, s.length(), buf);
182 printf("%s\n", buf);
183 }
184 #define debug(x) printf("%s\n", x);
185 #else
186 #define debugout(x)
187 #define debug(x)
188 #endif
189
190 // Set to 1 to make leading zeroes be an error when doing a strict parse.
191 // Decided in ICU mtg 2010-04-21 that an error for leading zeros is wrong for
192 // strict parsing in both ICU4C & ICU4J, so this goes off (and ICU4J will be fixed).
193 #define CHECK_FOR_LEADING_ZERO 0
194
195 // *****************************************************************************
196 // class DecimalFormat
197 // *****************************************************************************
198
199 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
200
201 // Constants for characters used in programmatic (unlocalized) patterns.
202 #define kPatternZeroDigit ((UChar)0x0030) /*'0'*/
203 #define kPatternSignificantDigit ((UChar)0x0040) /*'@'*/
204 #define kPatternGroupingSeparator ((UChar)0x002C) /*','*/
205 #define kPatternDecimalSeparator ((UChar)0x002E) /*'.'*/
206 #define kPatternPerMill ((UChar)0x2030)
207 #define kPatternPercent ((UChar)0x0025) /*'%'*/
208 #define kPatternDigit ((UChar)0x0023) /*'#'*/
209 #define kPatternSeparator ((UChar)0x003B) /*';'*/
210 #define kPatternExponent ((UChar)0x0045) /*'E'*/
211 #define kPatternPlus ((UChar)0x002B) /*'+'*/
212 #define kPatternMinus ((UChar)0x002D) /*'-'*/
213 #define kPatternPadEscape ((UChar)0x002A) /*'*'*/
214 #define kQuote ((UChar)0x0027) /*'\''*/
215 /**
216 * The CURRENCY_SIGN is the standard Unicode symbol for currency. It
217 * is used in patterns and substitued with either the currency symbol,
218 * or if it is doubled, with the international currency symbol. If the
219 * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
220 * replaced with the monetary decimal separator.
221 */
222 #define kCurrencySign ((UChar)0x00A4)
223 #define kDefaultPad ((UChar)0x0020) /* */
224
225 const int32_t DecimalFormat::kDoubleIntegerDigits = 309;
226 const int32_t DecimalFormat::kDoubleFractionDigits = 340;
227
228 const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
229
230 /**
231 * These are the tags we expect to see in normal resource bundle files associated
232 * with a locale.
233 */
234 const char DecimalFormat::fgNumberPatterns[]="NumberPatterns"; // Deprecated - not used
235 static const char fgNumberElements[]="NumberElements";
236 static const char fgLatn[]="latn";
237 static const char fgPatterns[]="patterns";
238 static const char fgDecimalFormat[]="decimalFormat";
239 static const char fgCurrencyFormat[]="currencyFormat";
240 static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0};
241
242 inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; }
243 inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; }
244
245 //------------------------------------------------------------------------------
246 // Constructs a DecimalFormat instance in the default locale.
247
248 DecimalFormat::DecimalFormat(UErrorCode& status) {
249 init();
250 UParseError parseError;
251 construct(status, parseError);
252 }
253
254 //------------------------------------------------------------------------------
255 // Constructs a DecimalFormat instance with the specified number format
256 // pattern in the default locale.
257
258 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
259 UErrorCode& status) {
260 init();
261 UParseError parseError;
262 construct(status, parseError, &pattern);
263 }
264
265 //------------------------------------------------------------------------------
266 // Constructs a DecimalFormat instance with the specified number format
267 // pattern and the number format symbols in the default locale. The
268 // created instance owns the symbols.
269
270 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
271 DecimalFormatSymbols* symbolsToAdopt,
272 UErrorCode& status) {
273 init();
274 UParseError parseError;
275 if (symbolsToAdopt == NULL)
276 status = U_ILLEGAL_ARGUMENT_ERROR;
277 construct(status, parseError, &pattern, symbolsToAdopt);
278 }
279
280 DecimalFormat::DecimalFormat( const UnicodeString& pattern,
281 DecimalFormatSymbols* symbolsToAdopt,
282 UParseError& parseErr,
283 UErrorCode& status) {
284 init();
285 if (symbolsToAdopt == NULL)
286 status = U_ILLEGAL_ARGUMENT_ERROR;
287 construct(status,parseErr, &pattern, symbolsToAdopt);
288 }
289
290 //------------------------------------------------------------------------------
291 // Constructs a DecimalFormat instance with the specified number format
292 // pattern and the number format symbols in the default locale. The
293 // created instance owns the clone of the symbols.
294
295 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
296 const DecimalFormatSymbols& symbols,
297 UErrorCode& status) {
298 init();
299 UParseError parseError;
300 construct(status, parseError, &pattern, new DecimalFormatSymbols(symbols));
301 }
302
303 //------------------------------------------------------------------------------
304 // Constructs a DecimalFormat instance with the specified number format
305 // pattern, the number format symbols, and the number format style.
306 // The created instance owns the clone of the symbols.
307
308 DecimalFormat::DecimalFormat(const UnicodeString& pattern,
309 DecimalFormatSymbols* symbolsToAdopt,
310 NumberFormat::EStyles style,
311 UErrorCode& status) {
312 init();
313 fStyle = style;
314 UParseError parseError;
315 construct(status, parseError, &pattern, symbolsToAdopt);
316 }
317
318 //-----------------------------------------------------------------------------
319 // Common DecimalFormat initialization.
320 // Put all fields of an uninitialized object into a known state.
321 // Common code, shared by all constructors.
322 void
323 DecimalFormat::init() {
324 fPosPrefixPattern = 0;
325 fPosSuffixPattern = 0;
326 fNegPrefixPattern = 0;
327 fNegSuffixPattern = 0;
328 fCurrencyChoice = 0;
329 fMultiplier = NULL;
330 fGroupingSize = 0;
331 fGroupingSize2 = 0;
332 fDecimalSeparatorAlwaysShown = FALSE;
333 fSymbols = NULL;
334 fUseSignificantDigits = FALSE;
335 fMinSignificantDigits = 1;
336 fMaxSignificantDigits = 6;
337 fUseExponentialNotation = FALSE;
338 fMinExponentDigits = 0;
339 fExponentSignAlwaysShown = FALSE;
340 fRoundingIncrement = 0;
341 fRoundingMode = kRoundHalfEven;
342 fPad = 0;
343 fFormatWidth = 0;
344 fPadPosition = kPadBeforePrefix;
345 fStyle = NumberFormat::kNumberStyle;
346 fCurrencySignCount = 0;
347 fAffixPatternsForCurrency = NULL;
348 fAffixesForCurrency = NULL;
349 fPluralAffixesForCurrency = NULL;
350 fCurrencyPluralInfo = NULL;
351 }
352
353 //------------------------------------------------------------------------------
354 // Constructs a DecimalFormat instance with the specified number format
355 // pattern and the number format symbols in the desired locale. The
356 // created instance owns the symbols.
357
358 void
359 DecimalFormat::construct(UErrorCode& status,
360 UParseError& parseErr,
361 const UnicodeString* pattern,
362 DecimalFormatSymbols* symbolsToAdopt)
363 {
364 fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!!
365 fRoundingIncrement = NULL;
366 fRoundingMode = kRoundHalfEven;
367 fPad = kPatternPadEscape;
368 fPadPosition = kPadBeforePrefix;
369 if (U_FAILURE(status))
370 return;
371
372 fPosPrefixPattern = fPosSuffixPattern = NULL;
373 fNegPrefixPattern = fNegSuffixPattern = NULL;
374 setMultiplier(1);
375 fGroupingSize = 3;
376 fGroupingSize2 = 0;
377 fDecimalSeparatorAlwaysShown = FALSE;
378 fUseExponentialNotation = FALSE;
379 fMinExponentDigits = 0;
380
381 if (fSymbols == NULL)
382 {
383 fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status);
384 /* test for NULL */
385 if (fSymbols == 0) {
386 status = U_MEMORY_ALLOCATION_ERROR;
387 return;
388 }
389 }
390
391 UnicodeString str;
392 // Uses the default locale's number format pattern if there isn't
393 // one specified.
394 if (pattern == NULL)
395 {
396 int32_t len = 0;
397 UResourceBundle *resource = ures_open(NULL, Locale::getDefault().getName(), &status);
398
399 resource = ures_getByKey(resource, fgNumberElements, resource, &status);
400 // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn".
401 resource = ures_getByKey(resource, fgLatn, resource, &status);
402 resource = ures_getByKey(resource, fgPatterns, resource, &status);
403 const UChar *resStr = ures_getStringByKey(resource, fgDecimalFormat, &len, &status);
404 str.setTo(TRUE, resStr, len);
405 pattern = &str;
406 ures_close(resource);
407 }
408
409 if (U_FAILURE(status))
410 {
411 return;
412 }
413
414 if (pattern->indexOf((UChar)kCurrencySign) >= 0) {
415 // If it looks like we are going to use a currency pattern
416 // then do the time consuming lookup.
417 setCurrencyForSymbols();
418 } else {
419 setCurrencyInternally(NULL, status);
420 }
421
422 const UnicodeString* patternUsed;
423 UnicodeString currencyPluralPatternForOther;
424 // apply pattern
425 if (fStyle == NumberFormat::kPluralCurrencyStyle) {
426 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
427 if (U_FAILURE(status)) {
428 return;
429 }
430
431 // the pattern used in format is not fixed until formatting,
432 // in which, the number is known and
433 // will be used to pick the right pattern based on plural count.
434 // Here, set the pattern as the pattern of plural count == "other".
435 // For most locale, the patterns are probably the same for all
436 // plural count. If not, the right pattern need to be re-applied
437 // during format.
438 fCurrencyPluralInfo->getCurrencyPluralPattern("other", currencyPluralPatternForOther);
439 patternUsed = &currencyPluralPatternForOther;
440 // TODO: not needed?
441 setCurrencyForSymbols();
442
443 } else {
444 patternUsed = pattern;
445 }
446
447 if (patternUsed->indexOf(kCurrencySign) != -1) {
448 // initialize for currency, not only for plural format,
449 // but also for mix parsing
450 if (fCurrencyPluralInfo == NULL) {
451 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
452 if (U_FAILURE(status)) {
453 return;
454 }
455 }
456 // need it for mix parsing
457 setupCurrencyAffixPatterns(status);
458 // expanded affixes for plural names
459 if (patternUsed->indexOf(fgTripleCurrencySign) != -1) {
460 setupCurrencyAffixes(*patternUsed, TRUE, TRUE, status);
461 }
462 }
463
464 applyPatternWithoutExpandAffix(*patternUsed,FALSE, parseErr, status);
465
466 // expand affixes
467 if (fCurrencySignCount != fgCurrencySignCountInPluralFormat) {
468 expandAffixAdjustWidth(NULL);
469 }
470
471 // If it was a currency format, apply the appropriate rounding by
472 // resetting the currency. NOTE: this copies fCurrency on top of itself.
473 if (fCurrencySignCount > fgCurrencySignCountZero) {
474 setCurrencyInternally(getCurrency(), status);
475 }
476 }
477
478
479 void
480 DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) {
481 if (U_FAILURE(status)) {
482 return;
483 }
484 UParseError parseErr;
485 fAffixPatternsForCurrency = initHashForAffixPattern(status);
486 if (U_FAILURE(status)) {
487 return;
488 }
489
490 // Save the default currency patterns of this locale.
491 // Here, chose onlyApplyPatternWithoutExpandAffix without
492 // expanding the affix patterns into affixes.
493 UnicodeString currencyPattern;
494 UErrorCode error = U_ZERO_ERROR;
495
496 UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(), &error);
497 resource = ures_getByKey(resource, fgNumberElements, resource, &error);
498 // TODO : Get the pattern based on the active numbering system for the locale. Right now assumes "latn".
499 resource = ures_getByKey(resource, fgLatn, resource, &error);
500 resource = ures_getByKey(resource, fgPatterns, resource, &error);
501 int32_t patLen = 0;
502 const UChar *patResStr = ures_getStringByKey(resource, fgCurrencyFormat, &patLen, &error);
503 ures_close(resource);
504
505 if (U_SUCCESS(error)) {
506 applyPatternWithoutExpandAffix(UnicodeString(patResStr, patLen), false,
507 parseErr, status);
508 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
509 *fNegPrefixPattern,
510 *fNegSuffixPattern,
511 *fPosPrefixPattern,
512 *fPosSuffixPattern,
513 UCURR_SYMBOL_NAME);
514 fAffixPatternsForCurrency->put("default", affixPtn, status);
515 }
516
517 // save the unique currency plural patterns of this locale.
518 Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern;
519 const UHashElement* element = NULL;
520 int32_t pos = -1;
521 Hashtable pluralPatternSet;
522 while ((element = pluralPtn->nextElement(pos)) != NULL) {
523 const UHashTok valueTok = element->value;
524 const UnicodeString* value = (UnicodeString*)valueTok.pointer;
525 const UHashTok keyTok = element->key;
526 const UnicodeString* key = (UnicodeString*)keyTok.pointer;
527 if (pluralPatternSet.geti(*value) != 1) {
528 pluralPatternSet.puti(*value, 1, status);
529 applyPatternWithoutExpandAffix(*value, false, parseErr, status);
530 AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency(
531 *fNegPrefixPattern,
532 *fNegSuffixPattern,
533 *fPosPrefixPattern,
534 *fPosSuffixPattern,
535 UCURR_LONG_NAME);
536 fAffixPatternsForCurrency->put(*key, affixPtn, status);
537 }
538 }
539 }
540
541
542 void
543 DecimalFormat::setupCurrencyAffixes(const UnicodeString& pattern,
544 UBool setupForCurrentPattern,
545 UBool setupForPluralPattern,
546 UErrorCode& status) {
547 if (U_FAILURE(status)) {
548 return;
549 }
550 UParseError parseErr;
551 if (setupForCurrentPattern) {
552 if (fAffixesForCurrency) {
553 deleteHashForAffix(fAffixesForCurrency);
554 }
555 fAffixesForCurrency = initHashForAffix(status);
556 if (U_SUCCESS(status)) {
557 applyPatternWithoutExpandAffix(pattern, false, parseErr, status);
558 const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules();
559 StringEnumeration* keywords = pluralRules->getKeywords(status);
560 if (U_SUCCESS(status)) {
561 const char* pluralCountCh;
562 while ((pluralCountCh = keywords->next(NULL, status)) != NULL) {
563 if ( U_SUCCESS(status) ) {
564 UnicodeString pluralCount = UnicodeString(pluralCountCh);
565 expandAffixAdjustWidth(&pluralCount);
566 AffixesForCurrency* affix = new AffixesForCurrency(
567 fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix);
568 fAffixesForCurrency->put(pluralCount, affix, status);
569 }
570 }
571 }
572 delete keywords;
573 }
574 }
575
576 if (U_FAILURE(status)) {
577 return;
578 }
579
580 if (setupForPluralPattern) {
581 if (fPluralAffixesForCurrency) {
582 deleteHashForAffix(fPluralAffixesForCurrency);
583 }
584 fPluralAffixesForCurrency = initHashForAffix(status);
585 if (U_SUCCESS(status)) {
586 const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules();
587 StringEnumeration* keywords = pluralRules->getKeywords(status);
588 if (U_SUCCESS(status)) {
589 const char* pluralCountCh;
590 while ((pluralCountCh = keywords->next(NULL, status)) != NULL) {
591 if ( U_SUCCESS(status) ) {
592 UnicodeString pluralCount = UnicodeString(pluralCountCh);
593 UnicodeString ptn;
594 fCurrencyPluralInfo->getCurrencyPluralPattern(pluralCount, ptn);
595 applyPatternInternally(pluralCount, ptn, false, parseErr, status);
596 AffixesForCurrency* affix = new AffixesForCurrency(
597 fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix);
598 fPluralAffixesForCurrency->put(pluralCount, affix, status);
599 }
600 }
601 }
602 delete keywords;
603 }
604 }
605 }
606
607
608 //------------------------------------------------------------------------------
609
610 DecimalFormat::~DecimalFormat()
611 {
612 delete fPosPrefixPattern;
613 delete fPosSuffixPattern;
614 delete fNegPrefixPattern;
615 delete fNegSuffixPattern;
616 delete fCurrencyChoice;
617 delete fMultiplier;
618 delete fSymbols;
619 delete fRoundingIncrement;
620 deleteHashForAffixPattern();
621 deleteHashForAffix(fAffixesForCurrency);
622 deleteHashForAffix(fPluralAffixesForCurrency);
623 delete fCurrencyPluralInfo;
624 }
625
626 //------------------------------------------------------------------------------
627 // copy constructor
628
629 DecimalFormat::DecimalFormat(const DecimalFormat &source) :
630 NumberFormat(source) {
631 init();
632 *this = source;
633 }
634
635 //------------------------------------------------------------------------------
636 // assignment operator
637
638 static void _copy_us_ptr(UnicodeString** pdest, const UnicodeString* source) {
639 if (source == NULL) {
640 delete *pdest;
641 *pdest = NULL;
642 } else if (*pdest == NULL) {
643 *pdest = new UnicodeString(*source);
644 } else {
645 **pdest = *source;
646 }
647 }
648
649 DecimalFormat&
650 DecimalFormat::operator=(const DecimalFormat& rhs)
651 {
652 if(this != &rhs) {
653 NumberFormat::operator=(rhs);
654 fPositivePrefix = rhs.fPositivePrefix;
655 fPositiveSuffix = rhs.fPositiveSuffix;
656 fNegativePrefix = rhs.fNegativePrefix;
657 fNegativeSuffix = rhs.fNegativeSuffix;
658 _copy_us_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern);
659 _copy_us_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern);
660 _copy_us_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern);
661 _copy_us_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern);
662 if (rhs.fCurrencyChoice == 0) {
663 delete fCurrencyChoice;
664 fCurrencyChoice = 0;
665 } else {
666 fCurrencyChoice = (ChoiceFormat*) rhs.fCurrencyChoice->clone();
667 }
668 setRoundingIncrement(rhs.getRoundingIncrement());
669 fRoundingMode = rhs.fRoundingMode;
670 setMultiplier(rhs.getMultiplier());
671 fGroupingSize = rhs.fGroupingSize;
672 fGroupingSize2 = rhs.fGroupingSize2;
673 fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown;
674 if(fSymbols == NULL) {
675 fSymbols = new DecimalFormatSymbols(*rhs.fSymbols);
676 } else {
677 *fSymbols = *rhs.fSymbols;
678 }
679 fUseExponentialNotation = rhs.fUseExponentialNotation;
680 fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
681 /*Bertrand A. D. Update 98.03.17*/
682 fCurrencySignCount = rhs.fCurrencySignCount;
683 /*end of Update*/
684 fMinExponentDigits = rhs.fMinExponentDigits;
685
686 /* sfb 990629 */
687 fFormatWidth = rhs.fFormatWidth;
688 fPad = rhs.fPad;
689 fPadPosition = rhs.fPadPosition;
690 /* end sfb */
691 fMinSignificantDigits = rhs.fMinSignificantDigits;
692 fMaxSignificantDigits = rhs.fMaxSignificantDigits;
693 fUseSignificantDigits = rhs.fUseSignificantDigits;
694 fFormatPattern = rhs.fFormatPattern;
695 fStyle = rhs.fStyle;
696 fCurrencySignCount = rhs.fCurrencySignCount;
697 if (rhs.fCurrencyPluralInfo) {
698 delete fCurrencyPluralInfo;
699 fCurrencyPluralInfo = rhs.fCurrencyPluralInfo->clone();
700 }
701 if (rhs.fAffixPatternsForCurrency) {
702 UErrorCode status = U_ZERO_ERROR;
703 deleteHashForAffixPattern();
704 fAffixPatternsForCurrency = initHashForAffixPattern(status);
705 copyHashForAffixPattern(rhs.fAffixPatternsForCurrency,
706 fAffixPatternsForCurrency, status);
707 }
708 if (rhs.fAffixesForCurrency) {
709 UErrorCode status = U_ZERO_ERROR;
710 deleteHashForAffix(fAffixesForCurrency);
711 fAffixesForCurrency = initHashForAffixPattern(status);
712 copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, status);
713 }
714 if (rhs.fPluralAffixesForCurrency) {
715 UErrorCode status = U_ZERO_ERROR;
716 deleteHashForAffix(fPluralAffixesForCurrency);
717 fPluralAffixesForCurrency = initHashForAffixPattern(status);
718 copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCurrency, status);
719 }
720 }
721 return *this;
722 }
723
724 //------------------------------------------------------------------------------
725
726 UBool
727 DecimalFormat::operator==(const Format& that) const
728 {
729 if (this == &that)
730 return TRUE;
731
732 // NumberFormat::operator== guarantees this cast is safe
733 const DecimalFormat* other = (DecimalFormat*)&that;
734
735 #ifdef FMT_DEBUG
736 // This code makes it easy to determine why two format objects that should
737 // be equal aren't.
738 UBool first = TRUE;
739 if (!NumberFormat::operator==(that)) {
740 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
741 debug("NumberFormat::!=");
742 } else {
743 if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null
744 fPositivePrefix == other->fPositivePrefix)
745 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
746 *fPosPrefixPattern == *other->fPosPrefixPattern))) {
747 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
748 debug("Pos Prefix !=");
749 }
750 if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null
751 fPositiveSuffix == other->fPositiveSuffix)
752 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
753 *fPosSuffixPattern == *other->fPosSuffixPattern))) {
754 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
755 debug("Pos Suffix !=");
756 }
757 if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null
758 fNegativePrefix == other->fNegativePrefix)
759 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
760 *fNegPrefixPattern == *other->fNegPrefixPattern))) {
761 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
762 debug("Neg Prefix ");
763 if (fNegPrefixPattern == NULL) {
764 debug("NULL(");
765 debugout(fNegativePrefix);
766 debug(")");
767 } else {
768 debugout(*fNegPrefixPattern);
769 }
770 debug(" != ");
771 if (other->fNegPrefixPattern == NULL) {
772 debug("NULL(");
773 debugout(other->fNegativePrefix);
774 debug(")");
775 } else {
776 debugout(*other->fNegPrefixPattern);
777 }
778 }
779 if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null
780 fNegativeSuffix == other->fNegativeSuffix)
781 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
782 *fNegSuffixPattern == *other->fNegSuffixPattern))) {
783 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
784 debug("Neg Suffix ");
785 if (fNegSuffixPattern == NULL) {
786 debug("NULL(");
787 debugout(fNegativeSuffix);
788 debug(")");
789 } else {
790 debugout(*fNegSuffixPattern);
791 }
792 debug(" != ");
793 if (other->fNegSuffixPattern == NULL) {
794 debug("NULL(");
795 debugout(other->fNegativeSuffix);
796 debug(")");
797 } else {
798 debugout(*other->fNegSuffixPattern);
799 }
800 }
801 if (!((fRoundingIncrement == other->fRoundingIncrement) // both null
802 || (fRoundingIncrement != NULL &&
803 other->fRoundingIncrement != NULL &&
804 *fRoundingIncrement == *other->fRoundingIncrement))) {
805 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
806 debug("Rounding Increment !=");
807 }
808 if (getMultiplier() != other->getMultiplier()) {
809 if (first) { printf("[ "); first = FALSE; }
810 printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier());
811 }
812 if (fGroupingSize != other->fGroupingSize) {
813 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
814 printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize);
815 }
816 if (fGroupingSize2 != other->fGroupingSize2) {
817 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
818 printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2);
819 }
820 if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) {
821 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
822 printf("Dec Sep Always %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown);
823 }
824 if (fUseExponentialNotation != other->fUseExponentialNotation) {
825 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
826 debug("Use Exp !=");
827 }
828 if (!(!fUseExponentialNotation ||
829 fMinExponentDigits != other->fMinExponentDigits)) {
830 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
831 debug("Exp Digits !=");
832 }
833 if (*fSymbols != *(other->fSymbols)) {
834 if (first) { printf("[ "); first = FALSE; } else { printf(", "); }
835 debug("Symbols !=");
836 }
837 // TODO Add debug stuff for significant digits here
838 if (fUseSignificantDigits != other->fUseSignificantDigits) {
839 debug("fUseSignificantDigits !=");
840 }
841 if (fUseSignificantDigits &&
842 fMinSignificantDigits != other->fMinSignificantDigits) {
843 debug("fMinSignificantDigits !=");
844 }
845 if (fUseSignificantDigits &&
846 fMaxSignificantDigits != other->fMaxSignificantDigits) {
847 debug("fMaxSignificantDigits !=");
848 }
849
850 if (!first) { printf(" ]"); }
851 if (fCurrencySignCount != other->fCurrencySignCount) {
852 debug("fCurrencySignCount !=");
853 }
854 if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) {
855 debug("fCurrencyPluralInfo == ");
856 if (fCurrencyPluralInfo == NULL) {
857 debug("fCurrencyPluralInfo == NULL");
858 }
859 }
860 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
861 *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) {
862 debug("fCurrencyPluralInfo !=");
863 }
864 if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL ||
865 fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) {
866 debug("fCurrencyPluralInfo one NULL, the other not");
867 }
868 if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) {
869 debug("fCurrencyPluralInfo == ");
870 }
871 }
872 #endif
873
874 return (NumberFormat::operator==(that) &&
875 ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ?
876 (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) :
877 (((fPosPrefixPattern == other->fPosPrefixPattern && // both null
878 fPositivePrefix == other->fPositivePrefix)
879 || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 &&
880 *fPosPrefixPattern == *other->fPosPrefixPattern)) &&
881 ((fPosSuffixPattern == other->fPosSuffixPattern && // both null
882 fPositiveSuffix == other->fPositiveSuffix)
883 || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 &&
884 *fPosSuffixPattern == *other->fPosSuffixPattern)) &&
885 ((fNegPrefixPattern == other->fNegPrefixPattern && // both null
886 fNegativePrefix == other->fNegativePrefix)
887 || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 &&
888 *fNegPrefixPattern == *other->fNegPrefixPattern)) &&
889 ((fNegSuffixPattern == other->fNegSuffixPattern && // both null
890 fNegativeSuffix == other->fNegativeSuffix)
891 || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 &&
892 *fNegSuffixPattern == *other->fNegSuffixPattern)))) &&
893 ((fRoundingIncrement == other->fRoundingIncrement) // both null
894 || (fRoundingIncrement != NULL &&
895 other->fRoundingIncrement != NULL &&
896 *fRoundingIncrement == *other->fRoundingIncrement)) &&
897 getMultiplier() == other->getMultiplier() &&
898 fGroupingSize == other->fGroupingSize &&
899 fGroupingSize2 == other->fGroupingSize2 &&
900 fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown &&
901 fUseExponentialNotation == other->fUseExponentialNotation &&
902 (!fUseExponentialNotation ||
903 fMinExponentDigits == other->fMinExponentDigits) &&
904 *fSymbols == *(other->fSymbols) &&
905 fUseSignificantDigits == other->fUseSignificantDigits &&
906 (!fUseSignificantDigits ||
907 (fMinSignificantDigits == other->fMinSignificantDigits &&
908 fMaxSignificantDigits == other->fMaxSignificantDigits)) &&
909 fCurrencySignCount == other->fCurrencySignCount &&
910 ((fCurrencyPluralInfo == other->fCurrencyPluralInfo &&
911 fCurrencyPluralInfo == NULL) ||
912 (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL &&
913 *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo))));
914 }
915
916 //------------------------------------------------------------------------------
917
918 Format*
919 DecimalFormat::clone() const
920 {
921 return new DecimalFormat(*this);
922 }
923
924 //------------------------------------------------------------------------------
925
926 UnicodeString&
927 DecimalFormat::format(int32_t number,
928 UnicodeString& appendTo,
929 FieldPosition& fieldPosition) const
930 {
931 return format((int64_t)number, appendTo, fieldPosition);
932 }
933
934 UnicodeString&
935 DecimalFormat::format(int32_t number,
936 UnicodeString& appendTo,
937 FieldPositionIterator* posIter,
938 UErrorCode& status) const
939 {
940 return format((int64_t)number, appendTo, posIter, status);
941 }
942
943 //------------------------------------------------------------------------------
944
945 UnicodeString&
946 DecimalFormat::format(int64_t number,
947 UnicodeString& appendTo,
948 FieldPosition& fieldPosition) const
949 {
950 FieldPositionOnlyHandler handler(fieldPosition);
951 return _format(number, appendTo, handler);
952 }
953
954 UnicodeString&
955 DecimalFormat::format(int64_t number,
956 UnicodeString& appendTo,
957 FieldPositionIterator* posIter,
958 UErrorCode& status) const
959 {
960 FieldPositionIteratorHandler handler(posIter, status);
961 return _format(number, appendTo, handler);
962 }
963
964 UnicodeString&
965 DecimalFormat::_format(int64_t number,
966 UnicodeString& appendTo,
967 FieldPositionHandler& handler) const
968 {
969 UErrorCode status = U_ZERO_ERROR;
970 DigitList digits;
971 digits.set(number);
972 return _format(digits, appendTo, handler, status);
973 }
974
975 //------------------------------------------------------------------------------
976
977 UnicodeString&
978 DecimalFormat::format( double number,
979 UnicodeString& appendTo,
980 FieldPosition& fieldPosition) const
981 {
982 FieldPositionOnlyHandler handler(fieldPosition);
983 return _format(number, appendTo, handler);
984 }
985
986 UnicodeString&
987 DecimalFormat::format( double number,
988 UnicodeString& appendTo,
989 FieldPositionIterator* posIter,
990 UErrorCode& status) const
991 {
992 FieldPositionIteratorHandler handler(posIter, status);
993 return _format(number, appendTo, handler);
994 }
995
996 UnicodeString&
997 DecimalFormat::_format( double number,
998 UnicodeString& appendTo,
999 FieldPositionHandler& handler) const
1000 {
1001 // Special case for NaN, sets the begin and end index to be the
1002 // the string length of localized name of NaN.
1003 // TODO: let NaNs go through DigitList.
1004 if (uprv_isNaN(number))
1005 {
1006 int begin = appendTo.length();
1007 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1008
1009 handler.addAttribute(kIntegerField, begin, appendTo.length());
1010
1011 addPadding(appendTo, handler, 0, 0);
1012 return appendTo;
1013 }
1014
1015 UErrorCode status = U_ZERO_ERROR;
1016 DigitList digits;
1017 digits.set(number);
1018 _format(digits, appendTo, handler, status);
1019 // No way to return status from here.
1020 return appendTo;
1021 }
1022
1023 //------------------------------------------------------------------------------
1024
1025
1026 UnicodeString&
1027 DecimalFormat::format(const StringPiece &number,
1028 UnicodeString &toAppendTo,
1029 FieldPositionIterator *posIter,
1030 UErrorCode &status) const
1031 {
1032 DigitList dnum;
1033 dnum.set(number, status);
1034 if (U_FAILURE(status)) {
1035 return toAppendTo;
1036 }
1037 FieldPositionIteratorHandler handler(posIter, status);
1038 _format(dnum, toAppendTo, handler, status);
1039 return toAppendTo;
1040 }
1041
1042
1043 UnicodeString&
1044 DecimalFormat::format(const DigitList &number,
1045 UnicodeString &appendTo,
1046 FieldPositionIterator *posIter,
1047 UErrorCode &status) const {
1048 FieldPositionIteratorHandler handler(posIter, status);
1049 _format(number, appendTo, handler, status);
1050 return appendTo;
1051 }
1052
1053
1054
1055 UnicodeString&
1056 DecimalFormat::format(const DigitList &number,
1057 UnicodeString& appendTo,
1058 FieldPosition& pos,
1059 UErrorCode &status) const {
1060 FieldPositionOnlyHandler handler(pos);
1061 _format(number, appendTo, handler, status);
1062 return appendTo;
1063 }
1064
1065
1066
1067 UnicodeString&
1068 DecimalFormat::_format(const DigitList &number,
1069 UnicodeString& appendTo,
1070 FieldPositionHandler& handler,
1071 UErrorCode &status) const
1072 {
1073 // Special case for NaN, sets the begin and end index to be the
1074 // the string length of localized name of NaN.
1075 if (number.isNaN())
1076 {
1077 int begin = appendTo.length();
1078 appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1079
1080 handler.addAttribute(kIntegerField, begin, appendTo.length());
1081
1082 addPadding(appendTo, handler, 0, 0);
1083 return appendTo;
1084 }
1085
1086 // Do this BEFORE checking to see if value is infinite or negative! Sets the
1087 // begin and end index to be length of the string composed of
1088 // localized name of Infinite and the positive/negative localized
1089 // signs.
1090
1091 DigitList adjustedNum(number); // Copy, so we do not alter the original.
1092 adjustedNum.setRoundingMode(fRoundingMode);
1093 if (fMultiplier != NULL) {
1094 adjustedNum.mult(*fMultiplier, status);
1095 }
1096
1097 /*
1098 * Note: sign is important for zero as well as non-zero numbers.
1099 * Proper detection of -0.0 is needed to deal with the
1100 * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98.
1101 */
1102 UBool isNegative = !adjustedNum.isPositive();
1103
1104 // Apply rounding after multiplier
1105 if (fRoundingIncrement != NULL) {
1106 adjustedNum.div(*fRoundingIncrement, status);
1107 adjustedNum.toIntegralValue();
1108 adjustedNum.mult(*fRoundingIncrement, status);
1109 adjustedNum.trim();
1110 }
1111
1112 // Special case for INFINITE,
1113 if (adjustedNum.isInfinite()) {
1114 int32_t prefixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, TRUE);
1115
1116 int begin = appendTo.length();
1117 appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
1118
1119 handler.addAttribute(kIntegerField, begin, appendTo.length());
1120
1121 int32_t suffixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, FALSE);
1122
1123 addPadding(appendTo, handler, prefixLen, suffixLen);
1124 return appendTo;
1125 }
1126
1127 if (fUseExponentialNotation || areSignificantDigitsUsed()) {
1128 int32_t sigDigits = precision();
1129 if (sigDigits > 0) {
1130 adjustedNum.round(sigDigits);
1131 }
1132 } else {
1133 // Fixed point format. Round to a set number of fraction digits.
1134 int32_t numFractionDigits = precision();
1135 adjustedNum.roundFixedPoint(numFractionDigits);
1136 }
1137
1138 return subformat(appendTo, handler, adjustedNum, FALSE);
1139 }
1140
1141
1142 UnicodeString&
1143 DecimalFormat::format( const Formattable& obj,
1144 UnicodeString& appendTo,
1145 FieldPosition& fieldPosition,
1146 UErrorCode& status) const
1147 {
1148 return NumberFormat::format(obj, appendTo, fieldPosition, status);
1149 }
1150
1151 /**
1152 * Return true if a grouping separator belongs at the given
1153 * position, based on whether grouping is in use and the values of
1154 * the primary and secondary grouping interval.
1155 * @param pos the number of integer digits to the right of
1156 * the current position. Zero indicates the position after the
1157 * rightmost integer digit.
1158 * @return true if a grouping character belongs at the current
1159 * position.
1160 */
1161 UBool DecimalFormat::isGroupingPosition(int32_t pos) const {
1162 UBool result = FALSE;
1163 if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) {
1164 if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) {
1165 result = ((pos - fGroupingSize) % fGroupingSize2) == 0;
1166 } else {
1167 result = pos % fGroupingSize == 0;
1168 }
1169 }
1170 return result;
1171 }
1172
1173 //------------------------------------------------------------------------------
1174
1175 /**
1176 * Complete the formatting of a finite number. On entry, the DigitList must
1177 * be filled in with the correct digits.
1178 */
1179 UnicodeString&
1180 DecimalFormat::subformat(UnicodeString& appendTo,
1181 FieldPositionHandler& handler,
1182 DigitList& digits,
1183 UBool isInteger) const
1184 {
1185 // char zero = '0';
1186 // DigitList returns digits as '0' thru '9', so we will need to
1187 // always need to subtract the character 0 to get the numeric value to use for indexing.
1188
1189 UChar32 localizedDigits[10];
1190 localizedDigits[0] = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
1191 localizedDigits[1] = getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol).char32At(0);
1192 localizedDigits[2] = getConstSymbol(DecimalFormatSymbols::kTwoDigitSymbol).char32At(0);
1193 localizedDigits[3] = getConstSymbol(DecimalFormatSymbols::kThreeDigitSymbol).char32At(0);
1194 localizedDigits[4] = getConstSymbol(DecimalFormatSymbols::kFourDigitSymbol).char32At(0);
1195 localizedDigits[5] = getConstSymbol(DecimalFormatSymbols::kFiveDigitSymbol).char32At(0);
1196 localizedDigits[6] = getConstSymbol(DecimalFormatSymbols::kSixDigitSymbol).char32At(0);
1197 localizedDigits[7] = getConstSymbol(DecimalFormatSymbols::kSevenDigitSymbol).char32At(0);
1198 localizedDigits[8] = getConstSymbol(DecimalFormatSymbols::kEightDigitSymbol).char32At(0);
1199 localizedDigits[9] = getConstSymbol(DecimalFormatSymbols::kNineDigitSymbol).char32At(0);
1200
1201 const UnicodeString *grouping ;
1202 if(fCurrencySignCount > fgCurrencySignCountZero) {
1203 grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol);
1204 }else{
1205 grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
1206 }
1207 const UnicodeString *decimal;
1208 if(fCurrencySignCount > fgCurrencySignCountZero) {
1209 decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1210 } else {
1211 decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
1212 }
1213 UBool useSigDig = areSignificantDigitsUsed();
1214 int32_t maxIntDig = getMaximumIntegerDigits();
1215 int32_t minIntDig = getMinimumIntegerDigits();
1216
1217 // Appends the prefix.
1218 double doubleValue = digits.getDouble();
1219 int32_t prefixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), TRUE);
1220
1221 if (fUseExponentialNotation)
1222 {
1223 int currentLength = appendTo.length();
1224 int intBegin = currentLength;
1225 int intEnd = -1;
1226 int fracBegin = -1;
1227
1228 int32_t minFracDig = 0;
1229 if (useSigDig) {
1230 maxIntDig = minIntDig = 1;
1231 minFracDig = getMinimumSignificantDigits() - 1;
1232 } else {
1233 minFracDig = getMinimumFractionDigits();
1234 if (maxIntDig > kMaxScientificIntegerDigits) {
1235 maxIntDig = 1;
1236 if (maxIntDig < minIntDig) {
1237 maxIntDig = minIntDig;
1238 }
1239 }
1240 if (maxIntDig > minIntDig) {
1241 minIntDig = 1;
1242 }
1243 }
1244
1245 // Minimum integer digits are handled in exponential format by
1246 // adjusting the exponent. For example, 0.01234 with 3 minimum
1247 // integer digits is "123.4E-4".
1248
1249 // Maximum integer digits are interpreted as indicating the
1250 // repeating range. This is useful for engineering notation, in
1251 // which the exponent is restricted to a multiple of 3. For
1252 // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
1253 // If maximum integer digits are defined and are larger than
1254 // minimum integer digits, then minimum integer digits are
1255 // ignored.
1256 digits.reduce(); // Removes trailing zero digits.
1257 int32_t exponent = digits.getDecimalAt();
1258 if (maxIntDig > 1 && maxIntDig != minIntDig) {
1259 // A exponent increment is defined; adjust to it.
1260 exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
1261 : (exponent / maxIntDig) - 1;
1262 exponent *= maxIntDig;
1263 } else {
1264 // No exponent increment is defined; use minimum integer digits.
1265 // If none is specified, as in "#E0", generate 1 integer digit.
1266 exponent -= (minIntDig > 0 || minFracDig > 0)
1267 ? minIntDig : 1;
1268 }
1269
1270 // We now output a minimum number of digits, and more if there
1271 // are more digits, up to the maximum number of digits. We
1272 // place the decimal point after the "integer" digits, which
1273 // are the first (decimalAt - exponent) digits.
1274 int32_t minimumDigits = minIntDig + minFracDig;
1275 // The number of integer digits is handled specially if the number
1276 // is zero, since then there may be no digits.
1277 int32_t integerDigits = digits.isZero() ? minIntDig :
1278 digits.getDecimalAt() - exponent;
1279 int32_t totalDigits = digits.getCount();
1280 if (minimumDigits > totalDigits)
1281 totalDigits = minimumDigits;
1282 if (integerDigits > totalDigits)
1283 totalDigits = integerDigits;
1284
1285 // totalDigits records total number of digits needs to be processed
1286 int32_t i;
1287 for (i=0; i<totalDigits; ++i)
1288 {
1289 if (i == integerDigits)
1290 {
1291 intEnd = appendTo.length();
1292 handler.addAttribute(kIntegerField, intBegin, intEnd);
1293
1294 appendTo += *decimal;
1295
1296 fracBegin = appendTo.length();
1297 handler.addAttribute(kDecimalSeparatorField, fracBegin - 1, fracBegin);
1298 }
1299 // Restores the digit character or pads the buffer with zeros.
1300 UChar32 c = (UChar32)((i < digits.getCount()) ?
1301 localizedDigits[digits.getDigitValue(i)] :
1302 localizedDigits[0]);
1303 appendTo += c;
1304 }
1305
1306 currentLength = appendTo.length();
1307
1308 if (intEnd < 0) {
1309 handler.addAttribute(kIntegerField, intBegin, currentLength);
1310 }
1311 if (fracBegin > 0) {
1312 handler.addAttribute(kFractionField, fracBegin, currentLength);
1313 }
1314
1315 // The exponent is output using the pattern-specified minimum
1316 // exponent digits. There is no maximum limit to the exponent
1317 // digits, since truncating the exponent would appendTo in an
1318 // unacceptable inaccuracy.
1319 appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
1320
1321 handler.addAttribute(kExponentSymbolField, currentLength, appendTo.length());
1322 currentLength = appendTo.length();
1323
1324 // For zero values, we force the exponent to zero. We
1325 // must do this here, and not earlier, because the value
1326 // is used to determine integer digit count above.
1327 if (digits.isZero())
1328 exponent = 0;
1329
1330 if (exponent < 0) {
1331 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
1332 handler.addAttribute(kExponentSignField, currentLength, appendTo.length());
1333 } else if (fExponentSignAlwaysShown) {
1334 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
1335 handler.addAttribute(kExponentSignField, currentLength, appendTo.length());
1336 }
1337
1338 currentLength = appendTo.length();
1339
1340 DigitList expDigits;
1341 expDigits.set(exponent);
1342 {
1343 int expDig = fMinExponentDigits;
1344 if (fUseExponentialNotation && expDig < 1) {
1345 expDig = 1;
1346 }
1347 for (i=expDigits.getDecimalAt(); i<expDig; ++i)
1348 appendTo += (localizedDigits[0]);
1349 }
1350 for (i=0; i<expDigits.getDecimalAt(); ++i)
1351 {
1352 UChar32 c = (UChar32)((i < expDigits.getCount()) ?
1353 localizedDigits[expDigits.getDigitValue(i)] :
1354 localizedDigits[0]);
1355 appendTo += c;
1356 }
1357
1358 handler.addAttribute(kExponentField, currentLength, appendTo.length());
1359 }
1360 else // Not using exponential notation
1361 {
1362 int currentLength = appendTo.length();
1363 int intBegin = currentLength;
1364
1365 int32_t sigCount = 0;
1366 int32_t minSigDig = getMinimumSignificantDigits();
1367 int32_t maxSigDig = getMaximumSignificantDigits();
1368 if (!useSigDig) {
1369 minSigDig = 0;
1370 maxSigDig = INT32_MAX;
1371 }
1372
1373 // Output the integer portion. Here 'count' is the total
1374 // number of integer digits we will display, including both
1375 // leading zeros required to satisfy getMinimumIntegerDigits,
1376 // and actual digits present in the number.
1377 int32_t count = useSigDig ?
1378 _max(1, digits.getDecimalAt()) : minIntDig;
1379 if (digits.getDecimalAt() > 0 && count < digits.getDecimalAt()) {
1380 count = digits.getDecimalAt();
1381 }
1382
1383 // Handle the case where getMaximumIntegerDigits() is smaller
1384 // than the real number of integer digits. If this is so, we
1385 // output the least significant max integer digits. For example,
1386 // the value 1997 printed with 2 max integer digits is just "97".
1387
1388 int32_t digitIndex = 0; // Index into digitList.fDigits[]
1389 if (count > maxIntDig && maxIntDig >= 0) {
1390 count = maxIntDig;
1391 digitIndex = digits.getDecimalAt() - count;
1392 }
1393
1394 int32_t sizeBeforeIntegerPart = appendTo.length();
1395
1396 int32_t i;
1397 for (i=count-1; i>=0; --i)
1398 {
1399 if (i < digits.getDecimalAt() && digitIndex < digits.getCount() &&
1400 sigCount < maxSigDig) {
1401 // Output a real digit
1402 appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)];
1403 ++sigCount;
1404 }
1405 else
1406 {
1407 // Output a zero (leading or trailing)
1408 appendTo += localizedDigits[0];
1409 if (sigCount > 0) {
1410 ++sigCount;
1411 }
1412 }
1413
1414 // Output grouping separator if necessary.
1415 if (isGroupingPosition(i)) {
1416 currentLength = appendTo.length();
1417 appendTo.append(*grouping);
1418 handler.addAttribute(kGroupingSeparatorField, currentLength, appendTo.length());
1419 }
1420 }
1421
1422 // TODO(dlf): this looks like it was a bug, we marked the int field as ending
1423 // before the zero was generated.
1424 // Record field information for caller.
1425 // if (fieldPosition.getField() == NumberFormat::kIntegerField)
1426 // fieldPosition.setEndIndex(appendTo.length());
1427
1428 // Determine whether or not there are any printable fractional
1429 // digits. If we've used up the digits we know there aren't.
1430 UBool fractionPresent = (!isInteger && digitIndex < digits.getCount()) ||
1431 (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));
1432
1433 // If there is no fraction present, and we haven't printed any
1434 // integer digits, then print a zero. Otherwise we won't print
1435 // _any_ digits, and we won't be able to parse this string.
1436 if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart)
1437 appendTo += localizedDigits[0];
1438
1439 currentLength = appendTo.length();
1440 handler.addAttribute(kIntegerField, intBegin, currentLength);
1441
1442 // Output the decimal separator if we always do so.
1443 if (fDecimalSeparatorAlwaysShown || fractionPresent) {
1444 appendTo += *decimal;
1445 handler.addAttribute(kDecimalSeparatorField, currentLength, appendTo.length());
1446 currentLength = appendTo.length();
1447 }
1448
1449 int fracBegin = currentLength;
1450
1451 count = useSigDig ? INT32_MAX : getMaximumFractionDigits();
1452 if (useSigDig && (sigCount == maxSigDig ||
1453 (sigCount >= minSigDig && digitIndex == digits.getCount()))) {
1454 count = 0;
1455 }
1456
1457 for (i=0; i < count; ++i) {
1458 // Here is where we escape from the loop. We escape
1459 // if we've output the maximum fraction digits
1460 // (specified in the for expression above). We also
1461 // stop when we've output the minimum digits and
1462 // either: we have an integer, so there is no
1463 // fractional stuff to display, or we're out of
1464 // significant digits.
1465 if (!useSigDig && i >= getMinimumFractionDigits() &&
1466 (isInteger || digitIndex >= digits.getCount())) {
1467 break;
1468 }
1469
1470 // Output leading fractional zeros. These are zeros
1471 // that come after the decimal but before any
1472 // significant digits. These are only output if
1473 // abs(number being formatted) < 1.0.
1474 if (-1-i > (digits.getDecimalAt()-1)) {
1475 appendTo += localizedDigits[0];
1476 continue;
1477 }
1478
1479 // Output a digit, if we have any precision left, or a
1480 // zero if we don't. We don't want to output noise digits.
1481 if (!isInteger && digitIndex < digits.getCount()) {
1482 appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)];
1483 } else {
1484 appendTo += localizedDigits[0];
1485 }
1486
1487 // If we reach the maximum number of significant
1488 // digits, or if we output all the real digits and
1489 // reach the minimum, then we are done.
1490 ++sigCount;
1491 if (useSigDig &&
1492 (sigCount == maxSigDig ||
1493 (digitIndex == digits.getCount() && sigCount >= minSigDig))) {
1494 break;
1495 }
1496 }
1497
1498 handler.addAttribute(kFractionField, fracBegin, appendTo.length());
1499 }
1500
1501 int32_t suffixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), FALSE);
1502
1503 addPadding(appendTo, handler, prefixLen, suffixLen);
1504 return appendTo;
1505 }
1506
1507 /**
1508 * Inserts the character fPad as needed to expand result to fFormatWidth.
1509 * @param result the string to be padded
1510 */
1511 void DecimalFormat::addPadding(UnicodeString& appendTo,
1512 FieldPositionHandler& handler,
1513 int32_t prefixLen,
1514 int32_t suffixLen) const
1515 {
1516 if (fFormatWidth > 0) {
1517 int32_t len = fFormatWidth - appendTo.length();
1518 if (len > 0) {
1519 UnicodeString padding;
1520 for (int32_t i=0; i<len; ++i) {
1521 padding += fPad;
1522 }
1523 switch (fPadPosition) {
1524 case kPadAfterPrefix:
1525 appendTo.insert(prefixLen, padding);
1526 break;
1527 case kPadBeforePrefix:
1528 appendTo.insert(0, padding);
1529 break;
1530 case kPadBeforeSuffix:
1531 appendTo.insert(appendTo.length() - suffixLen, padding);
1532 break;
1533 case kPadAfterSuffix:
1534 appendTo += padding;
1535 break;
1536 }
1537 if (fPadPosition == kPadBeforePrefix || fPadPosition == kPadAfterPrefix) {
1538 handler.shiftLast(len);
1539 }
1540 }
1541 }
1542 }
1543
1544 //------------------------------------------------------------------------------
1545
1546 void
1547 DecimalFormat::parse(const UnicodeString& text,
1548 Formattable& result,
1549 UErrorCode& status) const
1550 {
1551 NumberFormat::parse(text, result, status);
1552 }
1553
1554 void
1555 DecimalFormat::parse(const UnicodeString& text,
1556 Formattable& result,
1557 ParsePosition& parsePosition) const {
1558 parse(text, result, parsePosition, FALSE);
1559 }
1560
1561 Formattable& DecimalFormat::parseCurrency(const UnicodeString& text,
1562 Formattable& result,
1563 ParsePosition& pos) const {
1564 parse(text, result, pos, TRUE);
1565 return result;
1566 }
1567
1568 /**
1569 * Parses the given text as either a number or a currency amount.
1570 * @param text the string to parse
1571 * @param result output parameter for the result
1572 * @param parsePosition input-output position; on input, the
1573 * position within text to match; must have 0 <= pos.getIndex() <
1574 * text.length(); on output, the position after the last matched
1575 * character. If the parse fails, the position in unchanged upon
1576 * output.
1577 * @param parseCurrency if true, a currency amount is parsed;
1578 * otherwise a Number is parsed
1579 */
1580 void DecimalFormat::parse(const UnicodeString& text,
1581 Formattable& result,
1582 ParsePosition& parsePosition,
1583 UBool parseCurrency) const {
1584 int32_t backup;
1585 int32_t i = backup = parsePosition.getIndex();
1586
1587 // clear any old contents in the result. In particular, clears any DigitList
1588 // that it may be holding.
1589 result.setLong(0);
1590
1591 // Handle NaN as a special case:
1592
1593 // Skip padding characters, if around prefix
1594 if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix ||
1595 fPadPosition == kPadAfterPrefix)) {
1596 i = skipPadding(text, i);
1597 }
1598
1599 if (! isParseStrict()) {
1600 // skip any leading whitespace
1601 i = backup = skipUWhiteSpace(text, i);
1602 }
1603
1604 // If the text is composed of the representation of NaN, returns NaN.length
1605 const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
1606 int32_t nanLen = (text.compare(i, nan->length(), *nan)
1607 ? 0 : nan->length());
1608 if (nanLen) {
1609 i += nanLen;
1610 if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix ||
1611 fPadPosition == kPadAfterSuffix)) {
1612 i = skipPadding(text, i);
1613 }
1614 parsePosition.setIndex(i);
1615 result.setDouble(uprv_getNaN());
1616 return;
1617 }
1618
1619 // NaN parse failed; start over
1620 i = backup;
1621 parsePosition.setIndex(i);
1622
1623 // status is used to record whether a number is infinite.
1624 UBool status[fgStatusLength];
1625 UChar curbuf[4];
1626 UChar* currency = parseCurrency ? curbuf : NULL;
1627 DigitList *digits = new DigitList;
1628 if (digits == NULL) {
1629 return; // no way to report error from here.
1630 }
1631
1632 if (fCurrencySignCount > fgCurrencySignCountZero) {
1633 if (!parseForCurrency(text, parsePosition, *digits,
1634 status, currency)) {
1635 delete digits;
1636 return;
1637 }
1638 } else {
1639 if (!subparse(text,
1640 fNegPrefixPattern, fNegSuffixPattern,
1641 fPosPrefixPattern, fPosSuffixPattern,
1642 FALSE, UCURR_SYMBOL_NAME,
1643 parsePosition, *digits, status, currency)) {
1644 parsePosition.setIndex(backup);
1645 delete digits;
1646 return;
1647 }
1648 }
1649
1650 // Handle infinity
1651 if (status[fgStatusInfinite]) {
1652 double inf = uprv_getInfinity();
1653 result.setDouble(digits->isPositive() ? inf : -inf);
1654 delete digits; // TODO: set the dl to infinity, and let it fall into the code below.
1655 }
1656
1657 else {
1658
1659 if (fMultiplier != NULL) {
1660 UErrorCode ec = U_ZERO_ERROR;
1661 digits->div(*fMultiplier, ec);
1662 }
1663
1664 // Negative zero special case:
1665 // if parsing integerOnly, change to +0, which goes into an int32 in a Formattable.
1666 // if not parsing integerOnly, leave as -0, which a double can represent.
1667 if (digits->isZero() && !digits->isPositive() && isParseIntegerOnly()) {
1668 digits->setPositive(TRUE);
1669 }
1670 result.adoptDigitList(digits);
1671 }
1672
1673 if (parseCurrency) {
1674 UErrorCode ec = U_ZERO_ERROR;
1675 Formattable n(result);
1676 result.adoptObject(new CurrencyAmount(n, curbuf, ec));
1677 U_ASSERT(U_SUCCESS(ec)); // should always succeed
1678 }
1679 }
1680
1681
1682
1683 UBool
1684 DecimalFormat::parseForCurrency(const UnicodeString& text,
1685 ParsePosition& parsePosition,
1686 DigitList& digits,
1687 UBool* status,
1688 UChar* currency) const {
1689 int origPos = parsePosition.getIndex();
1690 int maxPosIndex = origPos;
1691 int maxErrorPos = -1;
1692 // First, parse against current pattern.
1693 // Since current pattern could be set by applyPattern(),
1694 // it could be an arbitrary pattern, and it may not be the one
1695 // defined in current locale.
1696 UBool tmpStatus[fgStatusLength];
1697 ParsePosition tmpPos(origPos);
1698 DigitList tmpDigitList;
1699 UBool found;
1700 if (fStyle == NumberFormat::kPluralCurrencyStyle) {
1701 found = subparse(text,
1702 fNegPrefixPattern, fNegSuffixPattern,
1703 fPosPrefixPattern, fPosSuffixPattern,
1704 TRUE, UCURR_LONG_NAME,
1705 tmpPos, tmpDigitList, tmpStatus, currency);
1706 } else {
1707 found = subparse(text,
1708 fNegPrefixPattern, fNegSuffixPattern,
1709 fPosPrefixPattern, fPosSuffixPattern,
1710 TRUE, UCURR_SYMBOL_NAME,
1711 tmpPos, tmpDigitList, tmpStatus, currency);
1712 }
1713 if (found) {
1714 if (tmpPos.getIndex() > maxPosIndex) {
1715 maxPosIndex = tmpPos.getIndex();
1716 for (int32_t i = 0; i < fgStatusLength; ++i) {
1717 status[i] = tmpStatus[i];
1718 }
1719 digits = tmpDigitList;
1720 }
1721 } else {
1722 maxErrorPos = tmpPos.getErrorIndex();
1723 }
1724 // Then, parse against affix patterns.
1725 // Those are currency patterns and currency plural patterns.
1726 int32_t pos = -1;
1727 const UHashElement* element = NULL;
1728 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
1729 const UHashTok keyTok = element->key;
1730 const UHashTok valueTok = element->value;
1731 const AffixPatternsForCurrency* affixPtn = (AffixPatternsForCurrency*)valueTok.pointer;
1732 UBool tmpStatus[fgStatusLength];
1733 ParsePosition tmpPos(origPos);
1734 DigitList tmpDigitList;
1735 UBool result = subparse(text,
1736 &affixPtn->negPrefixPatternForCurrency,
1737 &affixPtn->negSuffixPatternForCurrency,
1738 &affixPtn->posPrefixPatternForCurrency,
1739 &affixPtn->posSuffixPatternForCurrency,
1740 TRUE, affixPtn->patternType,
1741 tmpPos, tmpDigitList, tmpStatus, currency);
1742 if (result) {
1743 found = true;
1744 if (tmpPos.getIndex() > maxPosIndex) {
1745 maxPosIndex = tmpPos.getIndex();
1746 for (int32_t i = 0; i < fgStatusLength; ++i) {
1747 status[i] = tmpStatus[i];
1748 }
1749 digits = tmpDigitList;
1750 }
1751 } else {
1752 maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
1753 tmpPos.getErrorIndex() : maxErrorPos;
1754 }
1755 }
1756 // Finally, parse against simple affix to find the match.
1757 // For example, in TestMonster suite,
1758 // if the to-be-parsed text is "-\u00A40,00".
1759 // complexAffixCompare will not find match,
1760 // since there is no ISO code matches "\u00A4",
1761 // and the parse stops at "\u00A4".
1762 // We will just use simple affix comparison (look for exact match)
1763 // to pass it.
1764 UBool tmpStatus_2[fgStatusLength];
1765 ParsePosition tmpPos_2(origPos);
1766 DigitList tmpDigitList_2;
1767 // set currencySignCount to 0 so that compareAffix function will
1768 // fall to compareSimpleAffix path, not compareComplexAffix path.
1769 // ?? TODO: is it right? need "false"?
1770 UBool result = subparse(text,
1771 &fNegativePrefix, &fNegativeSuffix,
1772 &fPositivePrefix, &fPositiveSuffix,
1773 FALSE, UCURR_SYMBOL_NAME,
1774 tmpPos_2, tmpDigitList_2, tmpStatus_2,
1775 currency);
1776 if (result) {
1777 if (tmpPos_2.getIndex() > maxPosIndex) {
1778 maxPosIndex = tmpPos_2.getIndex();
1779 for (int32_t i = 0; i < fgStatusLength; ++i) {
1780 status[i] = tmpStatus_2[i];
1781 }
1782 digits = tmpDigitList_2;
1783 }
1784 found = true;
1785 } else {
1786 maxErrorPos = (tmpPos_2.getErrorIndex() > maxErrorPos) ?
1787 tmpPos_2.getErrorIndex() : maxErrorPos;
1788 }
1789
1790 if (!found) {
1791 //parsePosition.setIndex(origPos);
1792 parsePosition.setErrorIndex(maxErrorPos);
1793 } else {
1794 parsePosition.setIndex(maxPosIndex);
1795 parsePosition.setErrorIndex(-1);
1796 }
1797 return found;
1798 }
1799
1800
1801 /**
1802 * Parse the given text into a number. The text is parsed beginning at
1803 * parsePosition, until an unparseable character is seen.
1804 * @param text the string to parse.
1805 * @param negPrefix negative prefix.
1806 * @param negSuffix negative suffix.
1807 * @param posPrefix positive prefix.
1808 * @param posSuffix positive suffix.
1809 * @param currencyParsing whether it is currency parsing or not.
1810 * @param type the currency type to parse against, LONG_NAME only or not.
1811 * @param parsePosition The position at which to being parsing. Upon
1812 * return, the first unparsed character.
1813 * @param digits the DigitList to set to the parsed value.
1814 * @param status output param containing boolean status flags indicating
1815 * whether the value was infinite and whether it was positive.
1816 * @param currency return value for parsed currency, for generic
1817 * currency parsing mode, or NULL for normal parsing. In generic
1818 * currency parsing mode, any currency is parsed, not just the
1819 * currency that this formatter is set to.
1820 */
1821 UBool DecimalFormat::subparse(const UnicodeString& text,
1822 const UnicodeString* negPrefix,
1823 const UnicodeString* negSuffix,
1824 const UnicodeString* posPrefix,
1825 const UnicodeString* posSuffix,
1826 UBool currencyParsing,
1827 int8_t type,
1828 ParsePosition& parsePosition,
1829 DigitList& digits, UBool* status,
1830 UChar* currency) const
1831 {
1832 // The parsing process builds up the number as char string, in the neutral format that
1833 // will be acceptable to the decNumber library, then at the end passes that string
1834 // off for conversion to a decNumber.
1835 UErrorCode err = U_ZERO_ERROR;
1836 CharString parsedNum;
1837 digits.setToZero();
1838
1839 int32_t position = parsePosition.getIndex();
1840 int32_t oldStart = position;
1841 UBool strictParse = isParseStrict();
1842
1843 // Match padding before prefix
1844 if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) {
1845 position = skipPadding(text, position);
1846 }
1847
1848 // Match positive and negative prefixes; prefer longest match.
1849 int32_t posMatch = compareAffix(text, position, FALSE, TRUE, posPrefix, currencyParsing, type, currency);
1850 int32_t negMatch = compareAffix(text, position, TRUE, TRUE, negPrefix, currencyParsing, type, currency);
1851 if (posMatch >= 0 && negMatch >= 0) {
1852 if (posMatch > negMatch) {
1853 negMatch = -1;
1854 } else if (negMatch > posMatch) {
1855 posMatch = -1;
1856 }
1857 }
1858 if (posMatch >= 0) {
1859 position += posMatch;
1860 parsedNum.append('+', err);
1861 } else if (negMatch >= 0) {
1862 position += negMatch;
1863 parsedNum.append('-', err);
1864 } else if (strictParse){
1865 parsePosition.setErrorIndex(position);
1866 return FALSE;
1867 }
1868
1869 // Match padding before prefix
1870 if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) {
1871 position = skipPadding(text, position);
1872 }
1873
1874 if (! strictParse) {
1875 position = skipUWhiteSpace(text, position);
1876 }
1877
1878 // process digits or Inf, find decimal position
1879 const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
1880 int32_t infLen = (text.compare(position, inf->length(), *inf)
1881 ? 0 : inf->length());
1882 position += infLen; // infLen is non-zero when it does equal to infinity
1883 status[fgStatusInfinite] = infLen != 0;
1884
1885 if (infLen != 0)
1886 {
1887 parsedNum.append("Infinity", err);
1888 } else {
1889 // We now have a string of digits, possibly with grouping symbols,
1890 // and decimal points. We want to process these into a DigitList.
1891 // We don't want to put a bunch of leading zeros into the DigitList
1892 // though, so we keep track of the location of the decimal point,
1893 // put only significant digits into the DigitList, and adjust the
1894 // exponent as needed.
1895
1896 UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
1897
1898 UBool strictFail = FALSE; // did we exit with a strict parse failure?
1899 int32_t lastGroup = -1; // where did we last see a grouping separator?
1900 int32_t digitStart = position;
1901 int32_t gs2 = fGroupingSize2 == 0 ? fGroupingSize : fGroupingSize2;
1902
1903 #if CHECK_FOR_LEADING_ZERO
1904 // Strict parsing leading zeroes. If a leading zero would
1905 // be forced by the pattern, then don't fail strict parsing.
1906 UBool strictLeadingZero = FALSE;
1907 int32_t leadingZeroPos = 0;
1908 int32_t leadingZeroCount = 0;
1909 #endif
1910
1911 const UnicodeString *decimalString;
1912 if (fCurrencySignCount > fgCurrencySignCountZero) {
1913 decimalString = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
1914 } else {
1915 decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
1916 }
1917 UChar32 decimalChar = decimalString->char32At(0);
1918
1919 const UnicodeString *groupingString = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
1920 UChar32 groupingChar = groupingString->char32At(0);
1921 UBool sawDecimal = FALSE;
1922 UBool sawDigit = FALSE;
1923 int32_t backup = -1;
1924 int32_t digit;
1925 int32_t textLength = text.length(); // One less pointer to follow
1926 int32_t decimalStringLength = decimalString->length();
1927 int32_t decimalCharLength = U16_LENGTH(decimalChar);
1928 int32_t groupingStringLength = groupingString->length();
1929 int32_t groupingCharLength = U16_LENGTH(groupingChar);
1930
1931 // equivalent grouping and decimal support
1932 // TODO markdavis Cache these if it makes a difference in performance.
1933 UnicodeSet decimalFallback;
1934 UnicodeSet *decimalSet = NULL;
1935 UnicodeSet *groupingSet = NULL;
1936
1937 if (decimalCharLength == decimalStringLength) {
1938 decimalSet = (UnicodeSet *) DecimalFormatStaticSets::getSimilarDecimals(decimalChar, strictParse, &decimalFallback)->cloneAsThawed();
1939 }
1940
1941 if (groupingCharLength == groupingStringLength) {
1942 if (strictParse) {
1943 groupingSet = (UnicodeSet *) DecimalFormatStaticSets::gStaticSets->fStrictDefaultGroupingSeparators->cloneAsThawed();
1944 } else {
1945 groupingSet = (UnicodeSet *) DecimalFormatStaticSets::gStaticSets->fDefaultGroupingSeparators->cloneAsThawed();
1946 }
1947
1948 groupingSet->add(groupingChar);
1949
1950 if (decimalSet != NULL) {
1951 groupingSet->removeAll(*decimalSet);
1952 }
1953 }
1954
1955 // we are guaranteed that
1956 // decimalSet contains the decimal, and
1957 // groupingSet contains the groupingSeparator
1958 // (unless decimal and grouping are the same, which should never happen. But in that case, groupingSet will just be empty.)
1959
1960 // We have to track digitCount ourselves, because digits.fCount will
1961 // pin when the maximum allowable digits is reached.
1962 int32_t digitCount = 0;
1963 int32_t integerDigitCount = 0;
1964
1965 for (; position < textLength; )
1966 {
1967 UChar32 ch = text.char32At(position);
1968
1969 /* We recognize all digit ranges, not only the Latin digit range
1970 * '0'..'9'. We do so by using the Character.digit() method,
1971 * which converts a valid Unicode digit to the range 0..9.
1972 *
1973 * The character 'ch' may be a digit. If so, place its value
1974 * from 0 to 9 in 'digit'. First try using the locale digit,
1975 * which may or MAY NOT be a standard Unicode digit range. If
1976 * this fails, try using the standard Unicode digit ranges by
1977 * calling Character.digit(). If this also fails, digit will
1978 * have a value outside the range 0..9.
1979 */
1980 digit = ch - zero;
1981
1982 if (digit < 0 || digit > 9)
1983 {
1984 digit = u_charDigitValue(ch);
1985 }
1986
1987 // As a last resort, look through the localized digits if the zero digit
1988 // is not a "standard" Unicode digit.
1989 if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) {
1990 digit = 0;
1991 // Already check above (digit = ch - zero) for ch==zero; the only check we need to do here is:
1992 // if \u3007 is treated as 0 for parsing, \u96F6 should be too. Otherwise check for nonzero digits.
1993 if ( zero!=0x3007 || ch!=0x96F6 ) {
1994 for (digit = 1 ; digit < 10 ; digit++ ) {
1995 if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) {
1996 break;
1997 }
1998 }
1999 }
2000 }
2001
2002 if (digit >= 0 && digit <= 9)
2003 {
2004 if (strictParse && backup != -1) {
2005 // comma followed by digit, so group before comma is a
2006 // secondary group. If there was a group separator
2007 // before that, the group must == the secondary group
2008 // length, else it can be <= the the secondary group
2009 // length.
2010 if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||
2011 (lastGroup == -1 && position - digitStart - 1 > gs2)) {
2012 strictFail = TRUE;
2013 break;
2014 }
2015
2016 lastGroup = backup;
2017 }
2018
2019 // Cancel out backup setting (see grouping handler below)
2020 backup = -1;
2021 sawDigit = TRUE;
2022
2023 // Note: this will append leading zeros
2024 parsedNum.append((char)(digit + '0'), err);
2025
2026 // count any digit that's not a leading zero
2027 if (digit > 0 || digitCount > 0 || sawDecimal) {
2028 digitCount += 1;
2029
2030 // count any integer digit that's not a leading zero
2031 if (! sawDecimal) {
2032 integerDigitCount += 1;
2033 }
2034 #if CHECK_FOR_LEADING_ZERO
2035 } else if (strictParse && ! fUseExponentialNotation) {
2036 // TODO: Not sure we need to check fUseExponentialNotation
2037 if (!strictLeadingZero) {
2038 leadingZeroPos = position + U16_LENGTH(ch);
2039 strictLeadingZero = TRUE;
2040 }
2041
2042 leadingZeroCount += 1;
2043 #endif
2044 }
2045
2046 position += U16_LENGTH(ch);
2047 }
2048 else if (groupingStringLength > 0 && matchSymbol(text, position, groupingStringLength, *groupingString, groupingSet, ch) && isGroupingUsed())
2049 {
2050 if (sawDecimal) {
2051 break;
2052 }
2053
2054 if (strictParse) {
2055 if ( (!sawDigit && groupingSet!=NULL && u_isWhitespace(ch)) || backup != -1 ) {
2056 // We differ from the ICU4J code by allowing a leading group sep in strict mode (for
2057 // backward compatibility) as long as it is not one of the breaking whitespace characters
2058 // that is only treated as a group separator because of the equivalence set. If we get
2059 // here it is because the leading sep was such a breaking space, or there were multiple
2060 // group separators in a row. Note that the DecimalFormat documentation says
2061 // "During parsing, grouping separators are ignored" and that was for strict parsing,
2062 // so we may need to further revisit this strictParse restriction to ensure compatibility.
2063 // Also note: u_isWhitespace is true for all Zs/Zl/Zp except the no-break ones: 00A0,2007,202F.
2064 // In CLDR, all locales that have space as a group separator use 00A0 (NBSP).
2065 strictFail = TRUE;
2066 break;
2067 }
2068 }
2069
2070 // Ignore grouping characters, if we are using them, but require
2071 // that they be followed by a digit. Otherwise we backup and
2072 // reprocess them.
2073 backup = position;
2074 position += groupingStringLength;
2075
2076 if (groupingSet != NULL) {
2077 // Once we see a grouping character, we only accept that grouping character from then on.
2078 groupingSet->set(ch, ch);
2079 }
2080 }
2081 else if (matchSymbol(text, position, decimalStringLength, *decimalString, decimalSet, ch))
2082 {
2083 if (strictParse) {
2084 if (backup != -1 ||
2085 (lastGroup != -1 && position - lastGroup != fGroupingSize + 1)) {
2086 strictFail = TRUE;
2087 break;
2088 }
2089 }
2090
2091 // If we're only parsing integers, or if we ALREADY saw the
2092 // decimal, then don't parse this one.
2093 if (isParseIntegerOnly() || sawDecimal) {
2094 break;
2095 }
2096
2097 parsedNum.append('.', err);
2098 position += decimalStringLength;
2099 sawDecimal = TRUE;
2100
2101 if (decimalSet != NULL) {
2102 // Once we see a decimal character, we only accept that decimal character from then on.
2103 decimalSet->set(ch, ch);
2104 }
2105 }
2106 else
2107 {
2108 const UnicodeString *tmp;
2109 tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
2110 if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit
2111 {
2112 // Parse sign, if present
2113 int32_t pos = position + tmp->length();
2114 char exponentSign = '+';
2115
2116 if (pos < textLength)
2117 {
2118 tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2119 if (!text.compare(pos, tmp->length(), *tmp))
2120 {
2121 pos += tmp->length();
2122 }
2123 else {
2124 tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2125 if (!text.compare(pos, tmp->length(), *tmp))
2126 {
2127 exponentSign = '-';
2128 pos += tmp->length();
2129 }
2130 }
2131 }
2132
2133 UBool sawExponentDigit = FALSE;
2134 while (pos < textLength) {
2135 ch = text[(int32_t)pos];
2136 digit = ch - zero;
2137
2138 if (digit < 0 || digit > 9) {
2139 digit = u_charDigitValue(ch);
2140 }
2141 if (0 <= digit && digit <= 9) {
2142 if (!sawExponentDigit) {
2143 parsedNum.append('E', err);
2144 parsedNum.append(exponentSign, err);
2145 sawExponentDigit = TRUE;
2146 }
2147 ++pos;
2148 parsedNum.append((char)(digit + '0'), err);
2149 } else {
2150 break;
2151 }
2152 }
2153
2154 if (sawExponentDigit) {
2155 position = pos; // Advance past the exponent
2156 }
2157
2158 break; // Whether we fail or succeed, we exit this loop
2159 }
2160 else {
2161 break;
2162 }
2163 }
2164 }
2165
2166 delete groupingSet;
2167 delete decimalSet;
2168
2169 if (backup != -1)
2170 {
2171 position = backup;
2172 }
2173
2174 #if CHECK_FOR_LEADING_ZERO
2175 // check for strict parse errors
2176 if (strictParse && strictLeadingZero) {
2177 int32_t minIntegerDigits = getMinimumIntegerDigits();
2178
2179 if (minIntegerDigits == 0 && integerDigitCount == 0) {
2180 minIntegerDigits = 1;
2181 }
2182
2183 if ((leadingZeroCount + integerDigitCount) > minIntegerDigits) {
2184 parsePosition.setIndex(oldStart);
2185 parsePosition.setErrorIndex(leadingZeroPos);
2186 return FALSE;
2187 }
2188 }
2189 #endif
2190
2191 if (strictParse && !sawDecimal) {
2192 if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) {
2193 strictFail = TRUE;
2194 }
2195 }
2196
2197 if (strictFail) {
2198 // only set with strictParse and a leading zero error
2199 // leading zeros are an error with strict parsing except
2200 // immediately before nondigit (except group separator
2201 // followed by digit), or end of text.
2202
2203 parsePosition.setIndex(oldStart);
2204 parsePosition.setErrorIndex(position);
2205 return FALSE;
2206 }
2207
2208 // If there was no decimal point we have an integer
2209
2210 // If none of the text string was recognized. For example, parse
2211 // "x" with pattern "#0.00" (return index and error index both 0)
2212 // parse "$" with pattern "$#0.00". (return index 0 and error index
2213 // 1).
2214 if (!sawDigit && digitCount == 0) {
2215 parsePosition.setIndex(oldStart);
2216 parsePosition.setErrorIndex(oldStart);
2217 return FALSE;
2218 }
2219 }
2220
2221 // Match padding before suffix
2222 if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) {
2223 position = skipPadding(text, position);
2224 }
2225
2226 int32_t posSuffixMatch = -1, negSuffixMatch = -1;
2227
2228 // Match positive and negative suffixes; prefer longest match.
2229 if (posMatch >= 0 || (!strictParse && negMatch < 0)) {
2230 posSuffixMatch = compareAffix(text, position, FALSE, FALSE, posSuffix, currencyParsing, type, currency);
2231 }
2232 if (negMatch >= 0) {
2233 negSuffixMatch = compareAffix(text, position, TRUE, FALSE, negSuffix, currencyParsing, type, currency);
2234 }
2235 if (posSuffixMatch >= 0 && negSuffixMatch >= 0) {
2236 if (posSuffixMatch > negSuffixMatch) {
2237 negSuffixMatch = -1;
2238 } else if (negSuffixMatch > posSuffixMatch) {
2239 posSuffixMatch = -1;
2240 }
2241 }
2242
2243 // Fail if neither or both
2244 if (strictParse && ((posSuffixMatch >= 0) == (negSuffixMatch >= 0))) {
2245 parsePosition.setErrorIndex(position);
2246 return FALSE;
2247 }
2248
2249 position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0));
2250
2251 // Match padding before suffix
2252 if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) {
2253 position = skipPadding(text, position);
2254 }
2255
2256 parsePosition.setIndex(position);
2257
2258 parsedNum.data()[0] = (posSuffixMatch >= 0 || (!strictParse && negMatch < 0 && negSuffixMatch < 0)) ? '+' : '-';
2259
2260 if(parsePosition.getIndex() == oldStart)
2261 {
2262 parsePosition.setErrorIndex(position);
2263 return FALSE;
2264 }
2265 digits.set(parsedNum.toStringPiece(), err);
2266
2267 if (U_FAILURE(err)) {
2268 parsePosition.setErrorIndex(position);
2269 return FALSE;
2270 }
2271 return TRUE;
2272 }
2273
2274 /**
2275 * Starting at position, advance past a run of pad characters, if any.
2276 * Return the index of the first character after position that is not a pad
2277 * character. Result is >= position.
2278 */
2279 int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const {
2280 int32_t padLen = U16_LENGTH(fPad);
2281 while (position < text.length() &&
2282 text.char32At(position) == fPad) {
2283 position += padLen;
2284 }
2285 return position;
2286 }
2287
2288 /**
2289 * Return the length matched by the given affix, or -1 if none.
2290 * Runs of white space in the affix, match runs of white space in
2291 * the input. Pattern white space and input white space are
2292 * determined differently; see code.
2293 * @param text input text
2294 * @param pos offset into input at which to begin matching
2295 * @param isNegative
2296 * @param isPrefix
2297 * @param affixPat affix pattern used for currency affix comparison.
2298 * @param currencyParsing whether it is currency parsing or not
2299 * @param type the currency type to parse against, LONG_NAME only or not.
2300 * @param currency return value for parsed currency, for generic
2301 * currency parsing mode, or null for normal parsing. In generic
2302 * currency parsing mode, any currency is parsed, not just the
2303 * currency that this formatter is set to.
2304 * @return length of input that matches, or -1 if match failure
2305 */
2306 int32_t DecimalFormat::compareAffix(const UnicodeString& text,
2307 int32_t pos,
2308 UBool isNegative,
2309 UBool isPrefix,
2310 const UnicodeString* affixPat,
2311 UBool currencyParsing,
2312 int8_t type,
2313 UChar* currency) const
2314 {
2315 const UnicodeString *patternToCompare;
2316 if (fCurrencyChoice != NULL || currency != NULL ||
2317 (fCurrencySignCount > fgCurrencySignCountZero && currencyParsing)) {
2318
2319 if (affixPat != NULL) {
2320 return compareComplexAffix(*affixPat, text, pos, type, currency);
2321 }
2322 }
2323
2324 if (isNegative) {
2325 if (isPrefix) {
2326 patternToCompare = &fNegativePrefix;
2327 }
2328 else {
2329 patternToCompare = &fNegativeSuffix;
2330 }
2331 }
2332 else {
2333 if (isPrefix) {
2334 patternToCompare = &fPositivePrefix;
2335 }
2336 else {
2337 patternToCompare = &fPositiveSuffix;
2338 }
2339 }
2340 return compareSimpleAffix(*patternToCompare, text, pos, isParseStrict());
2341 }
2342
2343 /**
2344 * Return the length matched by the given affix, or -1 if none.
2345 * Runs of white space in the affix, match runs of white space in
2346 * the input. Pattern white space and input white space are
2347 * determined differently; see code.
2348 * @param affix pattern string, taken as a literal
2349 * @param input input text
2350 * @param pos offset into input at which to begin matching
2351 * @return length of input that matches, or -1 if match failure
2352 */
2353 int32_t DecimalFormat::compareSimpleAffix(const UnicodeString& affix,
2354 const UnicodeString& input,
2355 int32_t pos,
2356 UBool strict) {
2357 UErrorCode status = U_ZERO_ERROR;
2358 int32_t start = pos;
2359 UChar32 affixChar = affix.char32At(0);
2360 int32_t affixLength = affix.length();
2361 int32_t inputLength = input.length();
2362 int32_t affixCharLength = U16_LENGTH(affixChar);
2363 UnicodeSet *affixSet;
2364
2365 DecimalFormatStaticSets::initSets(&status);
2366
2367 if (strict) {
2368 affixSet = DecimalFormatStaticSets::gStaticSets->fStrictDashEquivalents;
2369
2370 // If the affix is exactly one character long and that character
2371 // is in the dash set and the very next input character is also
2372 // in the dash set, return a match.
2373 if (affixCharLength == affixLength && affixSet->contains(affixChar)) {
2374 if (affixSet->contains(input.char32At(pos))) {
2375 return 1;
2376 }
2377 }
2378
2379 for (int32_t i = 0; i < affixLength; ) {
2380 UChar32 c = affix.char32At(i);
2381 int32_t len = U16_LENGTH(c);
2382 if (uprv_isRuleWhiteSpace(c)) {
2383 // We may have a pattern like: \u200F \u0020
2384 // and input text like: \u200F \u0020
2385 // Note that U+200F and U+0020 are RuleWhiteSpace but only
2386 // U+0020 is UWhiteSpace. So we have to first do a direct
2387 // match of the run of RULE whitespace in the pattern,
2388 // then match any extra characters.
2389 UBool literalMatch = FALSE;
2390 while (pos < inputLength &&
2391 input.char32At(pos) == c) {
2392 literalMatch = TRUE;
2393 i += len;
2394 pos += len;
2395 if (i == affixLength) {
2396 break;
2397 }
2398 c = affix.char32At(i);
2399 len = U16_LENGTH(c);
2400 if (!uprv_isRuleWhiteSpace(c)) {
2401 break;
2402 }
2403 }
2404
2405 // Advance over run in pattern
2406 i = skipRuleWhiteSpace(affix, i);
2407
2408 // Advance over run in input text
2409 // Must see at least one white space char in input,
2410 // unless we've already matched some characters literally.
2411 int32_t s = pos;
2412 pos = skipUWhiteSpace(input, pos);
2413 if (pos == s && !literalMatch) {
2414 return -1;
2415 }
2416
2417 // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
2418 // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
2419 // is also in the affix.
2420 i = skipUWhiteSpace(affix, i);
2421 } else {
2422 if (pos < inputLength &&
2423 input.char32At(pos) == c) {
2424 i += len;
2425 pos += len;
2426 } else {
2427 return -1;
2428 }
2429 }
2430 }
2431 } else {
2432 UBool match = FALSE;
2433
2434 affixSet = DecimalFormatStaticSets::gStaticSets->fDashEquivalents;
2435
2436 if (affixCharLength == affixLength && affixSet->contains(affixChar)) {
2437 pos = skipUWhiteSpace(input, pos);
2438
2439 if (affixSet->contains(input.char32At(pos))) {
2440 return pos - start + 1;
2441 }
2442 }
2443
2444 for (int32_t i = 0; i < affixLength; )
2445 {
2446 //i = skipRuleWhiteSpace(affix, i);
2447 i = skipUWhiteSpace(affix, i);
2448 pos = skipUWhiteSpace(input, pos);
2449
2450 if (i >= affixLength || pos >= inputLength) {
2451 break;
2452 }
2453
2454 UChar32 c = affix.char32At(i);
2455 int32_t len = U16_LENGTH(c);
2456
2457 if (input.char32At(pos) != c) {
2458 return -1;
2459 }
2460
2461 match = TRUE;
2462 i += len;
2463 pos += len;
2464 }
2465
2466 if (affixLength > 0 && ! match) {
2467 return -1;
2468 }
2469 }
2470
2471 return pos - start;
2472 }
2473
2474 /**
2475 * Skip over a run of zero or more isRuleWhiteSpace() characters at
2476 * pos in text.
2477 */
2478 int32_t DecimalFormat::skipRuleWhiteSpace(const UnicodeString& text, int32_t pos) {
2479 while (pos < text.length()) {
2480 UChar32 c = text.char32At(pos);
2481 if (!uprv_isRuleWhiteSpace(c)) {
2482 break;
2483 }
2484 pos += U16_LENGTH(c);
2485 }
2486 return pos;
2487 }
2488
2489 /**
2490 * Skip over a run of zero or more isUWhiteSpace() characters at pos
2491 * in text.
2492 */
2493 int32_t DecimalFormat::skipUWhiteSpace(const UnicodeString& text, int32_t pos) {
2494 while (pos < text.length()) {
2495 UChar32 c = text.char32At(pos);
2496 if (!u_isUWhiteSpace(c)) {
2497 break;
2498 }
2499 pos += U16_LENGTH(c);
2500 }
2501 return pos;
2502 }
2503
2504 /**
2505 * Return the length matched by the given affix, or -1 if none.
2506 * @param affixPat pattern string
2507 * @param input input text
2508 * @param pos offset into input at which to begin matching
2509 * @param type the currency type to parse against, LONG_NAME only or not.
2510 * @param currency return value for parsed currency, for generic
2511 * currency parsing mode, or null for normal parsing. In generic
2512 * currency parsing mode, any currency is parsed, not just the
2513 * currency that this formatter is set to.
2514 * @return length of input that matches, or -1 if match failure
2515 */
2516 int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat,
2517 const UnicodeString& text,
2518 int32_t pos,
2519 int8_t type,
2520 UChar* currency) const
2521 {
2522 int32_t start = pos;
2523 U_ASSERT(currency != NULL ||
2524 (fCurrencyChoice != NULL && *getCurrency() != 0) ||
2525 fCurrencySignCount > fgCurrencySignCountZero);
2526
2527 for (int32_t i=0;
2528 i<affixPat.length() && pos >= 0; ) {
2529 UChar32 c = affixPat.char32At(i);
2530 i += U16_LENGTH(c);
2531
2532 if (c == kQuote) {
2533 U_ASSERT(i <= affixPat.length());
2534 c = affixPat.char32At(i);
2535 i += U16_LENGTH(c);
2536
2537 const UnicodeString* affix = NULL;
2538
2539 switch (c) {
2540 case kCurrencySign: {
2541 // since the currency names in choice format is saved
2542 // the same way as other currency names,
2543 // do not need to do currency choice parsing here.
2544 // the general currency parsing parse against all names,
2545 // including names in choice format.
2546 UBool intl = i<affixPat.length() &&
2547 affixPat.char32At(i) == kCurrencySign;
2548 if (intl) {
2549 ++i;
2550 }
2551 UBool plural = i<affixPat.length() &&
2552 affixPat.char32At(i) == kCurrencySign;
2553 if (plural) {
2554 ++i;
2555 intl = FALSE;
2556 }
2557 // Parse generic currency -- anything for which we
2558 // have a display name, or any 3-letter ISO code.
2559 // Try to parse display name for our locale; first
2560 // determine our locale.
2561 const char* loc = fCurrencyPluralInfo->getLocale().getName();
2562 ParsePosition ppos(pos);
2563 UChar curr[4];
2564 UErrorCode ec = U_ZERO_ERROR;
2565 // Delegate parse of display name => ISO code to Currency
2566 uprv_parseCurrency(loc, text, ppos, type, curr, ec);
2567
2568 // If parse succeeds, populate currency[0]
2569 if (U_SUCCESS(ec) && ppos.getIndex() != pos) {
2570 if (currency) {
2571 u_strcpy(currency, curr);
2572 } else if (isParseStrict()) {
2573 // The formatter is currency-style but the client has not requested
2574 // the value of the parsed currency. In this case, if that value does
2575 // not match the formatter's current value, then the parse fails.
2576 UChar effectiveCurr[4];
2577 getEffectiveCurrency(effectiveCurr, ec);
2578 if ( U_FAILURE(ec) || u_strncmp(curr,effectiveCurr,3) != 0 ) {
2579 pos = -1;
2580 continue;
2581 }
2582 }
2583 pos = ppos.getIndex();
2584 } else if (isParseStrict()){
2585 pos = -1;
2586 }
2587 continue;
2588 }
2589 case kPatternPercent:
2590 affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
2591 break;
2592 case kPatternPerMill:
2593 affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
2594 break;
2595 case kPatternPlus:
2596 affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
2597 break;
2598 case kPatternMinus:
2599 affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
2600 break;
2601 default:
2602 // fall through to affix!=0 test, which will fail
2603 break;
2604 }
2605
2606 if (affix != NULL) {
2607 pos = match(text, pos, *affix);
2608 continue;
2609 }
2610 }
2611
2612 pos = match(text, pos, c);
2613 if (uprv_isRuleWhiteSpace(c)) {
2614 i = skipRuleWhiteSpace(affixPat, i);
2615 }
2616 }
2617 return pos - start;
2618 }
2619
2620 /**
2621 * Match a single character at text[pos] and return the index of the
2622 * next character upon success. Return -1 on failure. If
2623 * isRuleWhiteSpace(ch) then match a run of white space in text.
2624 */
2625 int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, UChar32 ch) {
2626 if (uprv_isRuleWhiteSpace(ch)) {
2627 // Advance over run of white space in input text
2628 // Must see at least one white space char in input
2629 int32_t s = pos;
2630 pos = skipRuleWhiteSpace(text, pos);
2631 if (pos == s) {
2632 return -1;
2633 }
2634 return pos;
2635 }
2636 return (pos >= 0 && text.char32At(pos) == ch) ?
2637 (pos + U16_LENGTH(ch)) : -1;
2638 }
2639
2640 /**
2641 * Match a string at text[pos] and return the index of the next
2642 * character upon success. Return -1 on failure. Match a run of
2643 * white space in str with a run of white space in text.
2644 */
2645 int32_t DecimalFormat::match(const UnicodeString& text, int32_t pos, const UnicodeString& str) {
2646 for (int32_t i=0; i<str.length() && pos >= 0; ) {
2647 UChar32 ch = str.char32At(i);
2648 i += U16_LENGTH(ch);
2649 if (uprv_isRuleWhiteSpace(ch)) {
2650 i = skipRuleWhiteSpace(str, i);
2651 }
2652 pos = match(text, pos, ch);
2653 }
2654 return pos;
2655 }
2656
2657 UBool DecimalFormat::matchSymbol(const UnicodeString &text, int32_t position, int32_t length, const UnicodeString &symbol,
2658 UnicodeSet *sset, UChar32 schar)
2659 {
2660 if (sset != NULL) {
2661 return sset->contains(schar);
2662 }
2663
2664 return text.compare(position, length, symbol) == 0;
2665 }
2666
2667
2668 //------------------------------------------------------------------------------
2669 // Gets the pointer to the localized decimal format symbols
2670
2671 const DecimalFormatSymbols*
2672 DecimalFormat::getDecimalFormatSymbols() const
2673 {
2674 return fSymbols;
2675 }
2676
2677 //------------------------------------------------------------------------------
2678 // De-owning the current localized symbols and adopt the new symbols.
2679
2680 void
2681 DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt)
2682 {
2683 if (symbolsToAdopt == NULL) {
2684 return; // do not allow caller to set fSymbols to NULL
2685 }
2686
2687 UBool sameSymbols = FALSE;
2688 if (fSymbols != NULL) {
2689 sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) ==
2690 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) &&
2691 getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) ==
2692 symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
2693 delete fSymbols;
2694 }
2695
2696 fSymbols = symbolsToAdopt;
2697 if (!sameSymbols) {
2698 // If the currency symbols are the same, there is no need to recalculate.
2699 setCurrencyForSymbols();
2700 }
2701 expandAffixes(NULL);
2702 }
2703 //------------------------------------------------------------------------------
2704 // Setting the symbols is equlivalent to adopting a newly created localized
2705 // symbols.
2706
2707 void
2708 DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols)
2709 {
2710 adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
2711 }
2712
2713 const CurrencyPluralInfo*
2714 DecimalFormat::getCurrencyPluralInfo(void) const
2715 {
2716 return fCurrencyPluralInfo;
2717 }
2718
2719 void
2720 DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt)
2721 {
2722 if (toAdopt != NULL) {
2723 delete fCurrencyPluralInfo;
2724 fCurrencyPluralInfo = toAdopt;
2725 // re-set currency affix patterns and currency affixes.
2726 if (fCurrencySignCount > fgCurrencySignCountZero) {
2727 UErrorCode status = U_ZERO_ERROR;
2728 if (fAffixPatternsForCurrency) {
2729 deleteHashForAffixPattern();
2730 }
2731 setupCurrencyAffixPatterns(status);
2732 if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) {
2733 // only setup the affixes of the plural pattern.
2734 setupCurrencyAffixes(fFormatPattern, FALSE, TRUE, status);
2735 }
2736 }
2737 }
2738 }
2739
2740 void
2741 DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info)
2742 {
2743 adoptCurrencyPluralInfo(info.clone());
2744 }
2745
2746
2747 /**
2748 * Update the currency object to match the symbols. This method
2749 * is used only when the caller has passed in a symbols object
2750 * that may not be the default object for its locale.
2751 */
2752 void
2753 DecimalFormat::setCurrencyForSymbols() {
2754 /*Bug 4212072
2755 Update the affix strings accroding to symbols in order to keep
2756 the affix strings up to date.
2757 [Richard/GCL]
2758 */
2759
2760 // With the introduction of the Currency object, the currency
2761 // symbols in the DFS object are ignored. For backward
2762 // compatibility, we check any explicitly set DFS object. If it
2763 // is a default symbols object for its locale, we change the
2764 // currency object to one for that locale. If it is custom,
2765 // we set the currency to null.
2766 UErrorCode ec = U_ZERO_ERROR;
2767 const UChar* c = NULL;
2768 const char* loc = fSymbols->getLocale().getName();
2769 UChar intlCurrencySymbol[4];
2770 ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec);
2771 UnicodeString currencySymbol;
2772
2773 uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec);
2774 if (U_SUCCESS(ec)
2775 && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol
2776 && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == intlCurrencySymbol)
2777 {
2778 // Trap an error in mapping locale to currency. If we can't
2779 // map, then don't fail and set the currency to "".
2780 c = intlCurrencySymbol;
2781 }
2782 ec = U_ZERO_ERROR; // reset local error code!
2783 setCurrencyInternally(c, ec);
2784 }
2785
2786
2787 //------------------------------------------------------------------------------
2788 // Gets the positive prefix of the number pattern.
2789
2790 UnicodeString&
2791 DecimalFormat::getPositivePrefix(UnicodeString& result) const
2792 {
2793 result = fPositivePrefix;
2794 return result;
2795 }
2796
2797 //------------------------------------------------------------------------------
2798 // Sets the positive prefix of the number pattern.
2799
2800 void
2801 DecimalFormat::setPositivePrefix(const UnicodeString& newValue)
2802 {
2803 fPositivePrefix = newValue;
2804 delete fPosPrefixPattern;
2805 fPosPrefixPattern = 0;
2806 }
2807
2808 //------------------------------------------------------------------------------
2809 // Gets the negative prefix of the number pattern.
2810
2811 UnicodeString&
2812 DecimalFormat::getNegativePrefix(UnicodeString& result) const
2813 {
2814 result = fNegativePrefix;
2815 return result;
2816 }
2817
2818 //------------------------------------------------------------------------------
2819 // Gets the negative prefix of the number pattern.
2820
2821 void
2822 DecimalFormat::setNegativePrefix(const UnicodeString& newValue)
2823 {
2824 fNegativePrefix = newValue;
2825 delete fNegPrefixPattern;
2826 fNegPrefixPattern = 0;
2827 }
2828
2829 //------------------------------------------------------------------------------
2830 // Gets the positive suffix of the number pattern.
2831
2832 UnicodeString&
2833 DecimalFormat::getPositiveSuffix(UnicodeString& result) const
2834 {
2835 result = fPositiveSuffix;
2836 return result;
2837 }
2838
2839 //------------------------------------------------------------------------------
2840 // Sets the positive suffix of the number pattern.
2841
2842 void
2843 DecimalFormat::setPositiveSuffix(const UnicodeString& newValue)
2844 {
2845 fPositiveSuffix = newValue;
2846 delete fPosSuffixPattern;
2847 fPosSuffixPattern = 0;
2848 }
2849
2850 //------------------------------------------------------------------------------
2851 // Gets the negative suffix of the number pattern.
2852
2853 UnicodeString&
2854 DecimalFormat::getNegativeSuffix(UnicodeString& result) const
2855 {
2856 result = fNegativeSuffix;
2857 return result;
2858 }
2859
2860 //------------------------------------------------------------------------------
2861 // Sets the negative suffix of the number pattern.
2862
2863 void
2864 DecimalFormat::setNegativeSuffix(const UnicodeString& newValue)
2865 {
2866 fNegativeSuffix = newValue;
2867 delete fNegSuffixPattern;
2868 fNegSuffixPattern = 0;
2869 }
2870
2871 //------------------------------------------------------------------------------
2872 // Gets the multiplier of the number pattern.
2873 // Multipliers are stored as decimal numbers (DigitLists) because that
2874 // is the most convenient for muliplying or dividing the numbers to be formatted.
2875 // A NULL multiplier implies one, and the scaling operations are skipped.
2876
2877 int32_t
2878 DecimalFormat::getMultiplier() const
2879 {
2880 if (fMultiplier == NULL) {
2881 return 1;
2882 } else {
2883 return fMultiplier->getLong();
2884 }
2885 }
2886
2887 //------------------------------------------------------------------------------
2888 // Sets the multiplier of the number pattern.
2889 void
2890 DecimalFormat::setMultiplier(int32_t newValue)
2891 {
2892 // if (newValue == 0) {
2893 // throw new IllegalArgumentException("Bad multiplier: " + newValue);
2894 // }
2895 if (newValue == 0) {
2896 newValue = 1; // one being the benign default value for a multiplier.
2897 }
2898 if (newValue == 1) {
2899 delete fMultiplier;
2900 fMultiplier = NULL;
2901 } else {
2902 if (fMultiplier == NULL) {
2903 fMultiplier = new DigitList;
2904 }
2905 if (fMultiplier != NULL) {
2906 fMultiplier->set(newValue);
2907 }
2908 }
2909 }
2910
2911 /**
2912 * Get the rounding increment.
2913 * @return A positive rounding increment, or 0.0 if rounding
2914 * is not in effect.
2915 * @see #setRoundingIncrement
2916 * @see #getRoundingMode
2917 * @see #setRoundingMode
2918 */
2919 double DecimalFormat::getRoundingIncrement() const {
2920 if (fRoundingIncrement == NULL) {
2921 return 0.0;
2922 } else {
2923 return fRoundingIncrement->getDouble();
2924 }
2925 }
2926
2927 /**
2928 * Set the rounding increment. This method also controls whether
2929 * rounding is enabled.
2930 * @param newValue A positive rounding increment, or 0.0 to disable rounding.
2931 * Negative increments are equivalent to 0.0.
2932 * @see #getRoundingIncrement
2933 * @see #getRoundingMode
2934 * @see #setRoundingMode
2935 */
2936 void DecimalFormat::setRoundingIncrement(double newValue) {
2937 if (newValue > 0.0) {
2938 if (fRoundingIncrement == NULL) {
2939 fRoundingIncrement = new DigitList();
2940 }
2941 if (fRoundingIncrement != NULL) {
2942 fRoundingIncrement->set(newValue);
2943 return;
2944 }
2945 }
2946 // These statements are executed if newValue is less than 0.0
2947 // or fRoundingIncrement could not be created.
2948 delete fRoundingIncrement;
2949 fRoundingIncrement = NULL;
2950 }
2951
2952 /**
2953 * Get the rounding mode.
2954 * @return A rounding mode
2955 * @see #setRoundingIncrement
2956 * @see #getRoundingIncrement
2957 * @see #setRoundingMode
2958 */
2959 DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const {
2960 return fRoundingMode;
2961 }
2962
2963 /**
2964 * Set the rounding mode. This has no effect unless the rounding
2965 * increment is greater than zero.
2966 * @param roundingMode A rounding mode
2967 * @see #setRoundingIncrement
2968 * @see #getRoundingIncrement
2969 * @see #getRoundingMode
2970 */
2971 void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) {
2972 fRoundingMode = roundingMode;
2973 }
2974
2975 /**
2976 * Get the width to which the output of <code>format()</code> is padded.
2977 * @return the format width, or zero if no padding is in effect
2978 * @see #setFormatWidth
2979 * @see #getPadCharacter
2980 * @see #setPadCharacter
2981 * @see #getPadPosition
2982 * @see #setPadPosition
2983 */
2984 int32_t DecimalFormat::getFormatWidth() const {
2985 return fFormatWidth;
2986 }
2987
2988 /**
2989 * Set the width to which the output of <code>format()</code> is padded.
2990 * This method also controls whether padding is enabled.
2991 * @param width the width to which to pad the result of
2992 * <code>format()</code>, or zero to disable padding. A negative
2993 * width is equivalent to 0.
2994 * @see #getFormatWidth
2995 * @see #getPadCharacter
2996 * @see #setPadCharacter
2997 * @see #getPadPosition
2998 * @see #setPadPosition
2999 */
3000 void DecimalFormat::setFormatWidth(int32_t width) {
3001 fFormatWidth = (width > 0) ? width : 0;
3002 }
3003
3004 UnicodeString DecimalFormat::getPadCharacterString() const {
3005 return fPad;
3006 }
3007
3008 void DecimalFormat::setPadCharacter(const UnicodeString &padChar) {
3009 if (padChar.length() > 0) {
3010 fPad = padChar.char32At(0);
3011 }
3012 else {
3013 fPad = kDefaultPad;
3014 }
3015 }
3016
3017 /**
3018 * Get the position at which padding will take place. This is the location
3019 * at which padding will be inserted if the result of <code>format()</code>
3020 * is shorter than the format width.
3021 * @return the pad position, one of <code>kPadBeforePrefix</code>,
3022 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
3023 * <code>kPadAfterSuffix</code>.
3024 * @see #setFormatWidth
3025 * @see #getFormatWidth
3026 * @see #setPadCharacter
3027 * @see #getPadCharacter
3028 * @see #setPadPosition
3029 * @see #kPadBeforePrefix
3030 * @see #kPadAfterPrefix
3031 * @see #kPadBeforeSuffix
3032 * @see #kPadAfterSuffix
3033 */
3034 DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const {
3035 return fPadPosition;
3036 }
3037
3038 /**
3039 * <strong><font face=helvetica color=red>NEW</font></strong>
3040 * Set the position at which padding will take place. This is the location
3041 * at which padding will be inserted if the result of <code>format()</code>
3042 * is shorter than the format width. This has no effect unless padding is
3043 * enabled.
3044 * @param padPos the pad position, one of <code>kPadBeforePrefix</code>,
3045 * <code>kPadAfterPrefix</code>, <code>kPadBeforeSuffix</code>, or
3046 * <code>kPadAfterSuffix</code>.
3047 * @see #setFormatWidth
3048 * @see #getFormatWidth
3049 * @see #setPadCharacter
3050 * @see #getPadCharacter
3051 * @see #getPadPosition
3052 * @see #kPadBeforePrefix
3053 * @see #kPadAfterPrefix
3054 * @see #kPadBeforeSuffix
3055 * @see #kPadAfterSuffix
3056 */
3057 void DecimalFormat::setPadPosition(EPadPosition padPos) {
3058 fPadPosition = padPos;
3059 }
3060
3061 /**
3062 * Return whether or not scientific notation is used.
3063 * @return TRUE if this object formats and parses scientific notation
3064 * @see #setScientificNotation
3065 * @see #getMinimumExponentDigits
3066 * @see #setMinimumExponentDigits
3067 * @see #isExponentSignAlwaysShown
3068 * @see #setExponentSignAlwaysShown
3069 */
3070 UBool DecimalFormat::isScientificNotation() {
3071 return fUseExponentialNotation;
3072 }
3073
3074 /**
3075 * Set whether or not scientific notation is used.
3076 * @param useScientific TRUE if this object formats and parses scientific
3077 * notation
3078 * @see #isScientificNotation
3079 * @see #getMinimumExponentDigits
3080 * @see #setMinimumExponentDigits
3081 * @see #isExponentSignAlwaysShown
3082 * @see #setExponentSignAlwaysShown
3083 */
3084 void DecimalFormat::setScientificNotation(UBool useScientific) {
3085 fUseExponentialNotation = useScientific;
3086 }
3087
3088 /**
3089 * Return the minimum exponent digits that will be shown.
3090 * @return the minimum exponent digits that will be shown
3091 * @see #setScientificNotation
3092 * @see #isScientificNotation
3093 * @see #setMinimumExponentDigits
3094 * @see #isExponentSignAlwaysShown
3095 * @see #setExponentSignAlwaysShown
3096 */
3097 int8_t DecimalFormat::getMinimumExponentDigits() const {
3098 return fMinExponentDigits;
3099 }
3100
3101 /**
3102 * Set the minimum exponent digits that will be shown. This has no
3103 * effect unless scientific notation is in use.
3104 * @param minExpDig a value >= 1 indicating the fewest exponent digits
3105 * that will be shown. Values less than 1 will be treated as 1.
3106 * @see #setScientificNotation
3107 * @see #isScientificNotation
3108 * @see #getMinimumExponentDigits
3109 * @see #isExponentSignAlwaysShown
3110 * @see #setExponentSignAlwaysShown
3111 */
3112 void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) {
3113 fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1);
3114 }
3115
3116 /**
3117 * Return whether the exponent sign is always shown.
3118 * @return TRUE if the exponent is always prefixed with either the
3119 * localized minus sign or the localized plus sign, false if only negative
3120 * exponents are prefixed with the localized minus sign.
3121 * @see #setScientificNotation
3122 * @see #isScientificNotation
3123 * @see #setMinimumExponentDigits
3124 * @see #getMinimumExponentDigits
3125 * @see #setExponentSignAlwaysShown
3126 */
3127 UBool DecimalFormat::isExponentSignAlwaysShown() {
3128 return fExponentSignAlwaysShown;
3129 }
3130
3131 /**
3132 * Set whether the exponent sign is always shown. This has no effect
3133 * unless scientific notation is in use.
3134 * @param expSignAlways TRUE if the exponent is always prefixed with either
3135 * the localized minus sign or the localized plus sign, false if only
3136 * negative exponents are prefixed with the localized minus sign.
3137 * @see #setScientificNotation
3138 * @see #isScientificNotation
3139 * @see #setMinimumExponentDigits
3140 * @see #getMinimumExponentDigits
3141 * @see #isExponentSignAlwaysShown
3142 */
3143 void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) {
3144 fExponentSignAlwaysShown = expSignAlways;
3145 }
3146
3147 //------------------------------------------------------------------------------
3148 // Gets the grouping size of the number pattern. For example, thousand or 10
3149 // thousand groupings.
3150
3151 int32_t
3152 DecimalFormat::getGroupingSize() const
3153 {
3154 return fGroupingSize;
3155 }
3156
3157 //------------------------------------------------------------------------------
3158 // Gets the grouping size of the number pattern.
3159
3160 void
3161 DecimalFormat::setGroupingSize(int32_t newValue)
3162 {
3163 fGroupingSize = newValue;
3164 }
3165
3166 //------------------------------------------------------------------------------
3167
3168 int32_t
3169 DecimalFormat::getSecondaryGroupingSize() const
3170 {
3171 return fGroupingSize2;
3172 }
3173
3174 //------------------------------------------------------------------------------
3175
3176 void
3177 DecimalFormat::setSecondaryGroupingSize(int32_t newValue)
3178 {
3179 fGroupingSize2 = newValue;
3180 }
3181
3182 //------------------------------------------------------------------------------
3183 // Checks if to show the decimal separator.
3184
3185 UBool
3186 DecimalFormat::isDecimalSeparatorAlwaysShown() const
3187 {
3188 return fDecimalSeparatorAlwaysShown;
3189 }
3190
3191 //------------------------------------------------------------------------------
3192 // Sets to always show the decimal separator.
3193
3194 void
3195 DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue)
3196 {
3197 fDecimalSeparatorAlwaysShown = newValue;
3198 }
3199
3200 //------------------------------------------------------------------------------
3201 // Emits the pattern of this DecimalFormat instance.
3202
3203 UnicodeString&
3204 DecimalFormat::toPattern(UnicodeString& result) const
3205 {
3206 return toPattern(result, FALSE);
3207 }
3208
3209 //------------------------------------------------------------------------------
3210 // Emits the localized pattern this DecimalFormat instance.
3211
3212 UnicodeString&
3213 DecimalFormat::toLocalizedPattern(UnicodeString& result) const
3214 {
3215 return toPattern(result, TRUE);
3216 }
3217
3218 //------------------------------------------------------------------------------
3219 /**
3220 * Expand the affix pattern strings into the expanded affix strings. If any
3221 * affix pattern string is null, do not expand it. This method should be
3222 * called any time the symbols or the affix patterns change in order to keep
3223 * the expanded affix strings up to date.
3224 * This method also will be called before formatting if format currency
3225 * plural names, since the plural name is not a static one, it is
3226 * based on the currency plural count, the affix will be known only
3227 * after the currency plural count is know.
3228 * In which case, the parameter
3229 * 'pluralCount' will be a non-null currency plural count.
3230 * In all other cases, the 'pluralCount' is null, which means it is not needed.
3231 */
3232 void DecimalFormat::expandAffixes(const UnicodeString* pluralCount) {
3233 FieldPositionHandler none;
3234 if (fPosPrefixPattern != 0) {
3235 expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, none, FALSE, pluralCount);
3236 }
3237 if (fPosSuffixPattern != 0) {
3238 expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, none, FALSE, pluralCount);
3239 }
3240 if (fNegPrefixPattern != 0) {
3241 expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, none, FALSE, pluralCount);
3242 }
3243 if (fNegSuffixPattern != 0) {
3244 expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, none, FALSE, pluralCount);
3245 }
3246 #ifdef FMT_DEBUG
3247 UnicodeString s;
3248 s.append("[")
3249 .append(*fPosPrefixPattern).append("|").append(*fPosSuffixPattern)
3250 .append(";") .append(*fNegPrefixPattern).append("|").append(*fNegSuffixPattern)
3251 .append("]->[")
3252 .append(fPositivePrefix).append("|").append(fPositiveSuffix)
3253 .append(";") .append(fNegativePrefix).append("|").append(fNegativeSuffix)
3254 .append("]\n");
3255 debugout(s);
3256 #endif
3257 }
3258
3259 /**
3260 * Expand an affix pattern into an affix string. All characters in the
3261 * pattern are literal unless prefixed by kQuote. The following characters
3262 * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE,
3263 * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote +
3264 * kCurrencySign + kCurrencySign), it is interpreted as an international
3265 * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as
3266 * currency plural long names, such as "US Dollars".
3267 * Any other character after a kQuote represents itself.
3268 * kQuote must be followed by another character; kQuote may not occur by
3269 * itself at the end of the pattern.
3270 *
3271 * This method is used in two distinct ways. First, it is used to expand
3272 * the stored affix patterns into actual affixes. For this usage, doFormat
3273 * must be false. Second, it is used to expand the stored affix patterns
3274 * given a specific number (doFormat == true), for those rare cases in
3275 * which a currency format references a ChoiceFormat (e.g., en_IN display
3276 * name for INR). The number itself is taken from digitList.
3277 *
3278 * When used in the first way, this method has a side effect: It sets
3279 * currencyChoice to a ChoiceFormat object, if the currency's display name
3280 * in this locale is a ChoiceFormat pattern (very rare). It only does this
3281 * if currencyChoice is null to start with.
3282 *
3283 * @param pattern the non-null, fPossibly empty pattern
3284 * @param affix string to receive the expanded equivalent of pattern.
3285 * Previous contents are deleted.
3286 * @param doFormat if false, then the pattern will be expanded, and if a
3287 * currency symbol is encountered that expands to a ChoiceFormat, the
3288 * currencyChoice member variable will be initialized if it is null. If
3289 * doFormat is true, then it is assumed that the currencyChoice has been
3290 * created, and it will be used to format the value in digitList.
3291 * @param pluralCount the plural count. It is only used for currency
3292 * plural format. In which case, it is the plural
3293 * count of the currency amount. For example,
3294 * in en_US, it is the singular "one", or the plural
3295 * "other". For all other cases, it is null, and
3296 * is not being used.
3297 */
3298 void DecimalFormat::expandAffix(const UnicodeString& pattern,
3299 UnicodeString& affix,
3300 double number,
3301 FieldPositionHandler& handler,
3302 UBool doFormat,
3303 const UnicodeString* pluralCount) const {
3304 affix.remove();
3305 for (int i=0; i<pattern.length(); ) {
3306 UChar32 c = pattern.char32At(i);
3307 i += U16_LENGTH(c);
3308 if (c == kQuote) {
3309 c = pattern.char32At(i);
3310 i += U16_LENGTH(c);
3311 int beginIdx = affix.length();
3312 switch (c) {
3313 case kCurrencySign: {
3314 // As of ICU 2.2 we use the currency object, and
3315 // ignore the currency symbols in the DFS, unless
3316 // we have a null currency object. This occurs if
3317 // resurrecting a pre-2.2 object or if the user
3318 // sets a custom DFS.
3319 UBool intl = i<pattern.length() &&
3320 pattern.char32At(i) == kCurrencySign;
3321 UBool plural = FALSE;
3322 if (intl) {
3323 ++i;
3324 plural = i<pattern.length() &&
3325 pattern.char32At(i) == kCurrencySign;
3326 if (plural) {
3327 intl = FALSE;
3328 ++i;
3329 }
3330 }
3331 const UChar* currencyUChars = getCurrency();
3332 if (currencyUChars[0] != 0) {
3333 UErrorCode ec = U_ZERO_ERROR;
3334 if (plural && pluralCount != NULL) {
3335 // plural name is only needed when pluralCount != null,
3336 // which means when formatting currency plural names.
3337 // For other cases, pluralCount == null,
3338 // and plural names are not needed.
3339 int32_t len;
3340 // TODO: num of char in plural count
3341 char pluralCountChar[10];
3342 if (pluralCount->length() >= 10) {
3343 break;
3344 }
3345 pluralCount->extract(0, pluralCount->length(), pluralCountChar);
3346 UBool isChoiceFormat;
3347 const UChar* s = ucurr_getPluralName(currencyUChars,
3348 fSymbols != NULL ? fSymbols->getLocale().getName() :
3349 Locale::getDefault().getName(), &isChoiceFormat,
3350 pluralCountChar, &len, &ec);
3351 affix += UnicodeString(s, len);
3352 handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3353 } else if(intl) {
3354 affix += currencyUChars;
3355 handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3356 } else {
3357 int32_t len;
3358 UBool isChoiceFormat;
3359 // If fSymbols is NULL, use default locale
3360 const UChar* s = ucurr_getName(currencyUChars,
3361 fSymbols != NULL ? fSymbols->getLocale().getName() : Locale::getDefault().getName(),
3362 UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec);
3363 if (isChoiceFormat) {
3364 // Two modes here: If doFormat is false, we set up
3365 // currencyChoice. If doFormat is true, we use the
3366 // previously created currencyChoice to format the
3367 // value in digitList.
3368 if (!doFormat) {
3369 // If the currency is handled by a ChoiceFormat,
3370 // then we're not going to use the expanded
3371 // patterns. Instantiate the ChoiceFormat and
3372 // return.
3373 if (fCurrencyChoice == NULL) {
3374 // TODO Replace double-check with proper thread-safe code
3375 ChoiceFormat* fmt = new ChoiceFormat(s, ec);
3376 if (U_SUCCESS(ec)) {
3377 umtx_lock(NULL);
3378 if (fCurrencyChoice == NULL) {
3379 // Cast away const
3380 ((DecimalFormat*)this)->fCurrencyChoice = fmt;
3381 fmt = NULL;
3382 }
3383 umtx_unlock(NULL);
3384 delete fmt;
3385 }
3386 }
3387 // We could almost return null or "" here, since the
3388 // expanded affixes are almost not used at all
3389 // in this situation. However, one method --
3390 // toPattern() -- still does use the expanded
3391 // affixes, in order to set up a padding
3392 // pattern. We use the CURRENCY_SIGN as a
3393 // placeholder.
3394 affix.append(kCurrencySign);
3395 } else {
3396 if (fCurrencyChoice != NULL) {
3397 FieldPosition pos(0); // ignored
3398 if (number < 0) {
3399 number = -number;
3400 }
3401 fCurrencyChoice->format(number, affix, pos);
3402 } else {
3403 // We only arrive here if the currency choice
3404 // format in the locale data is INVALID.
3405 affix += currencyUChars;
3406 handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3407 }
3408 }
3409 continue;
3410 }
3411 affix += UnicodeString(s, len);
3412 handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3413 }
3414 } else {
3415 if(intl) {
3416 affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
3417 } else {
3418 affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
3419 }
3420 handler.addAttribute(kCurrencyField, beginIdx, affix.length());
3421 }
3422 break;
3423 }
3424 case kPatternPercent:
3425 affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3426 handler.addAttribute(kPercentField, beginIdx, affix.length());
3427 break;
3428 case kPatternPerMill:
3429 affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3430 handler.addAttribute(kPermillField, beginIdx, affix.length());
3431 break;
3432 case kPatternPlus:
3433 affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3434 handler.addAttribute(kSignField, beginIdx, affix.length());
3435 break;
3436 case kPatternMinus:
3437 affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3438 handler.addAttribute(kSignField, beginIdx, affix.length());
3439 break;
3440 default:
3441 affix.append(c);
3442 break;
3443 }
3444 }
3445 else {
3446 affix.append(c);
3447 }
3448 }
3449 }
3450
3451 /**
3452 * Append an affix to the given StringBuffer.
3453 * @param buf buffer to append to
3454 * @param isNegative
3455 * @param isPrefix
3456 */
3457 int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number,
3458 FieldPositionHandler& handler,
3459 UBool isNegative, UBool isPrefix) const {
3460 // plural format precedes choice format
3461 if (fCurrencyChoice != 0 &&
3462 fCurrencySignCount != fgCurrencySignCountInPluralFormat) {
3463 const UnicodeString* affixPat;
3464 if (isPrefix) {
3465 affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern;
3466 } else {
3467 affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern;
3468 }
3469 if (affixPat) {
3470 UnicodeString affixBuf;
3471 expandAffix(*affixPat, affixBuf, number, handler, TRUE, NULL);
3472 buf.append(affixBuf);
3473 return affixBuf.length();
3474 }
3475 // else someone called a function that reset the pattern.
3476 }
3477
3478 const UnicodeString* affix;
3479 if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) {
3480 UnicodeString pluralCount = fCurrencyPluralInfo->getPluralRules()->select(number);
3481 AffixesForCurrency* oneSet;
3482 if (fStyle == NumberFormat::kPluralCurrencyStyle) {
3483 oneSet = (AffixesForCurrency*)fPluralAffixesForCurrency->get(pluralCount);
3484 } else {
3485 oneSet = (AffixesForCurrency*)fAffixesForCurrency->get(pluralCount);
3486 }
3487 if (isPrefix) {
3488 affix = isNegative ? &oneSet->negPrefixForCurrency :
3489 &oneSet->posPrefixForCurrency;
3490 } else {
3491 affix = isNegative ? &oneSet->negSuffixForCurrency :
3492 &oneSet->posSuffixForCurrency;
3493 }
3494 } else {
3495 if (isPrefix) {
3496 affix = isNegative ? &fNegativePrefix : &fPositivePrefix;
3497 } else {
3498 affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix;
3499 }
3500 }
3501
3502 int32_t begin = (int) buf.length();
3503
3504 buf.append(*affix);
3505
3506 if (handler.isRecording()) {
3507 int32_t offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
3508 if (offset > -1) {
3509 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
3510 handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length());
3511 }
3512
3513 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
3514 if (offset > -1) {
3515 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
3516 handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length());
3517 }
3518
3519 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
3520 if (offset > -1) {
3521 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3522 handler.addAttribute(kSignField, begin + offset, begin + offset + aff.length());
3523 }
3524
3525 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
3526 if (offset > -1) {
3527 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3528 handler.addAttribute(kPercentField, begin + offset, begin + offset + aff.length());
3529 }
3530
3531 offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
3532 if (offset > -1) {
3533 UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3534 handler.addAttribute(kPermillField, begin + offset, begin + offset + aff.length());
3535 }
3536 }
3537 return affix->length();
3538 }
3539
3540 /**
3541 * Appends an affix pattern to the given StringBuffer, quoting special
3542 * characters as needed. Uses the internal affix pattern, if that exists,
3543 * or the literal affix, if the internal affix pattern is null. The
3544 * appended string will generate the same affix pattern (or literal affix)
3545 * when passed to toPattern().
3546 *
3547 * @param appendTo the affix string is appended to this
3548 * @param affixPattern a pattern such as fPosPrefixPattern; may be null
3549 * @param expAffix a corresponding expanded affix, such as fPositivePrefix.
3550 * Ignored unless affixPattern is null. If affixPattern is null, then
3551 * expAffix is appended as a literal affix.
3552 * @param localized true if the appended pattern should contain localized
3553 * pattern characters; otherwise, non-localized pattern chars are appended
3554 */
3555 void DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
3556 const UnicodeString* affixPattern,
3557 const UnicodeString& expAffix,
3558 UBool localized) const {
3559 if (affixPattern == 0) {
3560 appendAffixPattern(appendTo, expAffix, localized);
3561 } else {
3562 int i;
3563 for (int pos=0; pos<affixPattern->length(); pos=i) {
3564 i = affixPattern->indexOf(kQuote, pos);
3565 if (i < 0) {
3566 UnicodeString s;
3567 affixPattern->extractBetween(pos, affixPattern->length(), s);
3568 appendAffixPattern(appendTo, s, localized);
3569 break;
3570 }
3571 if (i > pos) {
3572 UnicodeString s;
3573 affixPattern->extractBetween(pos, i, s);
3574 appendAffixPattern(appendTo, s, localized);
3575 }
3576 UChar32 c = affixPattern->char32At(++i);
3577 ++i;
3578 if (c == kQuote) {
3579 appendTo.append(c).append(c);
3580 // Fall through and append another kQuote below
3581 } else if (c == kCurrencySign &&
3582 i<affixPattern->length() &&
3583 affixPattern->char32At(i) == kCurrencySign) {
3584 ++i;
3585 appendTo.append(c).append(c);
3586 } else if (localized) {
3587 switch (c) {
3588 case kPatternPercent:
3589 appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
3590 break;
3591 case kPatternPerMill:
3592 appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
3593 break;
3594 case kPatternPlus:
3595 appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3596 break;
3597 case kPatternMinus:
3598 appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
3599 break;
3600 default:
3601 appendTo.append(c);
3602 }
3603 } else {
3604 appendTo.append(c);
3605 }
3606 }
3607 }
3608 }
3609
3610 /**
3611 * Append an affix to the given StringBuffer, using quotes if
3612 * there are special characters. Single quotes themselves must be
3613 * escaped in either case.
3614 */
3615 void
3616 DecimalFormat::appendAffixPattern(UnicodeString& appendTo,
3617 const UnicodeString& affix,
3618 UBool localized) const {
3619 UBool needQuote;
3620 if(localized) {
3621 needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0
3622 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0
3623 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0
3624 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0
3625 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0
3626 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0
3627 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0
3628 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0
3629 || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0
3630 || affix.indexOf(kCurrencySign) >= 0;
3631 }
3632 else {
3633 needQuote = affix.indexOf(kPatternZeroDigit) >= 0
3634 || affix.indexOf(kPatternGroupingSeparator) >= 0
3635 || affix.indexOf(kPatternDecimalSeparator) >= 0
3636 || affix.indexOf(kPatternPercent) >= 0
3637 || affix.indexOf(kPatternPerMill) >= 0
3638 || affix.indexOf(kPatternDigit) >= 0
3639 || affix.indexOf(kPatternSeparator) >= 0
3640 || affix.indexOf(kPatternExponent) >= 0
3641 || affix.indexOf(kPatternPlus) >= 0
3642 || affix.indexOf(kPatternMinus) >= 0
3643 || affix.indexOf(kCurrencySign) >= 0;
3644 }
3645 if (needQuote)
3646 appendTo += (UChar)0x0027 /*'\''*/;
3647 if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0)
3648 appendTo += affix;
3649 else {
3650 for (int32_t j = 0; j < affix.length(); ) {
3651 UChar32 c = affix.char32At(j);
3652 j += U16_LENGTH(c);
3653 appendTo += c;
3654 if (c == 0x0027 /*'\''*/)
3655 appendTo += c;
3656 }
3657 }
3658 if (needQuote)
3659 appendTo += (UChar)0x0027 /*'\''*/;
3660 }
3661
3662 //------------------------------------------------------------------------------
3663
3664 UnicodeString&
3665 DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
3666 {
3667 if (fStyle == NumberFormat::kPluralCurrencyStyle) {
3668 // the prefix or suffix pattern might not be defined yet,
3669 // so they can not be synthesized,
3670 // instead, get them directly.
3671 // but it might not be the actual pattern used in formatting.
3672 // the actual pattern used in formatting depends on the
3673 // formatted number's plural count.
3674 result = fFormatPattern;
3675 return result;
3676 }
3677 result.remove();
3678 UChar32 zero, sigDigit = kPatternSignificantDigit;
3679 UnicodeString digit, group;
3680 int32_t i;
3681 int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
3682 UnicodeString roundingDigits;
3683 int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1;
3684 UnicodeString padSpec;
3685 UBool useSigDig = areSignificantDigitsUsed();
3686
3687 if (localized) {
3688 digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
3689 group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
3690 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
3691 if (useSigDig) {
3692 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
3693 }
3694 }
3695 else {
3696 digit.append((UChar)kPatternDigit);
3697 group.append((UChar)kPatternGroupingSeparator);
3698 zero = (UChar32)kPatternZeroDigit;
3699 }
3700 if (fFormatWidth > 0) {
3701 if (localized) {
3702 padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
3703 }
3704 else {
3705 padSpec.append((UChar)kPatternPadEscape);
3706 }
3707 padSpec.append(fPad);
3708 }
3709 if (fRoundingIncrement != NULL) {
3710 for(i=0; i<fRoundingIncrement->getCount(); ++i) {
3711 roundingDigits.append(zero+(fRoundingIncrement->getDigitValue(i))); // Convert to Unicode digit
3712 }
3713 roundingDecimalPos = fRoundingIncrement->getDecimalAt();
3714 }
3715 for (int32_t part=0; part<2; ++part) {
3716 if (padPos == kPadBeforePrefix) {
3717 result.append(padSpec);
3718 }
3719 appendAffixPattern(result,
3720 (part==0 ? fPosPrefixPattern : fNegPrefixPattern),
3721 (part==0 ? fPositivePrefix : fNegativePrefix),
3722 localized);
3723 if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) {
3724 result.append(padSpec);
3725 }
3726 int32_t sub0Start = result.length();
3727 int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0;
3728 if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) {
3729 g += fGroupingSize2;
3730 }
3731 int32_t maxDig = 0, minDig = 0, maxSigDig = 0;
3732 if (useSigDig) {
3733 minDig = getMinimumSignificantDigits();
3734 maxDig = maxSigDig = getMaximumSignificantDigits();
3735 } else {
3736 minDig = getMinimumIntegerDigits();
3737 maxDig = getMaximumIntegerDigits();
3738 }
3739 if (fUseExponentialNotation) {
3740 if (maxDig > kMaxScientificIntegerDigits) {
3741 maxDig = 1;
3742 }
3743 } else if (useSigDig) {
3744 maxDig = _max(maxDig, g+1);
3745 } else {
3746 maxDig = _max(_max(g, getMinimumIntegerDigits()),
3747 roundingDecimalPos) + 1;
3748 }
3749 for (i = maxDig; i > 0; --i) {
3750 if (!fUseExponentialNotation && i<maxDig &&
3751 isGroupingPosition(i)) {
3752 result.append(group);
3753 }
3754 if (useSigDig) {
3755 // #@,@### (maxSigDig == 5, minSigDig == 2)
3756 // 65 4321 (1-based pos, count from the right)
3757 // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
3758 // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
3759 if (maxSigDig >= i && i > (maxSigDig - minDig)) {
3760 result.append(sigDigit);
3761 } else {
3762 result.append(digit);
3763 }
3764 } else {
3765 if (! roundingDigits.isEmpty()) {
3766 int32_t pos = roundingDecimalPos - i;
3767 if (pos >= 0 && pos < roundingDigits.length()) {
3768 result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
3769 continue;
3770 }
3771 }
3772 if (i<=minDig) {
3773 result.append(zero);
3774 } else {
3775 result.append(digit);
3776 }
3777 }
3778 }
3779 if (!useSigDig) {
3780 if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
3781 if (localized) {
3782 result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
3783 }
3784 else {
3785 result.append((UChar)kPatternDecimalSeparator);
3786 }
3787 }
3788 int32_t pos = roundingDecimalPos;
3789 for (i = 0; i < getMaximumFractionDigits(); ++i) {
3790 if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) {
3791 if (pos < 0) {
3792 result.append(zero);
3793 }
3794 else {
3795 result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero));
3796 }
3797 ++pos;
3798 continue;
3799 }
3800 if (i<getMinimumFractionDigits()) {
3801 result.append(zero);
3802 }
3803 else {
3804 result.append(digit);
3805 }
3806 }
3807 }
3808 if (fUseExponentialNotation) {
3809 if (localized) {
3810 result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
3811 }
3812 else {
3813 result.append((UChar)kPatternExponent);
3814 }
3815 if (fExponentSignAlwaysShown) {
3816 if (localized) {
3817 result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
3818 }
3819 else {
3820 result.append((UChar)kPatternPlus);
3821 }
3822 }
3823 for (i=0; i<fMinExponentDigits; ++i) {
3824 result.append(zero);
3825 }
3826 }
3827 if (! padSpec.isEmpty() && !fUseExponentialNotation) {
3828 int32_t add = fFormatWidth - result.length() + sub0Start
3829 - ((part == 0)
3830 ? fPositivePrefix.length() + fPositiveSuffix.length()
3831 : fNegativePrefix.length() + fNegativeSuffix.length());
3832 while (add > 0) {
3833 result.insert(sub0Start, digit);
3834 ++maxDig;
3835 --add;
3836 // Only add a grouping separator if we have at least
3837 // 2 additional characters to be added, so we don't
3838 // end up with ",###".
3839 if (add>1 && isGroupingPosition(maxDig)) {
3840 result.insert(sub0Start, group);
3841 --add;
3842 }
3843 }
3844 }
3845 if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) {
3846 result.append(padSpec);
3847 }
3848 if (part == 0) {
3849 appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized);
3850 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
3851 result.append(padSpec);
3852 }
3853 UBool isDefault = FALSE;
3854 if ((fNegSuffixPattern == fPosSuffixPattern && // both null
3855 fNegativeSuffix == fPositiveSuffix)
3856 || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 &&
3857 *fNegSuffixPattern == *fPosSuffixPattern))
3858 {
3859 if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL)
3860 {
3861 int32_t length = fPosPrefixPattern->length();
3862 isDefault = fNegPrefixPattern->length() == (length+2) &&
3863 (*fNegPrefixPattern)[(int32_t)0] == kQuote &&
3864 (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus &&
3865 fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0;
3866 }
3867 if (!isDefault &&
3868 fNegPrefixPattern == NULL && fPosPrefixPattern == NULL)
3869 {
3870 int32_t length = fPositivePrefix.length();
3871 isDefault = fNegativePrefix.length() == (length+1) &&
3872 fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
3873 fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
3874 }
3875 }
3876 if (isDefault) {
3877 break; // Don't output default negative subpattern
3878 } else {
3879 if (localized) {
3880 result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
3881 }
3882 else {
3883 result.append((UChar)kPatternSeparator);
3884 }
3885 }
3886 } else {
3887 appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized);
3888 if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) {
3889 result.append(padSpec);
3890 }
3891 }
3892 }
3893
3894 return result;
3895 }
3896
3897 //------------------------------------------------------------------------------
3898
3899 void
3900 DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status)
3901 {
3902 UParseError parseError;
3903 applyPattern(pattern, FALSE, parseError, status);
3904 }
3905
3906 //------------------------------------------------------------------------------
3907
3908 void
3909 DecimalFormat::applyPattern(const UnicodeString& pattern,
3910 UParseError& parseError,
3911 UErrorCode& status)
3912 {
3913 applyPattern(pattern, FALSE, parseError, status);
3914 }
3915 //------------------------------------------------------------------------------
3916
3917 void
3918 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status)
3919 {
3920 UParseError parseError;
3921 applyPattern(pattern, TRUE,parseError,status);
3922 }
3923
3924 //------------------------------------------------------------------------------
3925
3926 void
3927 DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern,
3928 UParseError& parseError,
3929 UErrorCode& status)
3930 {
3931 applyPattern(pattern, TRUE,parseError,status);
3932 }
3933
3934 //------------------------------------------------------------------------------
3935
3936 void
3937 DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern,
3938 UBool localized,
3939 UParseError& parseError,
3940 UErrorCode& status)
3941 {
3942 if (U_FAILURE(status))
3943 {
3944 return;
3945 }
3946 // Clear error struct
3947 parseError.offset = -1;
3948 parseError.preContext[0] = parseError.postContext[0] = (UChar)0;
3949
3950 // Set the significant pattern symbols
3951 UChar32 zeroDigit = kPatternZeroDigit; // '0'
3952 UChar32 sigDigit = kPatternSignificantDigit; // '@'
3953 UnicodeString groupingSeparator ((UChar)kPatternGroupingSeparator);
3954 UnicodeString decimalSeparator ((UChar)kPatternDecimalSeparator);
3955 UnicodeString percent ((UChar)kPatternPercent);
3956 UnicodeString perMill ((UChar)kPatternPerMill);
3957 UnicodeString digit ((UChar)kPatternDigit); // '#'
3958 UnicodeString separator ((UChar)kPatternSeparator);
3959 UnicodeString exponent ((UChar)kPatternExponent);
3960 UnicodeString plus ((UChar)kPatternPlus);
3961 UnicodeString minus ((UChar)kPatternMinus);
3962 UnicodeString padEscape ((UChar)kPatternPadEscape);
3963 // Substitute with the localized symbols if necessary
3964 if (localized) {
3965 zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
3966 sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0);
3967 groupingSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
3968 decimalSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
3969 percent. remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
3970 perMill. remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
3971 digit. remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
3972 separator. remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
3973 exponent. remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol));
3974 plus. remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol));
3975 minus. remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
3976 padEscape. remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
3977 }
3978 UChar nineDigit = (UChar)(zeroDigit + 9);
3979 int32_t digitLen = digit.length();
3980 int32_t groupSepLen = groupingSeparator.length();
3981 int32_t decimalSepLen = decimalSeparator.length();
3982
3983 int32_t pos = 0;
3984 int32_t patLen = pattern.length();
3985 // Part 0 is the positive pattern. Part 1, if present, is the negative
3986 // pattern.
3987 for (int32_t part=0; part<2 && pos<patLen; ++part) {
3988 // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
3989 // 2=suffix, 3=prefix in quote, 4=suffix in quote. Subpart 0 is
3990 // between the prefix and suffix, and consists of pattern
3991 // characters. In the prefix and suffix, percent, perMill, and
3992 // currency symbols are recognized and translated.
3993 int32_t subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
3994
3995 // It's important that we don't change any fields of this object
3996 // prematurely. We set the following variables for the multiplier,
3997 // grouping, etc., and then only change the actual object fields if
3998 // everything parses correctly. This also lets us register
3999 // the data from part 0 and ignore the part 1, except for the
4000 // prefix and suffix.
4001 UnicodeString prefix;
4002 UnicodeString suffix;
4003 int32_t decimalPos = -1;
4004 int32_t multiplier = 1;
4005 int32_t digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
4006 int8_t groupingCount = -1;
4007 int8_t groupingCount2 = -1;
4008 int32_t padPos = -1;
4009 UChar32 padChar = 0;
4010 int32_t roundingPos = -1;
4011 DigitList roundingInc;
4012 int8_t expDigits = -1;
4013 UBool expSignAlways = FALSE;
4014
4015 // The affix is either the prefix or the suffix.
4016 UnicodeString* affix = &prefix;
4017
4018 int32_t start = pos;
4019 UBool isPartDone = FALSE;
4020 UChar32 ch;
4021
4022 for (; !isPartDone && pos < patLen; ) {
4023 // Todo: account for surrogate pairs
4024 ch = pattern.char32At(pos);
4025 switch (subpart) {
4026 case 0: // Pattern proper subpart (between prefix & suffix)
4027 // Process the digits, decimal, and grouping characters. We
4028 // record five pieces of information. We expect the digits
4029 // to occur in the pattern ####00.00####, and we record the
4030 // number of left digits, zero (central) digits, and right
4031 // digits. The position of the last grouping character is
4032 // recorded (should be somewhere within the first two blocks
4033 // of characters), as is the position of the decimal point,
4034 // if any (should be in the zero digits). If there is no
4035 // decimal point, then there should be no right digits.
4036 if (pattern.compare(pos, digitLen, digit) == 0) {
4037 if (zeroDigitCount > 0 || sigDigitCount > 0) {
4038 ++digitRightCount;
4039 } else {
4040 ++digitLeftCount;
4041 }
4042 if (groupingCount >= 0 && decimalPos < 0) {
4043 ++groupingCount;
4044 }
4045 pos += digitLen;
4046 } else if ((ch >= zeroDigit && ch <= nineDigit) ||
4047 ch == sigDigit) {
4048 if (digitRightCount > 0) {
4049 // Unexpected '0'
4050 debug("Unexpected '0'")
4051 status = U_UNEXPECTED_TOKEN;
4052 syntaxError(pattern,pos,parseError);
4053 return;
4054 }
4055 if (ch == sigDigit) {
4056 ++sigDigitCount;
4057 } else {
4058 ++zeroDigitCount;
4059 if (ch != zeroDigit && roundingPos < 0) {
4060 roundingPos = digitLeftCount + zeroDigitCount;
4061 }
4062 if (roundingPos >= 0) {
4063 roundingInc.append((char)(ch - zeroDigit + '0'));
4064 }
4065 }
4066 if (groupingCount >= 0 && decimalPos < 0) {
4067 ++groupingCount;
4068 }
4069 pos += U16_LENGTH(ch);
4070 } else if (pattern.compare(pos, groupSepLen, groupingSeparator) == 0) {
4071 if (decimalPos >= 0) {
4072 // Grouping separator after decimal
4073 debug("Grouping separator after decimal")
4074 status = U_UNEXPECTED_TOKEN;
4075 syntaxError(pattern,pos,parseError);
4076 return;
4077 }
4078 groupingCount2 = groupingCount;
4079 groupingCount = 0;
4080 pos += groupSepLen;
4081 } else if (pattern.compare(pos, decimalSepLen, decimalSeparator) == 0) {
4082 if (decimalPos >= 0) {
4083 // Multiple decimal separators
4084 debug("Multiple decimal separators")
4085 status = U_MULTIPLE_DECIMAL_SEPARATORS;
4086 syntaxError(pattern,pos,parseError);
4087 return;
4088 }
4089 // Intentionally incorporate the digitRightCount,
4090 // even though it is illegal for this to be > 0
4091 // at this point. We check pattern syntax below.
4092 decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
4093 pos += decimalSepLen;
4094 } else {
4095 if (pattern.compare(pos, exponent.length(), exponent) == 0) {
4096 if (expDigits >= 0) {
4097 // Multiple exponential symbols
4098 debug("Multiple exponential symbols")
4099 status = U_MULTIPLE_EXPONENTIAL_SYMBOLS;
4100 syntaxError(pattern,pos,parseError);
4101 return;
4102 }
4103 if (groupingCount >= 0) {
4104 // Grouping separator in exponential pattern
4105 debug("Grouping separator in exponential pattern")
4106 status = U_MALFORMED_EXPONENTIAL_PATTERN;
4107 syntaxError(pattern,pos,parseError);
4108 return;
4109 }
4110 pos += exponent.length();
4111 // Check for positive prefix
4112 if (pos < patLen
4113 && pattern.compare(pos, plus.length(), plus) == 0) {
4114 expSignAlways = TRUE;
4115 pos += plus.length();
4116 }
4117 // Use lookahead to parse out the exponential part of the
4118 // pattern, then jump into suffix subpart.
4119 expDigits = 0;
4120 while (pos < patLen &&
4121 pattern.char32At(pos) == zeroDigit) {
4122 ++expDigits;
4123 pos += U16_LENGTH(zeroDigit);
4124 }
4125
4126 // 1. Require at least one mantissa pattern digit
4127 // 2. Disallow "#+ @" in mantissa
4128 // 3. Require at least one exponent pattern digit
4129 if (((digitLeftCount + zeroDigitCount) < 1 &&
4130 (sigDigitCount + digitRightCount) < 1) ||
4131 (sigDigitCount > 0 && digitLeftCount > 0) ||
4132 expDigits < 1) {
4133 // Malformed exponential pattern
4134 debug("Malformed exponential pattern")
4135 status = U_MALFORMED_EXPONENTIAL_PATTERN;
4136 syntaxError(pattern,pos,parseError);
4137 return;
4138 }
4139 }
4140 // Transition to suffix subpart
4141 subpart = 2; // suffix subpart
4142 affix = &suffix;
4143 sub0Limit = pos;
4144 continue;
4145 }
4146 break;
4147 case 1: // Prefix subpart
4148 case 2: // Suffix subpart
4149 // Process the prefix / suffix characters
4150 // Process unquoted characters seen in prefix or suffix
4151 // subpart.
4152
4153 // Several syntax characters implicitly begins the
4154 // next subpart if we are in the prefix; otherwise
4155 // they are illegal if unquoted.
4156 if (!pattern.compare(pos, digitLen, digit) ||
4157 !pattern.compare(pos, groupSepLen, groupingSeparator) ||
4158 !pattern.compare(pos, decimalSepLen, decimalSeparator) ||
4159 (ch >= zeroDigit && ch <= nineDigit) ||
4160 ch == sigDigit) {
4161 if (subpart == 1) { // prefix subpart
4162 subpart = 0; // pattern proper subpart
4163 sub0Start = pos; // Reprocess this character
4164 continue;
4165 } else {
4166 status = U_UNQUOTED_SPECIAL;
4167 syntaxError(pattern,pos,parseError);
4168 return;
4169 }
4170 } else if (ch == kCurrencySign) {
4171 affix->append(kQuote); // Encode currency
4172 // Use lookahead to determine if the currency sign is
4173 // doubled or not.
4174 U_ASSERT(U16_LENGTH(kCurrencySign) == 1);
4175 if ((pos+1) < pattern.length() && pattern[pos+1] == kCurrencySign) {
4176 affix->append(kCurrencySign);
4177 ++pos; // Skip over the doubled character
4178 if ((pos+1) < pattern.length() &&
4179 pattern[pos+1] == kCurrencySign) {
4180 affix->append(kCurrencySign);
4181 ++pos; // Skip over the doubled character
4182 fCurrencySignCount = fgCurrencySignCountInPluralFormat;
4183 } else {
4184 fCurrencySignCount = fgCurrencySignCountInISOFormat;
4185 }
4186 } else {
4187 fCurrencySignCount = fgCurrencySignCountInSymbolFormat;
4188 }
4189 // Fall through to append(ch)
4190 } else if (ch == kQuote) {
4191 // A quote outside quotes indicates either the opening
4192 // quote or two quotes, which is a quote literal. That is,
4193 // we have the first quote in 'do' or o''clock.
4194 U_ASSERT(U16_LENGTH(kQuote) == 1);
4195 ++pos;
4196 if (pos < pattern.length() && pattern[pos] == kQuote) {
4197 affix->append(kQuote); // Encode quote
4198 // Fall through to append(ch)
4199 } else {
4200 subpart += 2; // open quote
4201 continue;
4202 }
4203 } else if (pattern.compare(pos, separator.length(), separator) == 0) {
4204 // Don't allow separators in the prefix, and don't allow
4205 // separators in the second pattern (part == 1).
4206 if (subpart == 1 || part == 1) {
4207 // Unexpected separator
4208 debug("Unexpected separator")
4209 status = U_UNEXPECTED_TOKEN;
4210 syntaxError(pattern,pos,parseError);
4211 return;
4212 }
4213 sub2Limit = pos;
4214 isPartDone = TRUE; // Go to next part
4215 pos += separator.length();
4216 break;
4217 } else if (pattern.compare(pos, percent.length(), percent) == 0) {
4218 // Next handle characters which are appended directly.
4219 if (multiplier != 1) {
4220 // Too many percent/perMill characters
4221 debug("Too many percent characters")
4222 status = U_MULTIPLE_PERCENT_SYMBOLS;
4223 syntaxError(pattern,pos,parseError);
4224 return;
4225 }
4226 affix->append(kQuote); // Encode percent/perMill
4227 affix->append(kPatternPercent); // Use unlocalized pattern char
4228 multiplier = 100;
4229 pos += percent.length();
4230 break;
4231 } else if (pattern.compare(pos, perMill.length(), perMill) == 0) {
4232 // Next handle characters which are appended directly.
4233 if (multiplier != 1) {
4234 // Too many percent/perMill characters
4235 debug("Too many perMill characters")
4236 status = U_MULTIPLE_PERMILL_SYMBOLS;
4237 syntaxError(pattern,pos,parseError);
4238 return;
4239 }
4240 affix->append(kQuote); // Encode percent/perMill
4241 affix->append(kPatternPerMill); // Use unlocalized pattern char
4242 multiplier = 1000;
4243 pos += perMill.length();
4244 break;
4245 } else if (pattern.compare(pos, padEscape.length(), padEscape) == 0) {
4246 if (padPos >= 0 || // Multiple pad specifiers
4247 (pos+1) == pattern.length()) { // Nothing after padEscape
4248 debug("Multiple pad specifiers")
4249 status = U_MULTIPLE_PAD_SPECIFIERS;
4250 syntaxError(pattern,pos,parseError);
4251 return;
4252 }
4253 padPos = pos;
4254 pos += padEscape.length();
4255 padChar = pattern.char32At(pos);
4256 pos += U16_LENGTH(padChar);
4257 break;
4258 } else if (pattern.compare(pos, minus.length(), minus) == 0) {
4259 affix->append(kQuote); // Encode minus
4260 affix->append(kPatternMinus);
4261 pos += minus.length();
4262 break;
4263 } else if (pattern.compare(pos, plus.length(), plus) == 0) {
4264 affix->append(kQuote); // Encode plus
4265 affix->append(kPatternPlus);
4266 pos += plus.length();
4267 break;
4268 }
4269 // Unquoted, non-special characters fall through to here, as
4270 // well as other code which needs to append something to the
4271 // affix.
4272 affix->append(ch);
4273 pos += U16_LENGTH(ch);
4274 break;
4275 case 3: // Prefix subpart, in quote
4276 case 4: // Suffix subpart, in quote
4277 // A quote within quotes indicates either the closing
4278 // quote or two quotes, which is a quote literal. That is,
4279 // we have the second quote in 'do' or 'don''t'.
4280 if (ch == kQuote) {
4281 ++pos;
4282 if (pos < pattern.length() && pattern[pos] == kQuote) {
4283 affix->append(kQuote); // Encode quote
4284 // Fall through to append(ch)
4285 } else {
4286 subpart -= 2; // close quote
4287 continue;
4288 }
4289 }
4290 affix->append(ch);
4291 pos += U16_LENGTH(ch);
4292 break;
4293 }
4294 }
4295
4296 if (sub0Limit == 0) {
4297 sub0Limit = pattern.length();
4298 }
4299
4300 if (sub2Limit == 0) {
4301 sub2Limit = pattern.length();
4302 }
4303
4304 /* Handle patterns with no '0' pattern character. These patterns
4305 * are legal, but must be recodified to make sense. "##.###" ->
4306 * "#0.###". ".###" -> ".0##".
4307 *
4308 * We allow patterns of the form "####" to produce a zeroDigitCount
4309 * of zero (got that?); although this seems like it might make it
4310 * possible for format() to produce empty strings, format() checks
4311 * for this condition and outputs a zero digit in this situation.
4312 * Having a zeroDigitCount of zero yields a minimum integer digits
4313 * of zero, which allows proper round-trip patterns. We don't want
4314 * "#" to become "#0" when toPattern() is called (even though that's
4315 * what it really is, semantically).
4316 */
4317 if (zeroDigitCount == 0 && sigDigitCount == 0 &&
4318 digitLeftCount > 0 && decimalPos >= 0) {
4319 // Handle "###.###" and "###." and ".###"
4320 int n = decimalPos;
4321 if (n == 0)
4322 ++n; // Handle ".###"
4323 digitRightCount = digitLeftCount - n;
4324 digitLeftCount = n - 1;
4325 zeroDigitCount = 1;
4326 }
4327
4328 // Do syntax checking on the digits, decimal points, and quotes.
4329 if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
4330 (decimalPos >= 0 &&
4331 (sigDigitCount > 0 ||
4332 decimalPos < digitLeftCount ||
4333 decimalPos > (digitLeftCount + zeroDigitCount))) ||
4334 groupingCount == 0 || groupingCount2 == 0 ||
4335 (sigDigitCount > 0 && zeroDigitCount > 0) ||
4336 subpart > 2)
4337 { // subpart > 2 == unmatched quote
4338 debug("Syntax error")
4339 status = U_PATTERN_SYNTAX_ERROR;
4340 syntaxError(pattern,pos,parseError);
4341 return;
4342 }
4343
4344 // Make sure pad is at legal position before or after affix.
4345 if (padPos >= 0) {
4346 if (padPos == start) {
4347 padPos = kPadBeforePrefix;
4348 } else if (padPos+2 == sub0Start) {
4349 padPos = kPadAfterPrefix;
4350 } else if (padPos == sub0Limit) {
4351 padPos = kPadBeforeSuffix;
4352 } else if (padPos+2 == sub2Limit) {
4353 padPos = kPadAfterSuffix;
4354 } else {
4355 // Illegal pad position
4356 debug("Illegal pad position")
4357 status = U_ILLEGAL_PAD_POSITION;
4358 syntaxError(pattern,pos,parseError);
4359 return;
4360 }
4361 }
4362
4363 if (part == 0) {
4364 delete fPosPrefixPattern;
4365 delete fPosSuffixPattern;
4366 delete fNegPrefixPattern;
4367 delete fNegSuffixPattern;
4368 fPosPrefixPattern = new UnicodeString(prefix);
4369 /* test for NULL */
4370 if (fPosPrefixPattern == 0) {
4371 status = U_MEMORY_ALLOCATION_ERROR;
4372 return;
4373 }
4374 fPosSuffixPattern = new UnicodeString(suffix);
4375 /* test for NULL */
4376 if (fPosSuffixPattern == 0) {
4377 status = U_MEMORY_ALLOCATION_ERROR;
4378 delete fPosPrefixPattern;
4379 return;
4380 }
4381 fNegPrefixPattern = 0;
4382 fNegSuffixPattern = 0;
4383
4384 fUseExponentialNotation = (expDigits >= 0);
4385 if (fUseExponentialNotation) {
4386 fMinExponentDigits = expDigits;
4387 }
4388 fExponentSignAlwaysShown = expSignAlways;
4389 int32_t digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
4390 // The effectiveDecimalPos is the position the decimal is at or
4391 // would be at if there is no decimal. Note that if
4392 // decimalPos<0, then digitTotalCount == digitLeftCount +
4393 // zeroDigitCount.
4394 int32_t effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
4395 UBool isSigDig = (sigDigitCount > 0);
4396 setSignificantDigitsUsed(isSigDig);
4397 if (isSigDig) {
4398 setMinimumSignificantDigits(sigDigitCount);
4399 setMaximumSignificantDigits(sigDigitCount + digitRightCount);
4400 } else {
4401 int32_t minInt = effectiveDecimalPos - digitLeftCount;
4402 setMinimumIntegerDigits(minInt);
4403 setMaximumIntegerDigits(fUseExponentialNotation
4404 ? digitLeftCount + getMinimumIntegerDigits()
4405 : kDoubleIntegerDigits);
4406 setMaximumFractionDigits(decimalPos >= 0
4407 ? (digitTotalCount - decimalPos) : 0);
4408 setMinimumFractionDigits(decimalPos >= 0
4409 ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
4410 }
4411 setGroupingUsed(groupingCount > 0);
4412 fGroupingSize = (groupingCount > 0) ? groupingCount : 0;
4413 fGroupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
4414 ? groupingCount2 : 0;
4415 setMultiplier(multiplier);
4416 setDecimalSeparatorAlwaysShown(decimalPos == 0
4417 || decimalPos == digitTotalCount);
4418 if (padPos >= 0) {
4419 fPadPosition = (EPadPosition) padPos;
4420 // To compute the format width, first set up sub0Limit -
4421 // sub0Start. Add in prefix/suffix length later.
4422
4423 // fFormatWidth = prefix.length() + suffix.length() +
4424 // sub0Limit - sub0Start;
4425 fFormatWidth = sub0Limit - sub0Start;
4426 fPad = padChar;
4427 } else {
4428 fFormatWidth = 0;
4429 }
4430 if (roundingPos >= 0) {
4431 roundingInc.setDecimalAt(effectiveDecimalPos - roundingPos);
4432 if (fRoundingIncrement != NULL) {
4433 *fRoundingIncrement = roundingInc;
4434 } else {
4435 fRoundingIncrement = new DigitList(roundingInc);
4436 /* test for NULL */
4437 if (fRoundingIncrement == NULL) {
4438 status = U_MEMORY_ALLOCATION_ERROR;
4439 delete fPosPrefixPattern;
4440 delete fPosSuffixPattern;
4441 return;
4442 }
4443 }
4444 fRoundingIncrement->getDouble(); // forces caching of double in the DigitList,
4445 // makes getting it thread safe.
4446 fRoundingMode = kRoundHalfEven;
4447 } else {
4448 setRoundingIncrement(0.0);
4449 }
4450 } else {
4451 fNegPrefixPattern = new UnicodeString(prefix);
4452 /* test for NULL */
4453 if (fNegPrefixPattern == 0) {
4454 status = U_MEMORY_ALLOCATION_ERROR;
4455 return;
4456 }
4457 fNegSuffixPattern = new UnicodeString(suffix);
4458 /* test for NULL */
4459 if (fNegSuffixPattern == 0) {
4460 delete fNegPrefixPattern;
4461 status = U_MEMORY_ALLOCATION_ERROR;
4462 return;
4463 }
4464 }
4465 }
4466
4467 if (pattern.length() == 0) {
4468 delete fNegPrefixPattern;
4469 delete fNegSuffixPattern;
4470 fNegPrefixPattern = NULL;
4471 fNegSuffixPattern = NULL;
4472 if (fPosPrefixPattern != NULL) {
4473 fPosPrefixPattern->remove();
4474 } else {
4475 fPosPrefixPattern = new UnicodeString();
4476 /* test for NULL */
4477 if (fPosPrefixPattern == 0) {
4478 status = U_MEMORY_ALLOCATION_ERROR;
4479 return;
4480 }
4481 }
4482 if (fPosSuffixPattern != NULL) {
4483 fPosSuffixPattern->remove();
4484 } else {
4485 fPosSuffixPattern = new UnicodeString();
4486 /* test for NULL */
4487 if (fPosSuffixPattern == 0) {
4488 delete fPosPrefixPattern;
4489 status = U_MEMORY_ALLOCATION_ERROR;
4490 return;
4491 }
4492 }
4493
4494 setMinimumIntegerDigits(0);
4495 setMaximumIntegerDigits(kDoubleIntegerDigits);
4496 setMinimumFractionDigits(0);
4497 setMaximumFractionDigits(kDoubleFractionDigits);
4498
4499 fUseExponentialNotation = FALSE;
4500 fCurrencySignCount = 0;
4501 setGroupingUsed(FALSE);
4502 fGroupingSize = 0;
4503 fGroupingSize2 = 0;
4504 setMultiplier(1);
4505 setDecimalSeparatorAlwaysShown(FALSE);
4506 fFormatWidth = 0;
4507 setRoundingIncrement(0.0);
4508 }
4509
4510 // If there was no negative pattern, or if the negative pattern is
4511 // identical to the positive pattern, then prepend the minus sign to the
4512 // positive pattern to form the negative pattern.
4513 if (fNegPrefixPattern == NULL ||
4514 (*fNegPrefixPattern == *fPosPrefixPattern
4515 && *fNegSuffixPattern == *fPosSuffixPattern)) {
4516 _copy_us_ptr(&fNegSuffixPattern, fPosSuffixPattern);
4517 if (fNegPrefixPattern == NULL) {
4518 fNegPrefixPattern = new UnicodeString();
4519 /* test for NULL */
4520 if (fNegPrefixPattern == 0) {
4521 status = U_MEMORY_ALLOCATION_ERROR;
4522 return;
4523 }
4524 } else {
4525 fNegPrefixPattern->remove();
4526 }
4527 fNegPrefixPattern->append(kQuote).append(kPatternMinus)
4528 .append(*fPosPrefixPattern);
4529 }
4530 #ifdef FMT_DEBUG
4531 UnicodeString s;
4532 s.append("\"").append(pattern).append("\"->");
4533 debugout(s);
4534 #endif
4535
4536 // save the pattern
4537 fFormatPattern = pattern;
4538 }
4539
4540
4541 void
4542 DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) {
4543 expandAffixes(pluralCount);
4544 if (fFormatWidth > 0) {
4545 // Finish computing format width (see above)
4546 // TODO: how to handle fFormatWidth,
4547 // need to save in f(Plural)AffixesForCurrecy?
4548 fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length();
4549 }
4550 }
4551
4552
4553 void
4554 DecimalFormat::applyPattern(const UnicodeString& pattern,
4555 UBool localized,
4556 UParseError& parseError,
4557 UErrorCode& status)
4558 {
4559 // do the following re-set first. since they change private data by
4560 // apply pattern again.
4561 if (pattern.indexOf(kCurrencySign) != -1) {
4562 if (fCurrencyPluralInfo == NULL) {
4563 // initialize currencyPluralInfo if needed
4564 fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status);
4565 }
4566 if (fAffixPatternsForCurrency == NULL) {
4567 setupCurrencyAffixPatterns(status);
4568 }
4569 if (pattern.indexOf(fgTripleCurrencySign) != -1) {
4570 // only setup the affixes of the current pattern.
4571 setupCurrencyAffixes(pattern, TRUE, FALSE, status);
4572 }
4573 }
4574 applyPatternWithoutExpandAffix(pattern, localized, parseError, status);
4575 expandAffixAdjustWidth(NULL);
4576 }
4577
4578
4579 void
4580 DecimalFormat::applyPatternInternally(const UnicodeString& pluralCount,
4581 const UnicodeString& pattern,
4582 UBool localized,
4583 UParseError& parseError,
4584 UErrorCode& status) {
4585 applyPatternWithoutExpandAffix(pattern, localized, parseError, status);
4586 expandAffixAdjustWidth(&pluralCount);
4587 }
4588
4589
4590 /**
4591 * Sets the maximum number of digits allowed in the integer portion of a
4592 * number. This override limits the integer digit count to 309.
4593 * @see NumberFormat#setMaximumIntegerDigits
4594 */
4595 void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) {
4596 NumberFormat::setMaximumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
4597 }
4598
4599 /**
4600 * Sets the minimum number of digits allowed in the integer portion of a
4601 * number. This override limits the integer digit count to 309.
4602 * @see NumberFormat#setMinimumIntegerDigits
4603 */
4604 void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) {
4605 NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits));
4606 }
4607
4608 /**
4609 * Sets the maximum number of digits allowed in the fraction portion of a
4610 * number. This override limits the fraction digit count to 340.
4611 * @see NumberFormat#setMaximumFractionDigits
4612 */
4613 void DecimalFormat::setMaximumFractionDigits(int32_t newValue) {
4614 NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits));
4615 }
4616
4617 /**
4618 * Sets the minimum number of digits allowed in the fraction portion of a
4619 * number. This override limits the fraction digit count to 340.
4620 * @see NumberFormat#setMinimumFractionDigits
4621 */
4622 void DecimalFormat::setMinimumFractionDigits(int32_t newValue) {
4623 NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits));
4624 }
4625
4626 int32_t DecimalFormat::getMinimumSignificantDigits() const {
4627 return fMinSignificantDigits;
4628 }
4629
4630 int32_t DecimalFormat::getMaximumSignificantDigits() const {
4631 return fMaxSignificantDigits;
4632 }
4633
4634 void DecimalFormat::setMinimumSignificantDigits(int32_t min) {
4635 if (min < 1) {
4636 min = 1;
4637 }
4638 // pin max sig dig to >= min
4639 int32_t max = _max(fMaxSignificantDigits, min);
4640 fMinSignificantDigits = min;
4641 fMaxSignificantDigits = max;
4642 }
4643
4644 void DecimalFormat::setMaximumSignificantDigits(int32_t max) {
4645 if (max < 1) {
4646 max = 1;
4647 }
4648 // pin min sig dig to 1..max
4649 U_ASSERT(fMinSignificantDigits >= 1);
4650 int32_t min = _min(fMinSignificantDigits, max);
4651 fMinSignificantDigits = min;
4652 fMaxSignificantDigits = max;
4653 }
4654
4655 UBool DecimalFormat::areSignificantDigitsUsed() const {
4656 return fUseSignificantDigits;
4657 }
4658
4659 void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) {
4660 fUseSignificantDigits = useSignificantDigits;
4661 }
4662
4663 void DecimalFormat::setCurrencyInternally(const UChar* theCurrency,
4664 UErrorCode& ec) {
4665 // If we are a currency format, then modify our affixes to
4666 // encode the currency symbol for the given currency in our
4667 // locale, and adjust the decimal digits and rounding for the
4668 // given currency.
4669
4670 // Note: The code is ordered so that this object is *not changed*
4671 // until we are sure we are going to succeed.
4672
4673 // NULL or empty currency is *legal* and indicates no currency.
4674 UBool isCurr = (theCurrency && *theCurrency);
4675
4676 double rounding = 0.0;
4677 int32_t frac = 0;
4678 if (fCurrencySignCount > fgCurrencySignCountZero && isCurr) {
4679 rounding = ucurr_getRoundingIncrement(theCurrency, &ec);
4680 frac = ucurr_getDefaultFractionDigits(theCurrency, &ec);
4681 }
4682
4683 NumberFormat::setCurrency(theCurrency, ec);
4684 if (U_FAILURE(ec)) return;
4685
4686 if (fCurrencySignCount > fgCurrencySignCountZero) {
4687 // NULL or empty currency is *legal* and indicates no currency.
4688 if (isCurr) {
4689 setRoundingIncrement(rounding);
4690 setMinimumFractionDigits(frac);
4691 setMaximumFractionDigits(frac);
4692 }
4693 expandAffixes(NULL);
4694 }
4695 }
4696
4697 void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) {
4698 // set the currency before compute affixes to get the right currency names
4699 NumberFormat::setCurrency(theCurrency, ec);
4700 if (fFormatPattern.indexOf(fgTripleCurrencySign) != -1) {
4701 UnicodeString savedPtn = fFormatPattern;
4702 setupCurrencyAffixes(fFormatPattern, TRUE, TRUE, ec);
4703 UParseError parseErr;
4704 applyPattern(savedPtn, FALSE, parseErr, ec);
4705 }
4706 // set the currency after apply pattern to get the correct rounding/fraction
4707 setCurrencyInternally(theCurrency, ec);
4708 }
4709
4710 // Deprecated variant with no UErrorCode parameter
4711 void DecimalFormat::setCurrency(const UChar* theCurrency) {
4712 UErrorCode ec = U_ZERO_ERROR;
4713 setCurrency(theCurrency, ec);
4714 }
4715
4716 void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const {
4717 if (fSymbols == NULL) {
4718 ec = U_MEMORY_ALLOCATION_ERROR;
4719 return;
4720 }
4721 ec = U_ZERO_ERROR;
4722 const UChar* c = getCurrency();
4723 if (*c == 0) {
4724 const UnicodeString &intl =
4725 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
4726 c = intl.getBuffer(); // ok for intl to go out of scope
4727 }
4728 u_strncpy(result, c, 3);
4729 result[3] = 0;
4730 }
4731
4732 /**
4733 * Return the number of fraction digits to display, or the total
4734 * number of digits for significant digit formats and exponential
4735 * formats.
4736 */
4737 int32_t
4738 DecimalFormat::precision() const {
4739 if (areSignificantDigitsUsed()) {
4740 return getMaximumSignificantDigits();
4741 } else if (fUseExponentialNotation) {
4742 return getMinimumIntegerDigits() + getMaximumFractionDigits();
4743 } else {
4744 return getMaximumFractionDigits();
4745 }
4746 }
4747
4748
4749 // TODO: template algorithm
4750 Hashtable*
4751 DecimalFormat::initHashForAffix(UErrorCode& status) {
4752 if ( U_FAILURE(status) ) {
4753 return NULL;
4754 }
4755 Hashtable* hTable;
4756 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
4757 status = U_MEMORY_ALLOCATION_ERROR;
4758 return NULL;
4759 }
4760 if ( U_FAILURE(status) ) {
4761 delete hTable;
4762 return NULL;
4763 }
4764 hTable->setValueComparator(decimfmtAffixValueComparator);
4765 return hTable;
4766 }
4767
4768 Hashtable*
4769 DecimalFormat::initHashForAffixPattern(UErrorCode& status) {
4770 if ( U_FAILURE(status) ) {
4771 return NULL;
4772 }
4773 Hashtable* hTable;
4774 if ( (hTable = new Hashtable(TRUE, status)) == NULL ) {
4775 status = U_MEMORY_ALLOCATION_ERROR;
4776 return NULL;
4777 }
4778 if ( U_FAILURE(status) ) {
4779 delete hTable;
4780 return NULL;
4781 }
4782 hTable->setValueComparator(decimfmtAffixPatternValueComparator);
4783 return hTable;
4784 }
4785
4786 void
4787 DecimalFormat::deleteHashForAffix(Hashtable*& table)
4788 {
4789 if ( table == NULL ) {
4790 return;
4791 }
4792 int32_t pos = -1;
4793 const UHashElement* element = NULL;
4794 while ( (element = table->nextElement(pos)) != NULL ) {
4795 const UHashTok keyTok = element->key;
4796 const UHashTok valueTok = element->value;
4797 const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer;
4798 delete value;
4799 }
4800 delete table;
4801 table = NULL;
4802 }
4803
4804
4805
4806 void
4807 DecimalFormat::deleteHashForAffixPattern()
4808 {
4809 if ( fAffixPatternsForCurrency == NULL ) {
4810 return;
4811 }
4812 int32_t pos = -1;
4813 const UHashElement* element = NULL;
4814 while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) {
4815 const UHashTok keyTok = element->key;
4816 const UHashTok valueTok = element->value;
4817 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
4818 delete value;
4819 }
4820 delete fAffixPatternsForCurrency;
4821 fAffixPatternsForCurrency = NULL;
4822 }
4823
4824
4825 void
4826 DecimalFormat::copyHashForAffixPattern(const Hashtable* source,
4827 Hashtable* target,
4828 UErrorCode& status) {
4829 if ( U_FAILURE(status) ) {
4830 return;
4831 }
4832 int32_t pos = -1;
4833 const UHashElement* element = NULL;
4834 if ( source ) {
4835 while ( (element = source->nextElement(pos)) != NULL ) {
4836 const UHashTok keyTok = element->key;
4837 const UnicodeString* key = (UnicodeString*)keyTok.pointer;
4838 const UHashTok valueTok = element->value;
4839 const AffixPatternsForCurrency* value = (AffixPatternsForCurrency*)valueTok.pointer;
4840 AffixPatternsForCurrency* copy = new AffixPatternsForCurrency(
4841 value->negPrefixPatternForCurrency,
4842 value->negSuffixPatternForCurrency,
4843 value->posPrefixPatternForCurrency,
4844 value->posSuffixPatternForCurrency,
4845 value->patternType);
4846 target->put(UnicodeString(*key), copy, status);
4847 if ( U_FAILURE(status) ) {
4848 return;
4849 }
4850 }
4851 }
4852 }
4853
4854
4855
4856 void
4857 DecimalFormat::copyHashForAffix(const Hashtable* source,
4858 Hashtable* target,
4859 UErrorCode& status) {
4860 if ( U_FAILURE(status) ) {
4861 return;
4862 }
4863 int32_t pos = -1;
4864 const UHashElement* element = NULL;
4865 if ( source ) {
4866 while ( (element = source->nextElement(pos)) != NULL ) {
4867 const UHashTok keyTok = element->key;
4868 const UnicodeString* key = (UnicodeString*)keyTok.pointer;
4869
4870 const UHashTok valueTok = element->value;
4871 const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer;
4872 AffixesForCurrency* copy = new AffixesForCurrency(
4873 value->negPrefixForCurrency,
4874 value->negSuffixForCurrency,
4875 value->posPrefixForCurrency,
4876 value->posSuffixForCurrency);
4877 target->put(UnicodeString(*key), copy, status);
4878 if ( U_FAILURE(status) ) {
4879 return;
4880 }
4881 }
4882 }
4883 }
4884
4885 U_NAMESPACE_END
4886
4887 #endif /* #if !UCONFIG_NO_FORMATTING */
4888
4889 //eof