]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/decimfmtimpl.cpp
ICU-62107.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / decimfmtimpl.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
2ca993e8
A
3/*
4 * Copyright (C) 2015, International Business Machines
5 * Corporation and others. All Rights Reserved.
6 *
7 * file name: decimfmtimpl.cpp
8 */
9
10#include "unicode/utypes.h"
11
12#if !UCONFIG_NO_FORMATTING
13
14#include <math.h>
15#include "unicode/numfmt.h"
16#include "unicode/plurrule.h"
17#include "unicode/ustring.h"
18#include "decimalformatpattern.h"
19#include "decimalformatpatternimpl.h"
20#include "decimfmtimpl.h"
21#include "fphdlimp.h"
22#include "plurrule_impl.h"
23#include "valueformatter.h"
24#include "visibledigits.h"
25
26U_NAMESPACE_BEGIN
27
28static const int32_t kMaxScientificIntegerDigits = 8;
29
30static const int32_t kFormattingPosPrefix = (1 << 0);
31static const int32_t kFormattingNegPrefix = (1 << 1);
32static const int32_t kFormattingPosSuffix = (1 << 2);
33static const int32_t kFormattingNegSuffix = (1 << 3);
34static const int32_t kFormattingSymbols = (1 << 4);
35static const int32_t kFormattingCurrency = (1 << 5);
36static const int32_t kFormattingUsesCurrency = (1 << 6);
37static const int32_t kFormattingPluralRules = (1 << 7);
38static const int32_t kFormattingAffixParser = (1 << 8);
39static const int32_t kFormattingCurrencyAffixInfo = (1 << 9);
40static const int32_t kFormattingAll = (1 << 10) - 1;
41static const int32_t kFormattingAffixes =
42 kFormattingPosPrefix | kFormattingPosSuffix |
43 kFormattingNegPrefix | kFormattingNegSuffix;
44static const int32_t kFormattingAffixParserWithCurrency =
45 kFormattingAffixParser | kFormattingCurrencyAffixInfo;
46
47DecimalFormatImpl::DecimalFormatImpl(
48 NumberFormat *super,
49 const Locale &locale,
50 const UnicodeString &pattern,
51 UErrorCode &status)
52 : fSuper(super),
53 fScale(0),
54 fRoundingMode(DecimalFormat::kRoundHalfEven),
55 fSymbols(NULL),
56 fCurrencyUsage(UCURR_USAGE_STANDARD),
57 fRules(NULL),
58 fMonetary(FALSE) {
59 if (U_FAILURE(status)) {
60 return;
61 }
62 fSymbols = new DecimalFormatSymbols(
63 locale, status);
64 if (fSymbols == NULL) {
65 status = U_MEMORY_ALLOCATION_ERROR;
66 return;
67 }
68 UParseError parseError;
69 applyPattern(pattern, FALSE, parseError, status);
70 updateAll(status);
71}
72
73DecimalFormatImpl::DecimalFormatImpl(
74 NumberFormat *super,
75 const UnicodeString &pattern,
76 DecimalFormatSymbols *symbolsToAdopt,
77 UParseError &parseError,
78 UErrorCode &status)
79 : fSuper(super),
80 fScale(0),
81 fRoundingMode(DecimalFormat::kRoundHalfEven),
82 fSymbols(symbolsToAdopt),
83 fCurrencyUsage(UCURR_USAGE_STANDARD),
84 fRules(NULL),
85 fMonetary(FALSE) {
86 applyPattern(pattern, FALSE, parseError, status);
87 updateAll(status);
88}
89
90DecimalFormatImpl::DecimalFormatImpl(
91 NumberFormat *super, const DecimalFormatImpl &other, UErrorCode &status) :
92 fSuper(super),
93 fMultiplier(other.fMultiplier),
94 fScale(other.fScale),
95 fRoundingMode(other.fRoundingMode),
96 fMinSigDigits(other.fMinSigDigits),
97 fMaxSigDigits(other.fMaxSigDigits),
98 fUseScientific(other.fUseScientific),
99 fUseSigDigits(other.fUseSigDigits),
100 fGrouping(other.fGrouping),
101 fPositivePrefixPattern(other.fPositivePrefixPattern),
102 fNegativePrefixPattern(other.fNegativePrefixPattern),
103 fPositiveSuffixPattern(other.fPositiveSuffixPattern),
104 fNegativeSuffixPattern(other.fNegativeSuffixPattern),
105 fSymbols(other.fSymbols),
106 fCurrencyUsage(other.fCurrencyUsage),
107 fRules(NULL),
108 fMonetary(other.fMonetary),
109 fAffixParser(other.fAffixParser),
110 fCurrencyAffixInfo(other.fCurrencyAffixInfo),
111 fEffPrecision(other.fEffPrecision),
112 fEffGrouping(other.fEffGrouping),
113 fOptions(other.fOptions),
114 fFormatter(other.fFormatter),
0f5d89e8
A
115 fAffixes(other.fAffixes),
116 fFormatFullPrecision(other.fFormatFullPrecision) {
2ca993e8
A
117 fSymbols = new DecimalFormatSymbols(*fSymbols);
118 if (fSymbols == NULL && U_SUCCESS(status)) {
119 status = U_MEMORY_ALLOCATION_ERROR;
120 }
121 if (other.fRules != NULL) {
122 fRules = new PluralRules(*other.fRules);
123 if (fRules == NULL && U_SUCCESS(status)) {
124 status = U_MEMORY_ALLOCATION_ERROR;
125 }
126 }
127}
128
129
130DecimalFormatImpl &
131DecimalFormatImpl::assign(const DecimalFormatImpl &other, UErrorCode &status) {
132 if (U_FAILURE(status) || this == &other) {
133 return (*this);
134 }
135 UObject::operator=(other);
136 fMultiplier = other.fMultiplier;
137 fScale = other.fScale;
138 fRoundingMode = other.fRoundingMode;
139 fMinSigDigits = other.fMinSigDigits;
140 fMaxSigDigits = other.fMaxSigDigits;
141 fUseScientific = other.fUseScientific;
142 fUseSigDigits = other.fUseSigDigits;
143 fGrouping = other.fGrouping;
144 fPositivePrefixPattern = other.fPositivePrefixPattern;
145 fNegativePrefixPattern = other.fNegativePrefixPattern;
146 fPositiveSuffixPattern = other.fPositiveSuffixPattern;
147 fNegativeSuffixPattern = other.fNegativeSuffixPattern;
148 fCurrencyUsage = other.fCurrencyUsage;
149 fMonetary = other.fMonetary;
150 fAffixParser = other.fAffixParser;
151 fCurrencyAffixInfo = other.fCurrencyAffixInfo;
152 fEffPrecision = other.fEffPrecision;
153 fEffGrouping = other.fEffGrouping;
154 fOptions = other.fOptions;
155 fFormatter = other.fFormatter;
156 fAffixes = other.fAffixes;
0f5d89e8 157 fFormatFullPrecision = other.fFormatFullPrecision;
2ca993e8
A
158 *fSymbols = *other.fSymbols;
159 if (fRules != NULL && other.fRules != NULL) {
160 *fRules = *other.fRules;
161 } else {
162 delete fRules;
163 fRules = other.fRules;
164 if (fRules != NULL) {
165 fRules = new PluralRules(*fRules);
166 if (fRules == NULL) {
167 status = U_MEMORY_ALLOCATION_ERROR;
168 return *this;
169 }
170 }
171 }
172 return *this;
173}
174
175UBool
176DecimalFormatImpl::operator==(const DecimalFormatImpl &other) const {
177 if (this == &other) {
178 return TRUE;
179 }
180 return (fMultiplier == other.fMultiplier)
181 && (fScale == other.fScale)
182 && (fRoundingMode == other.fRoundingMode)
183 && (fMinSigDigits == other.fMinSigDigits)
184 && (fMaxSigDigits == other.fMaxSigDigits)
185 && (fUseScientific == other.fUseScientific)
186 && (fUseSigDigits == other.fUseSigDigits)
187 && fGrouping.equals(other.fGrouping)
188 && fPositivePrefixPattern.equals(other.fPositivePrefixPattern)
189 && fNegativePrefixPattern.equals(other.fNegativePrefixPattern)
190 && fPositiveSuffixPattern.equals(other.fPositiveSuffixPattern)
191 && fNegativeSuffixPattern.equals(other.fNegativeSuffixPattern)
192 && fCurrencyUsage == other.fCurrencyUsage
193 && fAffixParser.equals(other.fAffixParser)
194 && fCurrencyAffixInfo.equals(other.fCurrencyAffixInfo)
195 && fEffPrecision.equals(other.fEffPrecision)
196 && fEffGrouping.equals(other.fEffGrouping)
197 && fOptions.equals(other.fOptions)
198 && fFormatter.equals(other.fFormatter)
199 && fAffixes.equals(other.fAffixes)
200 && (*fSymbols == *other.fSymbols)
201 && ((fRules == other.fRules) || (
202 (fRules != NULL) && (other.fRules != NULL)
203 && (*fRules == *other.fRules)))
0f5d89e8
A
204 && (fMonetary == other.fMonetary)
205 && (fFormatFullPrecision == other.fFormatFullPrecision);
2ca993e8
A
206}
207
208DecimalFormatImpl::~DecimalFormatImpl() {
209 delete fSymbols;
210 delete fRules;
211}
212
213ValueFormatter &
214DecimalFormatImpl::prepareValueFormatter(ValueFormatter &vf) const {
215 if (fUseScientific) {
216 vf.prepareScientificFormatting(
217 fFormatter, fEffPrecision, fOptions);
218 return vf;
219 }
220 vf.prepareFixedDecimalFormatting(
221 fFormatter, fEffGrouping, fEffPrecision.fMantissa, fOptions.fMantissa);
222 return vf;
223}
224
225int32_t
226DecimalFormatImpl::getPatternScale() const {
227 UBool usesPercent = fPositivePrefixPattern.usesPercent() ||
228 fPositiveSuffixPattern.usesPercent() ||
229 fNegativePrefixPattern.usesPercent() ||
230 fNegativeSuffixPattern.usesPercent();
231 if (usesPercent) {
232 return 2;
233 }
234 UBool usesPermill = fPositivePrefixPattern.usesPermill() ||
235 fPositiveSuffixPattern.usesPermill() ||
236 fNegativePrefixPattern.usesPermill() ||
237 fNegativeSuffixPattern.usesPermill();
238 if (usesPermill) {
239 return 3;
240 }
241 return 0;
242}
243
244void
245DecimalFormatImpl::setMultiplierScale(int32_t scale) {
246 if (scale == 0) {
247 // Needed to preserve equality. fMultiplier == 0 means
248 // multiplier is 1.
f3c0d7a5 249 fMultiplier.set((int32_t)0);
2ca993e8 250 } else {
f3c0d7a5 251 fMultiplier.set((int32_t)1);
2ca993e8
A
252 fMultiplier.shiftDecimalRight(scale);
253 }
254}
255
256UnicodeString &
257DecimalFormatImpl::format(
258 int32_t number,
259 UnicodeString &appendTo,
260 FieldPosition &pos,
261 UErrorCode &status) const {
262 FieldPositionOnlyHandler handler(pos);
263 return formatInt32(number, appendTo, handler, status);
264}
265
266UnicodeString &
267DecimalFormatImpl::format(
268 int32_t number,
269 UnicodeString &appendTo,
270 FieldPositionIterator *posIter,
271 UErrorCode &status) const {
272 FieldPositionIteratorHandler handler(posIter, status);
273 return formatInt32(number, appendTo, handler, status);
274}
275
276template<class T>
277UBool DecimalFormatImpl::maybeFormatWithDigitList(
278 T number,
279 UnicodeString &appendTo,
280 FieldPositionHandler &handler,
281 UErrorCode &status) const {
282 if (!fMultiplier.isZero()) {
283 DigitList digits;
284 digits.set(number);
285 digits.mult(fMultiplier, status);
286 digits.shiftDecimalRight(fScale);
287 formatAdjustedDigitList(digits, appendTo, handler, status);
288 return TRUE;
289 }
290 if (fScale != 0) {
291 DigitList digits;
292 digits.set(number);
293 digits.shiftDecimalRight(fScale);
294 formatAdjustedDigitList(digits, appendTo, handler, status);
295 return TRUE;
296 }
297 return FALSE;
298}
299
300template<class T>
301UBool DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList(
302 T number,
303 VisibleDigitsWithExponent &visibleDigits,
304 UErrorCode &status) const {
0f5d89e8
A
305
306 // for <rdar://problem/39240173>, don't need to do the following
307 // below since we don't take those paths; should we anyway?
308 // digits.fFormatFullPrecision = fFormatFullPrecision;
2ca993e8
A
309 if (!fMultiplier.isZero()) {
310 DigitList digits;
311 digits.set(number);
312 digits.mult(fMultiplier, status);
313 digits.shiftDecimalRight(fScale);
314 initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
315 return TRUE;
316 }
317 if (fScale != 0) {
318 DigitList digits;
319 digits.set(number);
320 digits.shiftDecimalRight(fScale);
321 initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
322 return TRUE;
323 }
324 return FALSE;
325}
326
327UnicodeString &
328DecimalFormatImpl::formatInt32(
329 int32_t number,
330 UnicodeString &appendTo,
331 FieldPositionHandler &handler,
332 UErrorCode &status) const {
333 if (maybeFormatWithDigitList(number, appendTo, handler, status)) {
334 return appendTo;
335 }
336 ValueFormatter vf;
337 return fAffixes.formatInt32(
338 number,
339 prepareValueFormatter(vf),
340 handler,
341 fRules,
342 appendTo,
343 status);
344}
345
346UnicodeString &
347DecimalFormatImpl::formatInt64(
348 int64_t number,
349 UnicodeString &appendTo,
350 FieldPositionHandler &handler,
351 UErrorCode &status) const {
352 if (number >= INT32_MIN && number <= INT32_MAX) {
353 return formatInt32((int32_t) number, appendTo, handler, status);
354 }
355 VisibleDigitsWithExponent digits;
356 initVisibleDigitsWithExponent(number, digits, status);
357 return formatVisibleDigitsWithExponent(
358 digits, appendTo, handler, status);
359}
360
361UnicodeString &
362DecimalFormatImpl::formatDouble(
363 double number,
364 UnicodeString &appendTo,
365 FieldPositionHandler &handler,
366 UErrorCode &status) const {
367 VisibleDigitsWithExponent digits;
368 initVisibleDigitsWithExponent(number, digits, status);
369 return formatVisibleDigitsWithExponent(
370 digits, appendTo, handler, status);
371}
372
373UnicodeString &
374DecimalFormatImpl::format(
375 double number,
376 UnicodeString &appendTo,
377 FieldPosition &pos,
378 UErrorCode &status) const {
379 FieldPositionOnlyHandler handler(pos);
380 return formatDouble(number, appendTo, handler, status);
381}
382
383UnicodeString &
384DecimalFormatImpl::format(
385 const DigitList &number,
386 UnicodeString &appendTo,
387 FieldPosition &pos,
388 UErrorCode &status) const {
389 DigitList dl(number);
390 FieldPositionOnlyHandler handler(pos);
391 return formatDigitList(dl, appendTo, handler, status);
392}
393
394UnicodeString &
395DecimalFormatImpl::format(
396 int64_t number,
397 UnicodeString &appendTo,
398 FieldPosition &pos,
399 UErrorCode &status) const {
400 FieldPositionOnlyHandler handler(pos);
401 return formatInt64(number, appendTo, handler, status);
402}
403
404UnicodeString &
405DecimalFormatImpl::format(
406 int64_t number,
407 UnicodeString &appendTo,
408 FieldPositionIterator *posIter,
409 UErrorCode &status) const {
410 FieldPositionIteratorHandler handler(posIter, status);
411 return formatInt64(number, appendTo, handler, status);
412}
413
414UnicodeString &
415DecimalFormatImpl::format(
416 double number,
417 UnicodeString &appendTo,
418 FieldPositionIterator *posIter,
419 UErrorCode &status) const {
420 FieldPositionIteratorHandler handler(posIter, status);
421 return formatDouble(number, appendTo, handler, status);
422}
423
424UnicodeString &
425DecimalFormatImpl::format(
426 const DigitList &number,
427 UnicodeString &appendTo,
428 FieldPositionIterator *posIter,
429 UErrorCode &status) const {
430 DigitList dl(number);
431 FieldPositionIteratorHandler handler(posIter, status);
432 return formatDigitList(dl, appendTo, handler, status);
433}
434
435UnicodeString &
436DecimalFormatImpl::format(
f3c0d7a5 437 StringPiece number,
2ca993e8
A
438 UnicodeString &appendTo,
439 FieldPositionIterator *posIter,
440 UErrorCode &status) const {
441 DigitList dl;
442 dl.set(number, status);
443 FieldPositionIteratorHandler handler(posIter, status);
444 return formatDigitList(dl, appendTo, handler, status);
445}
446
447UnicodeString &
448DecimalFormatImpl::format(
449 const VisibleDigitsWithExponent &digits,
450 UnicodeString &appendTo,
451 FieldPosition &pos,
452 UErrorCode &status) const {
453 FieldPositionOnlyHandler handler(pos);
454 return formatVisibleDigitsWithExponent(
455 digits, appendTo, handler, status);
456}
457
458UnicodeString &
459DecimalFormatImpl::format(
460 const VisibleDigitsWithExponent &digits,
461 UnicodeString &appendTo,
462 FieldPositionIterator *posIter,
463 UErrorCode &status) const {
464 FieldPositionIteratorHandler handler(posIter, status);
465 return formatVisibleDigitsWithExponent(
466 digits, appendTo, handler, status);
467}
468
469DigitList &
470DecimalFormatImpl::adjustDigitList(
471 DigitList &number, UErrorCode &status) const {
472 number.setRoundingMode(fRoundingMode);
473 if (!fMultiplier.isZero()) {
474 number.mult(fMultiplier, status);
475 }
476 if (fScale != 0) {
477 number.shiftDecimalRight(fScale);
478 }
479 number.reduce();
480 return number;
481}
482
483UnicodeString &
484DecimalFormatImpl::formatDigitList(
485 DigitList &number,
486 UnicodeString &appendTo,
487 FieldPositionHandler &handler,
488 UErrorCode &status) const {
489 VisibleDigitsWithExponent digits;
490 initVisibleDigitsWithExponent(number, digits, status);
491 return formatVisibleDigitsWithExponent(
492 digits, appendTo, handler, status);
493}
494
495UnicodeString &
496DecimalFormatImpl::formatAdjustedDigitList(
497 DigitList &number,
498 UnicodeString &appendTo,
499 FieldPositionHandler &handler,
500 UErrorCode &status) const {
501 ValueFormatter vf;
502 return fAffixes.format(
503 number,
504 prepareValueFormatter(vf),
505 handler,
506 fRules,
507 appendTo,
508 status);
509}
510
511UnicodeString &
512DecimalFormatImpl::formatVisibleDigitsWithExponent(
513 const VisibleDigitsWithExponent &digits,
514 UnicodeString &appendTo,
515 FieldPositionHandler &handler,
516 UErrorCode &status) const {
517 ValueFormatter vf;
518 return fAffixes.format(
519 digits,
520 prepareValueFormatter(vf),
521 handler,
522 fRules,
523 appendTo,
524 status);
525}
526
527static FixedDecimal &initFixedDecimal(
528 const VisibleDigits &digits, FixedDecimal &result) {
529 result.source = 0.0;
530 result.isNegative = digits.isNegative();
0f5d89e8
A
531 result._isNaN = digits.isNaN();
532 result._isInfinite = digits.isInfinite();
2ca993e8
A
533 digits.getFixedDecimal(
534 result.source, result.intValue, result.decimalDigits,
535 result.decimalDigitsWithoutTrailingZeros,
0f5d89e8 536 result.visibleDecimalDigitCount, result._hasIntegerValue);
2ca993e8
A
537 return result;
538}
539
540FixedDecimal &
541DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const {
542 if (U_FAILURE(status)) {
543 return result;
544 }
545 VisibleDigits digits;
546 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
547 return initFixedDecimal(digits, result);
548}
549
550FixedDecimal &
551DecimalFormatImpl::getFixedDecimal(
552 DigitList &number, FixedDecimal &result, UErrorCode &status) const {
553 if (U_FAILURE(status)) {
554 return result;
555 }
556 VisibleDigits digits;
557 fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
558 return initFixedDecimal(digits, result);
559}
560
561VisibleDigitsWithExponent &
562DecimalFormatImpl::initVisibleDigitsWithExponent(
563 int64_t number,
564 VisibleDigitsWithExponent &digits,
565 UErrorCode &status) const {
566 if (maybeInitVisibleDigitsFromDigitList(
567 number, digits, status)) {
568 return digits;
569 }
570 if (fUseScientific) {
571 fEffPrecision.initVisibleDigitsWithExponent(
572 number, digits, status);
573 } else {
574 fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
575 number, digits, status);
576 }
577 return digits;
578}
579
580VisibleDigitsWithExponent &
581DecimalFormatImpl::initVisibleDigitsWithExponent(
582 double number,
583 VisibleDigitsWithExponent &digits,
584 UErrorCode &status) const {
585 if (maybeInitVisibleDigitsFromDigitList(
586 number, digits, status)) {
587 return digits;
588 }
589 if (fUseScientific) {
590 fEffPrecision.initVisibleDigitsWithExponent(
591 number, digits, status);
592 } else {
0f5d89e8 593 digits.setFormatFullPrecision(fFormatFullPrecision); // Apple
2ca993e8
A
594 fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
595 number, digits, status);
596 }
597 return digits;
598}
599
600VisibleDigitsWithExponent &
601DecimalFormatImpl::initVisibleDigitsWithExponent(
602 DigitList &number,
603 VisibleDigitsWithExponent &digits,
604 UErrorCode &status) const {
605 adjustDigitList(number, status);
606 return initVisibleDigitsFromAdjusted(number, digits, status);
607}
608
609VisibleDigitsWithExponent &
610DecimalFormatImpl::initVisibleDigitsFromAdjusted(
611 DigitList &number,
612 VisibleDigitsWithExponent &digits,
613 UErrorCode &status) const {
614 if (fUseScientific) {
615 fEffPrecision.initVisibleDigitsWithExponent(
616 number, digits, status);
617 } else {
618 fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
619 number, digits, status);
620 }
621 return digits;
622}
623
624DigitList &
625DecimalFormatImpl::round(
626 DigitList &number, UErrorCode &status) const {
627 if (number.isNaN() || number.isInfinite()) {
628 return number;
629 }
630 adjustDigitList(number, status);
631 ValueFormatter vf;
632 prepareValueFormatter(vf);
633 return vf.round(number, status);
634}
635
636void
637DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) {
638 fMinSigDigits = newValue;
639 fUseSigDigits = TRUE; // ticket 9936
640 updatePrecision();
641}
642
643void
644DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) {
645 fMaxSigDigits = newValue;
646 fUseSigDigits = TRUE; // ticket 9936
647 updatePrecision();
648}
649
650void
651DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) {
652 fMinSigDigits = min;
653 fMaxSigDigits = max;
654 fUseSigDigits = TRUE; // ticket 9936
655 updatePrecision();
656}
657
658void
659DecimalFormatImpl::setScientificNotation(UBool newValue) {
660 fUseScientific = newValue;
661 updatePrecision();
662}
663
664void
665DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) {
666 fUseSigDigits = newValue;
667 updatePrecision();
668}
669
670void
671DecimalFormatImpl::setGroupingSize(int32_t newValue) {
672 fGrouping.fGrouping = newValue;
673 updateGrouping();
674}
675
676void
677DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) {
678 fGrouping.fGrouping2 = newValue;
679 updateGrouping();
680}
681
682void
683DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) {
684 fGrouping.fMinGrouping = newValue;
685 updateGrouping();
686}
687
688void
689DecimalFormatImpl::setCurrencyUsage(
690 UCurrencyUsage currencyUsage, UErrorCode &status) {
691 fCurrencyUsage = currencyUsage;
692 updateFormatting(kFormattingCurrency, status);
693}
694
695void
696DecimalFormatImpl::setRoundingIncrement(double d) {
697 if (d > 0.0) {
698 fEffPrecision.fMantissa.fRoundingIncrement.set(d);
699 } else {
700 fEffPrecision.fMantissa.fRoundingIncrement.set(0.0);
701 }
702}
703
704double
705DecimalFormatImpl::getRoundingIncrement() const {
706 return fEffPrecision.fMantissa.fRoundingIncrement.getDouble();
707}
708
709int32_t
710DecimalFormatImpl::getMultiplier() const {
711 if (fMultiplier.isZero()) {
712 return 1;
713 }
714 return (int32_t) fMultiplier.getDouble();
715}
716
717void
718DecimalFormatImpl::setMultiplier(int32_t m) {
719 if (m == 0 || m == 1) {
f3c0d7a5 720 fMultiplier.set((int32_t)0);
2ca993e8
A
721 } else {
722 fMultiplier.set(m);
723 }
724}
725
726void
727DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) {
728 fPositivePrefixPattern.remove();
729 fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
730 UErrorCode status = U_ZERO_ERROR;
731 updateFormatting(kFormattingPosPrefix, status);
732}
733
734void
735DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) {
736 fPositiveSuffixPattern.remove();
737 fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
738 UErrorCode status = U_ZERO_ERROR;
739 updateFormatting(kFormattingPosSuffix, status);
740}
741
742void
743DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) {
744 fNegativePrefixPattern.remove();
745 fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
746 UErrorCode status = U_ZERO_ERROR;
747 updateFormatting(kFormattingNegPrefix, status);
748}
749
750void
751DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) {
752 fNegativeSuffixPattern.remove();
753 fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
754 UErrorCode status = U_ZERO_ERROR;
755 updateFormatting(kFormattingNegSuffix, status);
756}
757
758UnicodeString &
759DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const {
760 result = fAffixes.fPositivePrefix.getOtherVariant().toString();
761 return result;
762}
763
764UnicodeString &
765DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const {
766 result = fAffixes.fPositiveSuffix.getOtherVariant().toString();
767 return result;
768}
769
770UnicodeString &
771DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const {
772 result = fAffixes.fNegativePrefix.getOtherVariant().toString();
773 return result;
774}
775
776UnicodeString &
777DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const {
778 result = fAffixes.fNegativeSuffix.getOtherVariant().toString();
779 return result;
780}
781
782void
783DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) {
784 if (symbolsToAdopt == NULL) {
785 return;
786 }
787 delete fSymbols;
788 fSymbols = symbolsToAdopt;
789 UErrorCode status = U_ZERO_ERROR;
790 updateFormatting(kFormattingSymbols, status);
791}
792
793void
794DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
795 const UnicodeString &pattern, UErrorCode &status) {
796 UParseError perror;
797 applyPattern(pattern, FALSE, perror, status);
798 updateForApplyPatternFavorCurrencyPrecision(status);
799}
800
801void
802DecimalFormatImpl::applyPattern(
803 const UnicodeString &pattern, UErrorCode &status) {
804 UParseError perror;
805 applyPattern(pattern, FALSE, perror, status);
806 updateForApplyPattern(status);
807}
808
809void
810DecimalFormatImpl::applyPattern(
811 const UnicodeString &pattern,
812 UParseError &perror, UErrorCode &status) {
813 applyPattern(pattern, FALSE, perror, status);
814 updateForApplyPattern(status);
815}
816
817void
818DecimalFormatImpl::applyLocalizedPattern(
819 const UnicodeString &pattern, UErrorCode &status) {
820 UParseError perror;
821 applyPattern(pattern, TRUE, perror, status);
822 updateForApplyPattern(status);
823}
824
825void
826DecimalFormatImpl::applyLocalizedPattern(
827 const UnicodeString &pattern,
828 UParseError &perror, UErrorCode &status) {
829 applyPattern(pattern, TRUE, perror, status);
830 updateForApplyPattern(status);
831}
832
833void
834DecimalFormatImpl::applyPattern(
835 const UnicodeString &pattern,
836 UBool localized, UParseError &perror, UErrorCode &status) {
837 if (U_FAILURE(status)) {
838 return;
839 }
840 DecimalFormatPatternParser patternParser;
841 if (localized) {
842 patternParser.useSymbols(*fSymbols);
843 }
844 DecimalFormatPattern out;
845 patternParser.applyPatternWithoutExpandAffix(
846 pattern, out, perror, status);
847 if (U_FAILURE(status)) {
848 return;
849 }
850 fUseScientific = out.fUseExponentialNotation;
851 fUseSigDigits = out.fUseSignificantDigits;
852 fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits);
853 fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits);
854 fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits);
855 fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits);
856 fMinSigDigits = out.fMinimumSignificantDigits;
857 fMaxSigDigits = out.fMaximumSignificantDigits;
858 fEffPrecision.fMinExponentDigits = out.fMinExponentDigits;
859 fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown;
860 fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed);
861 fGrouping.fGrouping = out.fGroupingSize;
862 fGrouping.fGrouping2 = out.fGroupingSize2;
863 fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown;
864 if (out.fRoundingIncrementUsed) {
865 fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement;
866 } else {
867 fEffPrecision.fMantissa.fRoundingIncrement.clear();
868 }
869 fAffixes.fPadChar = out.fPad;
870 fNegativePrefixPattern = out.fNegPrefixAffix;
871 fNegativeSuffixPattern = out.fNegSuffixAffix;
872 fPositivePrefixPattern = out.fPosPrefixAffix;
873 fPositiveSuffixPattern = out.fPosSuffixAffix;
874
875 // Work around. Pattern parsing code and DecimalFormat code don't agree
876 // on the definition of field width, so we have to translate from
877 // pattern field width to decimal format field width here.
878 fAffixes.fWidth = out.fFormatWidth == 0 ? 0 :
879 out.fFormatWidth + fPositivePrefixPattern.countChar32()
880 + fPositiveSuffixPattern.countChar32();
881 switch (out.fPadPosition) {
882 case DecimalFormatPattern::kPadBeforePrefix:
883 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix;
884 break;
885 case DecimalFormatPattern::kPadAfterPrefix:
886 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix;
887 break;
888 case DecimalFormatPattern::kPadBeforeSuffix:
889 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix;
890 break;
891 case DecimalFormatPattern::kPadAfterSuffix:
892 fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
893 break;
894 default:
895 break;
896 }
897}
898
899void
900DecimalFormatImpl::updatePrecision() {
901 if (fUseScientific) {
902 updatePrecisionForScientific();
903 } else {
904 updatePrecisionForFixed();
905 }
906}
907
908static void updatePrecisionForScientificMinMax(
909 const DigitInterval &min,
910 const DigitInterval &max,
911 DigitInterval &resultMin,
912 DigitInterval &resultMax,
913 SignificantDigitInterval &resultSignificant) {
914 resultMin.setIntDigitCount(0);
915 resultMin.setFracDigitCount(0);
916 resultSignificant.clear();
917 resultMax.clear();
918
919 int32_t maxIntDigitCount = max.getIntDigitCount();
920 int32_t minIntDigitCount = min.getIntDigitCount();
921 int32_t maxFracDigitCount = max.getFracDigitCount();
922 int32_t minFracDigitCount = min.getFracDigitCount();
923
924
925 // Not in spec: maxIntDigitCount > 8 assume
926 // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
927 // no provision for unsetting maxIntDigitCount which would be useful for
928 // scientific notation. The best we can do is assume that if
929 // maxIntDigitCount is the default of 2000000000 or is "big enough" then
930 // user did not intend to explicitly set it. The 8 was derived emperically
931 // by extensive testing of legacy code.
932 if (maxIntDigitCount > 8) {
933 maxIntDigitCount = minIntDigitCount;
934 }
935
936 // Per the spec, exponent grouping happens if maxIntDigitCount is more
937 // than 1 and more than minIntDigitCount.
938 UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount;
939 if (bExponentGrouping) {
940 resultMax.setIntDigitCount(maxIntDigitCount);
941
942 // For exponent grouping minIntDigits is always treated as 1 even
943 // if it wasn't set to 1!
944 resultMin.setIntDigitCount(1);
945 } else {
946 // Fixed digit count left of decimal. minIntDigitCount doesn't have
947 // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
948 // maxIntDigitCount == 1.
949 int32_t fixedIntDigitCount = maxIntDigitCount;
950
951 // If fixedIntDigitCount is 0 but
952 // min or max fraction count is 0 too then use 1. This way we can get
953 // unlimited precision for X.XXXEX
954 if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) {
955 fixedIntDigitCount = 1;
956 }
957 resultMax.setIntDigitCount(fixedIntDigitCount);
958 resultMin.setIntDigitCount(fixedIntDigitCount);
959 }
960 // Spec says this is how we compute significant digits. 0 means
961 // unlimited significant digits.
962 int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount;
963 if (maxSigDigits > 0) {
964 int32_t minSigDigits = minIntDigitCount + minFracDigitCount;
965 resultSignificant.setMin(minSigDigits);
966 resultSignificant.setMax(maxSigDigits);
967 }
968}
969
970void
971DecimalFormatImpl::updatePrecisionForScientific() {
972 FixedPrecision *result = &fEffPrecision.fMantissa;
973 if (fUseSigDigits) {
974 result->fMax.setFracDigitCount(-1);
975 result->fMax.setIntDigitCount(1);
976 result->fMin.setFracDigitCount(0);
977 result->fMin.setIntDigitCount(1);
978 result->fSignificant.clear();
979 extractSigDigits(result->fSignificant);
980 return;
981 }
982 DigitInterval max;
983 DigitInterval min;
984 extractMinMaxDigits(min, max);
985 updatePrecisionForScientificMinMax(
986 min, max,
987 result->fMin, result->fMax, result->fSignificant);
988}
989
990void
991DecimalFormatImpl::updatePrecisionForFixed() {
992 FixedPrecision *result = &fEffPrecision.fMantissa;
993 if (!fUseSigDigits) {
994 extractMinMaxDigits(result->fMin, result->fMax);
995 result->fSignificant.clear();
996 } else {
997 extractSigDigits(result->fSignificant);
998 result->fMin.setIntDigitCount(1);
999 result->fMin.setFracDigitCount(0);
1000 result->fMax.clear();
1001 }
1002}
1003
1004void
1005 DecimalFormatImpl::extractMinMaxDigits(
1006 DigitInterval &min, DigitInterval &max) const {
1007 min.setIntDigitCount(fSuper->getMinimumIntegerDigits());
1008 max.setIntDigitCount(fSuper->getMaximumIntegerDigits());
1009 min.setFracDigitCount(fSuper->getMinimumFractionDigits());
1010 max.setFracDigitCount(fSuper->getMaximumFractionDigits());
1011}
1012
1013void
1014 DecimalFormatImpl::extractSigDigits(
1015 SignificantDigitInterval &sig) const {
1016 sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits);
1017 sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits);
1018}
1019
1020void
1021DecimalFormatImpl::updateGrouping() {
1022 if (fSuper->isGroupingUsed()) {
1023 fEffGrouping = fGrouping;
1024 } else {
1025 fEffGrouping.clear();
1026 }
1027}
1028
1029void
1030DecimalFormatImpl::updateCurrency(UErrorCode &status) {
1031 updateFormatting(kFormattingCurrency, TRUE, status);
1032}
1033
1034void
1035DecimalFormatImpl::updateFormatting(
1036 int32_t changedFormattingFields,
1037 UErrorCode &status) {
1038 updateFormatting(changedFormattingFields, TRUE, status);
1039}
1040
1041void
1042DecimalFormatImpl::updateFormatting(
1043 int32_t changedFormattingFields,
1044 UBool updatePrecisionBasedOnCurrency,
1045 UErrorCode &status) {
1046 if (U_FAILURE(status)) {
1047 return;
1048 }
1049 // Each function updates one field. Order matters. For instance,
1050 // updatePluralRules comes before updateCurrencyAffixInfo because the
1051 // fRules field is needed to update the fCurrencyAffixInfo field.
1052 updateFormattingUsesCurrency(changedFormattingFields);
1053 updateFormattingFixedPointFormatter(changedFormattingFields);
1054 updateFormattingAffixParser(changedFormattingFields);
1055 updateFormattingPluralRules(changedFormattingFields, status);
1056 updateFormattingCurrencyAffixInfo(
1057 changedFormattingFields,
1058 updatePrecisionBasedOnCurrency,
1059 status);
1060 updateFormattingLocalizedPositivePrefix(
1061 changedFormattingFields, status);
1062 updateFormattingLocalizedPositiveSuffix(
1063 changedFormattingFields, status);
1064 updateFormattingLocalizedNegativePrefix(
1065 changedFormattingFields, status);
1066 updateFormattingLocalizedNegativeSuffix(
1067 changedFormattingFields, status);
1068}
1069
1070void
1071DecimalFormatImpl::updateFormattingUsesCurrency(
1072 int32_t &changedFormattingFields) {
1073 if ((changedFormattingFields & kFormattingAffixes) == 0) {
1074 // If no affixes changed, don't need to do any work
1075 return;
1076 }
1077 UBool newUsesCurrency =
1078 fPositivePrefixPattern.usesCurrency() ||
1079 fPositiveSuffixPattern.usesCurrency() ||
1080 fNegativePrefixPattern.usesCurrency() ||
1081 fNegativeSuffixPattern.usesCurrency();
1082 if (fMonetary != newUsesCurrency) {
1083 fMonetary = newUsesCurrency;
1084 changedFormattingFields |= kFormattingUsesCurrency;
1085 }
1086}
1087
1088void
1089DecimalFormatImpl::updateFormattingPluralRules(
1090 int32_t &changedFormattingFields, UErrorCode &status) {
1091 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
1092 // No work to do if both fSymbols and fMonetary
1093 // fields are unchanged
1094 return;
1095 }
1096 if (U_FAILURE(status)) {
1097 return;
1098 }
1099 PluralRules *newRules = NULL;
1100 if (fMonetary) {
1101 newRules = PluralRules::forLocale(fSymbols->getLocale(), status);
1102 if (U_FAILURE(status)) {
1103 return;
1104 }
1105 }
1106 // Its ok to say a field has changed when it really hasn't but not
1107 // the other way around. Here we assume the field changed unless it
1108 // was NULL before and is still NULL now
1109 if (fRules != newRules) {
1110 delete fRules;
1111 fRules = newRules;
1112 changedFormattingFields |= kFormattingPluralRules;
1113 }
1114}
1115
1116void
1117DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
1118 int32_t &changedFormattingFields,
1119 UBool updatePrecisionBasedOnCurrency,
1120 UErrorCode &status) {
1121 if ((changedFormattingFields & (
1122 kFormattingSymbols | kFormattingCurrency |
1123 kFormattingUsesCurrency | kFormattingPluralRules)) == 0) {
1124 // If all these fields are unchanged, no work to do.
1125 return;
1126 }
1127 if (U_FAILURE(status)) {
1128 return;
1129 }
1130 if (!fMonetary) {
1131 if (fCurrencyAffixInfo.isDefault()) {
1132 // In this case don't have to do any work
1133 return;
1134 }
1135 fCurrencyAffixInfo.set(NULL, NULL, NULL, status);
1136 if (U_FAILURE(status)) {
1137 return;
1138 }
1139 changedFormattingFields |= kFormattingCurrencyAffixInfo;
1140 } else {
1141 const UChar *currency = fSuper->getCurrency();
1142 UChar localeCurr[4];
1143 if (currency[0] == 0) {
1144 ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status);
1145 if (U_SUCCESS(status)) {
1146 currency = localeCurr;
1147 fSuper->NumberFormat::setCurrency(currency, status);
1148 } else {
1149 currency = NULL;
1150 status = U_ZERO_ERROR;
1151 }
1152 }
1153 fCurrencyAffixInfo.set(
1154 fSymbols->getLocale().getName(), fRules, currency, status);
1155 if (U_FAILURE(status)) {
1156 return;
1157 }
1158 UBool customCurrencySymbol = FALSE;
1159 // If DecimalFormatSymbols has custom currency symbol, prefer
1160 // that over what we just read from the resource bundles
1161 if (fSymbols->isCustomCurrencySymbol()) {
1162 fCurrencyAffixInfo.setSymbol(
1163 fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
1164 customCurrencySymbol = TRUE;
1165 }
1166 if (fSymbols->isCustomIntlCurrencySymbol()) {
1167 fCurrencyAffixInfo.setISO(
1168 fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
1169 customCurrencySymbol = TRUE;
1170 }
1171 changedFormattingFields |= kFormattingCurrencyAffixInfo;
1172 if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) {
1173 FixedPrecision precision;
1174 CurrencyAffixInfo::adjustPrecision(
1175 currency, fCurrencyUsage, precision, status);
1176 if (U_FAILURE(status)) {
1177 return;
1178 }
1179 fSuper->NumberFormat::setMinimumFractionDigits(
1180 precision.fMin.getFracDigitCount());
1181 fSuper->NumberFormat::setMaximumFractionDigits(
1182 precision.fMax.getFracDigitCount());
1183 updatePrecision();
1184 fEffPrecision.fMantissa.fRoundingIncrement =
1185 precision.fRoundingIncrement;
1186 }
1187
1188 }
1189}
1190
1191void
1192DecimalFormatImpl::updateFormattingFixedPointFormatter(
1193 int32_t &changedFormattingFields) {
1194 if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
1195 // No work to do if fSymbols is unchanged
1196 return;
1197 }
1198 if (fMonetary) {
1199 fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols);
1200 } else {
1201 fFormatter.setDecimalFormatSymbols(*fSymbols);
1202 }
1203}
1204
1205void
1206DecimalFormatImpl::updateFormattingAffixParser(
1207 int32_t &changedFormattingFields) {
1208 if ((changedFormattingFields & kFormattingSymbols) == 0) {
1209 // No work to do if fSymbols is unchanged
1210 return;
1211 }
1212 fAffixParser.setDecimalFormatSymbols(*fSymbols);
1213 changedFormattingFields |= kFormattingAffixParser;
1214}
1215
1216void
1217DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
1218 int32_t &changedFormattingFields, UErrorCode &status) {
1219 if (U_FAILURE(status)) {
1220 return;
1221 }
1222 if ((changedFormattingFields & (
1223 kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) {
1224 // No work to do
1225 return;
1226 }
1227 fAffixes.fPositivePrefix.remove();
1228 fAffixParser.parse(
1229 fPositivePrefixPattern,
1230 fCurrencyAffixInfo,
1231 fAffixes.fPositivePrefix,
1232 status);
1233}
1234
1235void
1236DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
1237 int32_t &changedFormattingFields, UErrorCode &status) {
1238 if (U_FAILURE(status)) {
1239 return;
1240 }
1241 if ((changedFormattingFields & (
1242 kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) {
1243 // No work to do
1244 return;
1245 }
1246 fAffixes.fPositiveSuffix.remove();
1247 fAffixParser.parse(
1248 fPositiveSuffixPattern,
1249 fCurrencyAffixInfo,
1250 fAffixes.fPositiveSuffix,
1251 status);
1252}
1253
1254void
1255DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
1256 int32_t &changedFormattingFields, UErrorCode &status) {
1257 if (U_FAILURE(status)) {
1258 return;
1259 }
1260 if ((changedFormattingFields & (
1261 kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) {
1262 // No work to do
1263 return;
1264 }
1265 fAffixes.fNegativePrefix.remove();
1266 fAffixParser.parse(
1267 fNegativePrefixPattern,
1268 fCurrencyAffixInfo,
1269 fAffixes.fNegativePrefix,
1270 status);
1271}
1272
1273void
1274DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
1275 int32_t &changedFormattingFields, UErrorCode &status) {
1276 if (U_FAILURE(status)) {
1277 return;
1278 }
1279 if ((changedFormattingFields & (
1280 kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) {
1281 // No work to do
1282 return;
1283 }
1284 fAffixes.fNegativeSuffix.remove();
1285 fAffixParser.parse(
1286 fNegativeSuffixPattern,
1287 fCurrencyAffixInfo,
1288 fAffixes.fNegativeSuffix,
1289 status);
1290}
1291
1292void
1293DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
1294 UErrorCode &status) {
1295 updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status);
1296}
1297
1298void
1299DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) {
1300 updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status);
1301}
1302
1303void
1304DecimalFormatImpl::updateAll(UErrorCode &status) {
1305 updateAll(kFormattingAll, TRUE, status);
1306}
1307
1308void
1309DecimalFormatImpl::updateAll(
1310 int32_t formattingFlags,
1311 UBool updatePrecisionBasedOnCurrency,
1312 UErrorCode &status) {
1313 if (U_FAILURE(status)) {
1314 return;
1315 }
1316 updatePrecision();
1317 updateGrouping();
1318 updateFormatting(
1319 formattingFlags, updatePrecisionBasedOnCurrency, status);
1320 setMultiplierScale(getPatternScale());
0f5d89e8 1321 fFormatFullPrecision = FALSE;
2ca993e8
A
1322}
1323
1324
1325static int32_t
1326getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) {
1327 if (grouping.fGrouping <= 0) {
1328 return 0;
1329 }
1330 if (grouping.fGrouping2 <= 0) {
1331 return grouping.fGrouping + 1;
1332 }
1333 return grouping.fGrouping + grouping.fGrouping2 + 1;
1334}
1335
1336/**
1337 * Given a grouping policy, calculates how many digits are needed left of
1338 * the decimal point to achieve a desired length left of the
1339 * decimal point.
1340 * @param grouping the grouping policy
1341 * @param desiredLength number of characters needed left of decimal point
1342 * @param minLeftDigits at least this many digits is returned
1343 * @param leftDigits the number of digits needed stored here
1344 * which is >= minLeftDigits.
1345 * @return true if a perfect fit or false if having leftDigits would exceed
1346 * desiredLength
1347 */
1348static UBool
1349getLeftDigitsForLeftLength(
1350 const DigitGrouping &grouping,
1351 int32_t desiredLength,
1352 int32_t minLeftDigits,
1353 int32_t &leftDigits) {
1354 leftDigits = minLeftDigits;
1355 int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits);
1356 while (lengthSoFar < desiredLength) {
1357 lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1;
1358 ++leftDigits;
1359 }
1360 return (lengthSoFar == desiredLength);
1361}
1362
1363int32_t
1364DecimalFormatImpl::computeExponentPatternLength() const {
1365 if (fUseScientific) {
1366 return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits;
1367 }
1368 return 0;
1369}
1370
1371int32_t
1372DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
1373 int32_t fracDigitCount) const {
1374 if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) {
1375 return 0;
1376 }
1377 return fracDigitCount + 1;
1378}
1379
1380UnicodeString&
1381DecimalFormatImpl::toNumberPattern(
1382 UBool hasPadding, int32_t minimumLength, UnicodeString& result) const {
1383 // Get a grouping policy like the one in this object that does not
1384 // have minimum grouping since toPattern doesn't support it.
1385 DigitGrouping grouping(fEffGrouping);
1386 grouping.fMinGrouping = 0;
1387
1388 // Only for fixed digits, these are the digits that get 0's.
1389 DigitInterval minInterval;
1390
1391 // Only for fixed digits, these are the digits that get #'s.
1392 DigitInterval maxInterval;
1393
1394 // Only for significant digits
0f5d89e8
A
1395 int32_t sigMin = 0; /* initialize to avoid compiler warning */
1396 int32_t sigMax = 0; /* initialize to avoid compiler warning */
2ca993e8
A
1397
1398 // These are all the digits to be displayed. For significant digits,
1399 // this interval always starts at the 1's place an extends left.
1400 DigitInterval fullInterval;
1401
1402 // Digit range of rounding increment. If rounding increment is .025.
1403 // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
1404 int32_t roundingIncrementLowerExp = 0;
1405 int32_t roundingIncrementUpperExp = 0;
1406
1407 if (fUseSigDigits) {
1408 SignificantDigitInterval sigInterval;
1409 extractSigDigits(sigInterval);
1410 sigMax = sigInterval.getMax();
1411 sigMin = sigInterval.getMin();
1412 fullInterval.setFracDigitCount(0);
1413 fullInterval.setIntDigitCount(sigMax);
1414 } else {
1415 extractMinMaxDigits(minInterval, maxInterval);
1416 if (fUseScientific) {
1417 if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) {
1418 maxInterval.setIntDigitCount(1);
1419 minInterval.shrinkToFitWithin(maxInterval);
1420 }
1421 } else if (hasPadding) {
1422 // Make max int digits match min int digits for now, we
1423 // compute necessary padding later.
1424 maxInterval.setIntDigitCount(minInterval.getIntDigitCount());
1425 } else {
1426 // For some reason toPattern adds at least one leading '#'
1427 maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1);
1428 }
1429 if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) {
1430 roundingIncrementLowerExp =
1431 fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent();
1432 roundingIncrementUpperExp =
1433 fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent();
1434 // We have to include the rounding increment in what we display
1435 maxInterval.expandToContainDigit(roundingIncrementLowerExp);
1436 maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1);
1437 }
1438 fullInterval = maxInterval;
1439 }
1440 // We have to include enough digits to show grouping strategy
1441 int32_t minLengthToDescribeGrouping =
1442 getMinimumLengthToDescribeGrouping(grouping);
1443 if (minLengthToDescribeGrouping > 0) {
1444 fullInterval.expandToContainDigit(
1445 getMinimumLengthToDescribeGrouping(grouping) - 1);
1446 }
1447
1448 // If we have a minimum length, we have to add digits to the left to
1449 // depict padding.
1450 if (hasPadding) {
1451 // For non scientific notation,
1452 // minimumLengthForMantissa = minimumLength
1453 int32_t minimumLengthForMantissa =
1454 minimumLength - computeExponentPatternLength();
1455 int32_t mininumLengthForMantissaIntPart =
1456 minimumLengthForMantissa
1457 - countFractionDigitAndDecimalPatternLength(
1458 fullInterval.getFracDigitCount());
1459 // Because of grouping, we may need fewer than expected digits to
1460 // achieve the length we need.
1461 int32_t digitsNeeded;
1462 if (getLeftDigitsForLeftLength(
1463 grouping,
1464 mininumLengthForMantissaIntPart,
1465 fullInterval.getIntDigitCount(),
1466 digitsNeeded)) {
1467
1468 // In this case, we achieved the exact length that we want.
1469 fullInterval.setIntDigitCount(digitsNeeded);
1470 } else if (digitsNeeded > fullInterval.getIntDigitCount()) {
1471
1472 // Having digitsNeeded digits goes over desired length which
1473 // means that to have desired length would mean starting on a
1474 // grouping sepearator e.g ,###,### so add a '#' and use one
1475 // less digit. This trick gives ####,### but that is the best
1476 // we can do.
1477 result.append(kPatternDigit);
1478 fullInterval.setIntDigitCount(digitsNeeded - 1);
1479 }
1480 }
1481 int32_t maxDigitPos = fullInterval.getMostSignificantExclusive();
1482 int32_t minDigitPos = fullInterval.getLeastSignificantInclusive();
1483 for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) {
1484 if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) {
1485 result.append(kPatternDecimalSeparator);
1486 }
1487 if (fUseSigDigits) {
1488 // Use digit symbol
1489 if (i >= sigMax || i < sigMax - sigMin) {
1490 result.append(kPatternDigit);
1491 } else {
1492 result.append(kPatternSignificantDigit);
1493 }
1494 } else {
1495 if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) {
f3c0d7a5 1496 result.append((UChar)(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit));
2ca993e8
A
1497 } else if (minInterval.contains(i)) {
1498 result.append(kPatternZeroDigit);
1499 } else {
1500 result.append(kPatternDigit);
1501 }
1502 }
1503 if (grouping.isSeparatorAt(i + 1, i)) {
1504 result.append(kPatternGroupingSeparator);
1505 }
1506 if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) {
1507 result.append(kPatternDecimalSeparator);
1508 }
1509 }
1510 if (fUseScientific) {
1511 result.append(kPatternExponent);
1512 if (fOptions.fExponent.fAlwaysShowSign) {
1513 result.append(kPatternPlus);
1514 }
1515 for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) {
1516 result.append(kPatternZeroDigit);
1517 }
1518 }
1519 return result;
1520}
1521
1522UnicodeString&
1523DecimalFormatImpl::toPattern(UnicodeString& result) const {
1524 result.remove();
1525 UnicodeString padSpec;
1526 if (fAffixes.fWidth > 0) {
1527 padSpec.append(kPatternPadEscape);
1528 padSpec.append(fAffixes.fPadChar);
1529 }
1530 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
1531 result.append(padSpec);
1532 }
1533 fPositivePrefixPattern.toUserString(result);
1534 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
1535 result.append(padSpec);
1536 }
1537 toNumberPattern(
1538 fAffixes.fWidth > 0,
1539 fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(),
1540 result);
1541 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
1542 result.append(padSpec);
1543 }
1544 fPositiveSuffixPattern.toUserString(result);
1545 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
1546 result.append(padSpec);
1547 }
1548 AffixPattern withNegative;
1549 withNegative.add(AffixPattern::kNegative);
1550 withNegative.append(fPositivePrefixPattern);
1551 if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) ||
1552 !withNegative.equals(fNegativePrefixPattern)) {
1553 result.append(kPatternSeparator);
1554 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
1555 result.append(padSpec);
1556 }
1557 fNegativePrefixPattern.toUserString(result);
1558 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
1559 result.append(padSpec);
1560 }
1561 toNumberPattern(
1562 fAffixes.fWidth > 0,
1563 fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(),
1564 result);
1565 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
1566 result.append(padSpec);
1567 }
1568 fNegativeSuffixPattern.toUserString(result);
1569 if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
1570 result.append(padSpec);
1571 }
1572 }
1573 return result;
1574}
1575
1576int32_t
1577DecimalFormatImpl::getOldFormatWidth() const {
1578 if (fAffixes.fWidth == 0) {
1579 return 0;
1580 }
1581 return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32();
1582}
1583
1584const UnicodeString &
1585DecimalFormatImpl::getConstSymbol(
1586 DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
1587 return fSymbols->getConstSymbol(symbol);
1588}
1589
1590UBool
1591DecimalFormatImpl::isParseFastpath() const {
1592 AffixPattern negative;
1593 negative.add(AffixPattern::kNegative);
1594
1595 return fAffixes.fWidth == 0 &&
1596 fPositivePrefixPattern.countChar32() == 0 &&
1597 fNegativePrefixPattern.equals(negative) &&
1598 fPositiveSuffixPattern.countChar32() == 0 &&
1599 fNegativeSuffixPattern.countChar32() == 0;
1600}
1601
1602
1603U_NAMESPACE_END
1604
1605#endif /* #if !UCONFIG_NO_FORMATTING */
1606