summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/decimfmtimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/decimfmtimpl.cpp')
-rw-r--r--deps/icu-small/source/i18n/decimfmtimpl.cpp1596
1 files changed, 0 insertions, 1596 deletions
diff --git a/deps/icu-small/source/i18n/decimfmtimpl.cpp b/deps/icu-small/source/i18n/decimfmtimpl.cpp
deleted file mode 100644
index ef44eab010..0000000000
--- a/deps/icu-small/source/i18n/decimfmtimpl.cpp
+++ /dev/null
@@ -1,1596 +0,0 @@
-// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
- * Copyright (C) 2015, International Business Machines
- * Corporation and others. All Rights Reserved.
- *
- * file name: decimfmtimpl.cpp
- */
-
-#include "unicode/utypes.h"
-
-#if !UCONFIG_NO_FORMATTING
-
-#include <math.h>
-#include "unicode/numfmt.h"
-#include "unicode/plurrule.h"
-#include "unicode/ustring.h"
-#include "decimalformatpattern.h"
-#include "decimalformatpatternimpl.h"
-#include "decimfmtimpl.h"
-#include "fphdlimp.h"
-#include "plurrule_impl.h"
-#include "valueformatter.h"
-#include "visibledigits.h"
-
-U_NAMESPACE_BEGIN
-
-static const int32_t kMaxScientificIntegerDigits = 8;
-
-static const int32_t kFormattingPosPrefix = (1 << 0);
-static const int32_t kFormattingNegPrefix = (1 << 1);
-static const int32_t kFormattingPosSuffix = (1 << 2);
-static const int32_t kFormattingNegSuffix = (1 << 3);
-static const int32_t kFormattingSymbols = (1 << 4);
-static const int32_t kFormattingCurrency = (1 << 5);
-static const int32_t kFormattingUsesCurrency = (1 << 6);
-static const int32_t kFormattingPluralRules = (1 << 7);
-static const int32_t kFormattingAffixParser = (1 << 8);
-static const int32_t kFormattingCurrencyAffixInfo = (1 << 9);
-static const int32_t kFormattingAll = (1 << 10) - 1;
-static const int32_t kFormattingAffixes =
- kFormattingPosPrefix | kFormattingPosSuffix |
- kFormattingNegPrefix | kFormattingNegSuffix;
-static const int32_t kFormattingAffixParserWithCurrency =
- kFormattingAffixParser | kFormattingCurrencyAffixInfo;
-
-DecimalFormatImpl::DecimalFormatImpl(
- NumberFormat *super,
- const Locale &locale,
- const UnicodeString &pattern,
- UErrorCode &status)
- : fSuper(super),
- fScale(0),
- fRoundingMode(DecimalFormat::kRoundHalfEven),
- fSymbols(NULL),
- fCurrencyUsage(UCURR_USAGE_STANDARD),
- fRules(NULL),
- fMonetary(FALSE) {
- if (U_FAILURE(status)) {
- return;
- }
- fSymbols = new DecimalFormatSymbols(
- locale, status);
- if (fSymbols == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return;
- }
- UParseError parseError;
- applyPattern(pattern, FALSE, parseError, status);
- updateAll(status);
-}
-
-DecimalFormatImpl::DecimalFormatImpl(
- NumberFormat *super,
- const UnicodeString &pattern,
- DecimalFormatSymbols *symbolsToAdopt,
- UParseError &parseError,
- UErrorCode &status)
- : fSuper(super),
- fScale(0),
- fRoundingMode(DecimalFormat::kRoundHalfEven),
- fSymbols(symbolsToAdopt),
- fCurrencyUsage(UCURR_USAGE_STANDARD),
- fRules(NULL),
- fMonetary(FALSE) {
- applyPattern(pattern, FALSE, parseError, status);
- updateAll(status);
-}
-
-DecimalFormatImpl::DecimalFormatImpl(
- NumberFormat *super, const DecimalFormatImpl &other, UErrorCode &status) :
- fSuper(super),
- fMultiplier(other.fMultiplier),
- fScale(other.fScale),
- fRoundingMode(other.fRoundingMode),
- fMinSigDigits(other.fMinSigDigits),
- fMaxSigDigits(other.fMaxSigDigits),
- fUseScientific(other.fUseScientific),
- fUseSigDigits(other.fUseSigDigits),
- fGrouping(other.fGrouping),
- fPositivePrefixPattern(other.fPositivePrefixPattern),
- fNegativePrefixPattern(other.fNegativePrefixPattern),
- fPositiveSuffixPattern(other.fPositiveSuffixPattern),
- fNegativeSuffixPattern(other.fNegativeSuffixPattern),
- fSymbols(other.fSymbols),
- fCurrencyUsage(other.fCurrencyUsage),
- fRules(NULL),
- fMonetary(other.fMonetary),
- fAffixParser(other.fAffixParser),
- fCurrencyAffixInfo(other.fCurrencyAffixInfo),
- fEffPrecision(other.fEffPrecision),
- fEffGrouping(other.fEffGrouping),
- fOptions(other.fOptions),
- fFormatter(other.fFormatter),
- fAffixes(other.fAffixes) {
- fSymbols = new DecimalFormatSymbols(*fSymbols);
- if (fSymbols == NULL && U_SUCCESS(status)) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
- if (other.fRules != NULL) {
- fRules = new PluralRules(*other.fRules);
- if (fRules == NULL && U_SUCCESS(status)) {
- status = U_MEMORY_ALLOCATION_ERROR;
- }
- }
-}
-
-
-DecimalFormatImpl &
-DecimalFormatImpl::assign(const DecimalFormatImpl &other, UErrorCode &status) {
- if (U_FAILURE(status) || this == &other) {
- return (*this);
- }
- UObject::operator=(other);
- fMultiplier = other.fMultiplier;
- fScale = other.fScale;
- fRoundingMode = other.fRoundingMode;
- fMinSigDigits = other.fMinSigDigits;
- fMaxSigDigits = other.fMaxSigDigits;
- fUseScientific = other.fUseScientific;
- fUseSigDigits = other.fUseSigDigits;
- fGrouping = other.fGrouping;
- fPositivePrefixPattern = other.fPositivePrefixPattern;
- fNegativePrefixPattern = other.fNegativePrefixPattern;
- fPositiveSuffixPattern = other.fPositiveSuffixPattern;
- fNegativeSuffixPattern = other.fNegativeSuffixPattern;
- fCurrencyUsage = other.fCurrencyUsage;
- fMonetary = other.fMonetary;
- fAffixParser = other.fAffixParser;
- fCurrencyAffixInfo = other.fCurrencyAffixInfo;
- fEffPrecision = other.fEffPrecision;
- fEffGrouping = other.fEffGrouping;
- fOptions = other.fOptions;
- fFormatter = other.fFormatter;
- fAffixes = other.fAffixes;
- *fSymbols = *other.fSymbols;
- if (fRules != NULL && other.fRules != NULL) {
- *fRules = *other.fRules;
- } else {
- delete fRules;
- fRules = other.fRules;
- if (fRules != NULL) {
- fRules = new PluralRules(*fRules);
- if (fRules == NULL) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return *this;
- }
- }
- }
- return *this;
-}
-
-UBool
-DecimalFormatImpl::operator==(const DecimalFormatImpl &other) const {
- if (this == &other) {
- return TRUE;
- }
- return (fMultiplier == other.fMultiplier)
- && (fScale == other.fScale)
- && (fRoundingMode == other.fRoundingMode)
- && (fMinSigDigits == other.fMinSigDigits)
- && (fMaxSigDigits == other.fMaxSigDigits)
- && (fUseScientific == other.fUseScientific)
- && (fUseSigDigits == other.fUseSigDigits)
- && fGrouping.equals(other.fGrouping)
- && fPositivePrefixPattern.equals(other.fPositivePrefixPattern)
- && fNegativePrefixPattern.equals(other.fNegativePrefixPattern)
- && fPositiveSuffixPattern.equals(other.fPositiveSuffixPattern)
- && fNegativeSuffixPattern.equals(other.fNegativeSuffixPattern)
- && fCurrencyUsage == other.fCurrencyUsage
- && fAffixParser.equals(other.fAffixParser)
- && fCurrencyAffixInfo.equals(other.fCurrencyAffixInfo)
- && fEffPrecision.equals(other.fEffPrecision)
- && fEffGrouping.equals(other.fEffGrouping)
- && fOptions.equals(other.fOptions)
- && fFormatter.equals(other.fFormatter)
- && fAffixes.equals(other.fAffixes)
- && (*fSymbols == *other.fSymbols)
- && ((fRules == other.fRules) || (
- (fRules != NULL) && (other.fRules != NULL)
- && (*fRules == *other.fRules)))
- && (fMonetary == other.fMonetary);
-}
-
-DecimalFormatImpl::~DecimalFormatImpl() {
- delete fSymbols;
- delete fRules;
-}
-
-ValueFormatter &
-DecimalFormatImpl::prepareValueFormatter(ValueFormatter &vf) const {
- if (fUseScientific) {
- vf.prepareScientificFormatting(
- fFormatter, fEffPrecision, fOptions);
- return vf;
- }
- vf.prepareFixedDecimalFormatting(
- fFormatter, fEffGrouping, fEffPrecision.fMantissa, fOptions.fMantissa);
- return vf;
-}
-
-int32_t
-DecimalFormatImpl::getPatternScale() const {
- UBool usesPercent = fPositivePrefixPattern.usesPercent() ||
- fPositiveSuffixPattern.usesPercent() ||
- fNegativePrefixPattern.usesPercent() ||
- fNegativeSuffixPattern.usesPercent();
- if (usesPercent) {
- return 2;
- }
- UBool usesPermill = fPositivePrefixPattern.usesPermill() ||
- fPositiveSuffixPattern.usesPermill() ||
- fNegativePrefixPattern.usesPermill() ||
- fNegativeSuffixPattern.usesPermill();
- if (usesPermill) {
- return 3;
- }
- return 0;
-}
-
-void
-DecimalFormatImpl::setMultiplierScale(int32_t scale) {
- if (scale == 0) {
- // Needed to preserve equality. fMultiplier == 0 means
- // multiplier is 1.
- fMultiplier.set((int32_t)0);
- } else {
- fMultiplier.set((int32_t)1);
- fMultiplier.shiftDecimalRight(scale);
- }
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- int32_t number,
- UnicodeString &appendTo,
- FieldPosition &pos,
- UErrorCode &status) const {
- FieldPositionOnlyHandler handler(pos);
- return formatInt32(number, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- int32_t number,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- FieldPositionIteratorHandler handler(posIter, status);
- return formatInt32(number, appendTo, handler, status);
-}
-
-template<class T>
-UBool DecimalFormatImpl::maybeFormatWithDigitList(
- T number,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- if (!fMultiplier.isZero()) {
- DigitList digits;
- digits.set(number);
- digits.mult(fMultiplier, status);
- digits.shiftDecimalRight(fScale);
- formatAdjustedDigitList(digits, appendTo, handler, status);
- return TRUE;
- }
- if (fScale != 0) {
- DigitList digits;
- digits.set(number);
- digits.shiftDecimalRight(fScale);
- formatAdjustedDigitList(digits, appendTo, handler, status);
- return TRUE;
- }
- return FALSE;
-}
-
-template<class T>
-UBool DecimalFormatImpl::maybeInitVisibleDigitsFromDigitList(
- T number,
- VisibleDigitsWithExponent &visibleDigits,
- UErrorCode &status) const {
- if (!fMultiplier.isZero()) {
- DigitList digits;
- digits.set(number);
- digits.mult(fMultiplier, status);
- digits.shiftDecimalRight(fScale);
- initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
- return TRUE;
- }
- if (fScale != 0) {
- DigitList digits;
- digits.set(number);
- digits.shiftDecimalRight(fScale);
- initVisibleDigitsFromAdjusted(digits, visibleDigits, status);
- return TRUE;
- }
- return FALSE;
-}
-
-UnicodeString &
-DecimalFormatImpl::formatInt32(
- int32_t number,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- if (maybeFormatWithDigitList(number, appendTo, handler, status)) {
- return appendTo;
- }
- ValueFormatter vf;
- return fAffixes.formatInt32(
- number,
- prepareValueFormatter(vf),
- handler,
- fRules,
- appendTo,
- status);
-}
-
-UnicodeString &
-DecimalFormatImpl::formatInt64(
- int64_t number,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- if (number >= INT32_MIN && number <= INT32_MAX) {
- return formatInt32((int32_t) number, appendTo, handler, status);
- }
- VisibleDigitsWithExponent digits;
- initVisibleDigitsWithExponent(number, digits, status);
- return formatVisibleDigitsWithExponent(
- digits, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::formatDouble(
- double number,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- VisibleDigitsWithExponent digits;
- initVisibleDigitsWithExponent(number, digits, status);
- return formatVisibleDigitsWithExponent(
- digits, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- double number,
- UnicodeString &appendTo,
- FieldPosition &pos,
- UErrorCode &status) const {
- FieldPositionOnlyHandler handler(pos);
- return formatDouble(number, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- const DigitList &number,
- UnicodeString &appendTo,
- FieldPosition &pos,
- UErrorCode &status) const {
- DigitList dl(number);
- FieldPositionOnlyHandler handler(pos);
- return formatDigitList(dl, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- int64_t number,
- UnicodeString &appendTo,
- FieldPosition &pos,
- UErrorCode &status) const {
- FieldPositionOnlyHandler handler(pos);
- return formatInt64(number, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- int64_t number,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- FieldPositionIteratorHandler handler(posIter, status);
- return formatInt64(number, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- double number,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- FieldPositionIteratorHandler handler(posIter, status);
- return formatDouble(number, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- const DigitList &number,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- DigitList dl(number);
- FieldPositionIteratorHandler handler(posIter, status);
- return formatDigitList(dl, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- StringPiece number,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- DigitList dl;
- dl.set(number, status);
- FieldPositionIteratorHandler handler(posIter, status);
- return formatDigitList(dl, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- const VisibleDigitsWithExponent &digits,
- UnicodeString &appendTo,
- FieldPosition &pos,
- UErrorCode &status) const {
- FieldPositionOnlyHandler handler(pos);
- return formatVisibleDigitsWithExponent(
- digits, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::format(
- const VisibleDigitsWithExponent &digits,
- UnicodeString &appendTo,
- FieldPositionIterator *posIter,
- UErrorCode &status) const {
- FieldPositionIteratorHandler handler(posIter, status);
- return formatVisibleDigitsWithExponent(
- digits, appendTo, handler, status);
-}
-
-DigitList &
-DecimalFormatImpl::adjustDigitList(
- DigitList &number, UErrorCode &status) const {
- number.setRoundingMode(fRoundingMode);
- if (!fMultiplier.isZero()) {
- number.mult(fMultiplier, status);
- }
- if (fScale != 0) {
- number.shiftDecimalRight(fScale);
- }
- number.reduce();
- return number;
-}
-
-UnicodeString &
-DecimalFormatImpl::formatDigitList(
- DigitList &number,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- VisibleDigitsWithExponent digits;
- initVisibleDigitsWithExponent(number, digits, status);
- return formatVisibleDigitsWithExponent(
- digits, appendTo, handler, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::formatAdjustedDigitList(
- DigitList &number,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- ValueFormatter vf;
- return fAffixes.format(
- number,
- prepareValueFormatter(vf),
- handler,
- fRules,
- appendTo,
- status);
-}
-
-UnicodeString &
-DecimalFormatImpl::formatVisibleDigitsWithExponent(
- const VisibleDigitsWithExponent &digits,
- UnicodeString &appendTo,
- FieldPositionHandler &handler,
- UErrorCode &status) const {
- ValueFormatter vf;
- return fAffixes.format(
- digits,
- prepareValueFormatter(vf),
- handler,
- fRules,
- appendTo,
- status);
-}
-
-static FixedDecimal &initFixedDecimal(
- const VisibleDigits &digits, FixedDecimal &result) {
- result.source = 0.0;
- result.isNegative = digits.isNegative();
- result._isNaN = digits.isNaN();
- result._isInfinite = digits.isInfinite();
- digits.getFixedDecimal(
- result.source, result.intValue, result.decimalDigits,
- result.decimalDigitsWithoutTrailingZeros,
- result.visibleDecimalDigitCount, result.hasIntegerValue);
- return result;
-}
-
-FixedDecimal &
-DecimalFormatImpl::getFixedDecimal(double number, FixedDecimal &result, UErrorCode &status) const {
- if (U_FAILURE(status)) {
- return result;
- }
- VisibleDigits digits;
- fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
- return initFixedDecimal(digits, result);
-}
-
-FixedDecimal &
-DecimalFormatImpl::getFixedDecimal(
- DigitList &number, FixedDecimal &result, UErrorCode &status) const {
- if (U_FAILURE(status)) {
- return result;
- }
- VisibleDigits digits;
- fEffPrecision.fMantissa.initVisibleDigits(number, digits, status);
- return initFixedDecimal(digits, result);
-}
-
-VisibleDigitsWithExponent &
-DecimalFormatImpl::initVisibleDigitsWithExponent(
- int64_t number,
- VisibleDigitsWithExponent &digits,
- UErrorCode &status) const {
- if (maybeInitVisibleDigitsFromDigitList(
- number, digits, status)) {
- return digits;
- }
- if (fUseScientific) {
- fEffPrecision.initVisibleDigitsWithExponent(
- number, digits, status);
- } else {
- fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
- number, digits, status);
- }
- return digits;
-}
-
-VisibleDigitsWithExponent &
-DecimalFormatImpl::initVisibleDigitsWithExponent(
- double number,
- VisibleDigitsWithExponent &digits,
- UErrorCode &status) const {
- if (maybeInitVisibleDigitsFromDigitList(
- number, digits, status)) {
- return digits;
- }
- if (fUseScientific) {
- fEffPrecision.initVisibleDigitsWithExponent(
- number, digits, status);
- } else {
- fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
- number, digits, status);
- }
- return digits;
-}
-
-VisibleDigitsWithExponent &
-DecimalFormatImpl::initVisibleDigitsWithExponent(
- DigitList &number,
- VisibleDigitsWithExponent &digits,
- UErrorCode &status) const {
- adjustDigitList(number, status);
- return initVisibleDigitsFromAdjusted(number, digits, status);
-}
-
-VisibleDigitsWithExponent &
-DecimalFormatImpl::initVisibleDigitsFromAdjusted(
- DigitList &number,
- VisibleDigitsWithExponent &digits,
- UErrorCode &status) const {
- if (fUseScientific) {
- fEffPrecision.initVisibleDigitsWithExponent(
- number, digits, status);
- } else {
- fEffPrecision.fMantissa.initVisibleDigitsWithExponent(
- number, digits, status);
- }
- return digits;
-}
-
-DigitList &
-DecimalFormatImpl::round(
- DigitList &number, UErrorCode &status) const {
- if (number.isNaN() || number.isInfinite()) {
- return number;
- }
- adjustDigitList(number, status);
- ValueFormatter vf;
- prepareValueFormatter(vf);
- return vf.round(number, status);
-}
-
-void
-DecimalFormatImpl::setMinimumSignificantDigits(int32_t newValue) {
- fMinSigDigits = newValue;
- fUseSigDigits = TRUE; // ticket 9936
- updatePrecision();
-}
-
-void
-DecimalFormatImpl::setMaximumSignificantDigits(int32_t newValue) {
- fMaxSigDigits = newValue;
- fUseSigDigits = TRUE; // ticket 9936
- updatePrecision();
-}
-
-void
-DecimalFormatImpl::setMinMaxSignificantDigits(int32_t min, int32_t max) {
- fMinSigDigits = min;
- fMaxSigDigits = max;
- fUseSigDigits = TRUE; // ticket 9936
- updatePrecision();
-}
-
-void
-DecimalFormatImpl::setScientificNotation(UBool newValue) {
- fUseScientific = newValue;
- updatePrecision();
-}
-
-void
-DecimalFormatImpl::setSignificantDigitsUsed(UBool newValue) {
- fUseSigDigits = newValue;
- updatePrecision();
-}
-
-void
-DecimalFormatImpl::setGroupingSize(int32_t newValue) {
- fGrouping.fGrouping = newValue;
- updateGrouping();
-}
-
-void
-DecimalFormatImpl::setSecondaryGroupingSize(int32_t newValue) {
- fGrouping.fGrouping2 = newValue;
- updateGrouping();
-}
-
-void
-DecimalFormatImpl::setMinimumGroupingDigits(int32_t newValue) {
- fGrouping.fMinGrouping = newValue;
- updateGrouping();
-}
-
-void
-DecimalFormatImpl::setCurrencyUsage(
- UCurrencyUsage currencyUsage, UErrorCode &status) {
- fCurrencyUsage = currencyUsage;
- updateFormatting(kFormattingCurrency, status);
-}
-
-void
-DecimalFormatImpl::setRoundingIncrement(double d) {
- if (d > 0.0) {
- fEffPrecision.fMantissa.fRoundingIncrement.set(d);
- } else {
- fEffPrecision.fMantissa.fRoundingIncrement.set(0.0);
- }
-}
-
-double
-DecimalFormatImpl::getRoundingIncrement() const {
- return fEffPrecision.fMantissa.fRoundingIncrement.getDouble();
-}
-
-int32_t
-DecimalFormatImpl::getMultiplier() const {
- if (fMultiplier.isZero()) {
- return 1;
- }
- return (int32_t) fMultiplier.getDouble();
-}
-
-void
-DecimalFormatImpl::setMultiplier(int32_t m) {
- if (m == 0 || m == 1) {
- fMultiplier.set((int32_t)0);
- } else {
- fMultiplier.set(m);
- }
-}
-
-void
-DecimalFormatImpl::setPositivePrefix(const UnicodeString &str) {
- fPositivePrefixPattern.remove();
- fPositivePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
- UErrorCode status = U_ZERO_ERROR;
- updateFormatting(kFormattingPosPrefix, status);
-}
-
-void
-DecimalFormatImpl::setPositiveSuffix(const UnicodeString &str) {
- fPositiveSuffixPattern.remove();
- fPositiveSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
- UErrorCode status = U_ZERO_ERROR;
- updateFormatting(kFormattingPosSuffix, status);
-}
-
-void
-DecimalFormatImpl::setNegativePrefix(const UnicodeString &str) {
- fNegativePrefixPattern.remove();
- fNegativePrefixPattern.addLiteral(str.getBuffer(), 0, str.length());
- UErrorCode status = U_ZERO_ERROR;
- updateFormatting(kFormattingNegPrefix, status);
-}
-
-void
-DecimalFormatImpl::setNegativeSuffix(const UnicodeString &str) {
- fNegativeSuffixPattern.remove();
- fNegativeSuffixPattern.addLiteral(str.getBuffer(), 0, str.length());
- UErrorCode status = U_ZERO_ERROR;
- updateFormatting(kFormattingNegSuffix, status);
-}
-
-UnicodeString &
-DecimalFormatImpl::getPositivePrefix(UnicodeString &result) const {
- result = fAffixes.fPositivePrefix.getOtherVariant().toString();
- return result;
-}
-
-UnicodeString &
-DecimalFormatImpl::getPositiveSuffix(UnicodeString &result) const {
- result = fAffixes.fPositiveSuffix.getOtherVariant().toString();
- return result;
-}
-
-UnicodeString &
-DecimalFormatImpl::getNegativePrefix(UnicodeString &result) const {
- result = fAffixes.fNegativePrefix.getOtherVariant().toString();
- return result;
-}
-
-UnicodeString &
-DecimalFormatImpl::getNegativeSuffix(UnicodeString &result) const {
- result = fAffixes.fNegativeSuffix.getOtherVariant().toString();
- return result;
-}
-
-void
-DecimalFormatImpl::adoptDecimalFormatSymbols(DecimalFormatSymbols *symbolsToAdopt) {
- if (symbolsToAdopt == NULL) {
- return;
- }
- delete fSymbols;
- fSymbols = symbolsToAdopt;
- UErrorCode status = U_ZERO_ERROR;
- updateFormatting(kFormattingSymbols, status);
-}
-
-void
-DecimalFormatImpl::applyPatternFavorCurrencyPrecision(
- const UnicodeString &pattern, UErrorCode &status) {
- UParseError perror;
- applyPattern(pattern, FALSE, perror, status);
- updateForApplyPatternFavorCurrencyPrecision(status);
-}
-
-void
-DecimalFormatImpl::applyPattern(
- const UnicodeString &pattern, UErrorCode &status) {
- UParseError perror;
- applyPattern(pattern, FALSE, perror, status);
- updateForApplyPattern(status);
-}
-
-void
-DecimalFormatImpl::applyPattern(
- const UnicodeString &pattern,
- UParseError &perror, UErrorCode &status) {
- applyPattern(pattern, FALSE, perror, status);
- updateForApplyPattern(status);
-}
-
-void
-DecimalFormatImpl::applyLocalizedPattern(
- const UnicodeString &pattern, UErrorCode &status) {
- UParseError perror;
- applyPattern(pattern, TRUE, perror, status);
- updateForApplyPattern(status);
-}
-
-void
-DecimalFormatImpl::applyLocalizedPattern(
- const UnicodeString &pattern,
- UParseError &perror, UErrorCode &status) {
- applyPattern(pattern, TRUE, perror, status);
- updateForApplyPattern(status);
-}
-
-void
-DecimalFormatImpl::applyPattern(
- const UnicodeString &pattern,
- UBool localized, UParseError &perror, UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- DecimalFormatPatternParser patternParser;
- if (localized) {
- patternParser.useSymbols(*fSymbols);
- }
- DecimalFormatPattern out;
- patternParser.applyPatternWithoutExpandAffix(
- pattern, out, perror, status);
- if (U_FAILURE(status)) {
- return;
- }
- fUseScientific = out.fUseExponentialNotation;
- fUseSigDigits = out.fUseSignificantDigits;
- fSuper->NumberFormat::setMinimumIntegerDigits(out.fMinimumIntegerDigits);
- fSuper->NumberFormat::setMaximumIntegerDigits(out.fMaximumIntegerDigits);
- fSuper->NumberFormat::setMinimumFractionDigits(out.fMinimumFractionDigits);
- fSuper->NumberFormat::setMaximumFractionDigits(out.fMaximumFractionDigits);
- fMinSigDigits = out.fMinimumSignificantDigits;
- fMaxSigDigits = out.fMaximumSignificantDigits;
- fEffPrecision.fMinExponentDigits = out.fMinExponentDigits;
- fOptions.fExponent.fAlwaysShowSign = out.fExponentSignAlwaysShown;
- fSuper->NumberFormat::setGroupingUsed(out.fGroupingUsed);
- fGrouping.fGrouping = out.fGroupingSize;
- fGrouping.fGrouping2 = out.fGroupingSize2;
- fOptions.fMantissa.fAlwaysShowDecimal = out.fDecimalSeparatorAlwaysShown;
- if (out.fRoundingIncrementUsed) {
- fEffPrecision.fMantissa.fRoundingIncrement = out.fRoundingIncrement;
- } else {
- fEffPrecision.fMantissa.fRoundingIncrement.clear();
- }
- fAffixes.fPadChar = out.fPad;
- fNegativePrefixPattern = out.fNegPrefixAffix;
- fNegativeSuffixPattern = out.fNegSuffixAffix;
- fPositivePrefixPattern = out.fPosPrefixAffix;
- fPositiveSuffixPattern = out.fPosSuffixAffix;
-
- // Work around. Pattern parsing code and DecimalFormat code don't agree
- // on the definition of field width, so we have to translate from
- // pattern field width to decimal format field width here.
- fAffixes.fWidth = out.fFormatWidth == 0 ? 0 :
- out.fFormatWidth + fPositivePrefixPattern.countChar32()
- + fPositiveSuffixPattern.countChar32();
- switch (out.fPadPosition) {
- case DecimalFormatPattern::kPadBeforePrefix:
- fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforePrefix;
- break;
- case DecimalFormatPattern::kPadAfterPrefix:
- fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterPrefix;
- break;
- case DecimalFormatPattern::kPadBeforeSuffix:
- fAffixes.fPadPosition = DigitAffixesAndPadding::kPadBeforeSuffix;
- break;
- case DecimalFormatPattern::kPadAfterSuffix:
- fAffixes.fPadPosition = DigitAffixesAndPadding::kPadAfterSuffix;
- break;
- default:
- break;
- }
-}
-
-void
-DecimalFormatImpl::updatePrecision() {
- if (fUseScientific) {
- updatePrecisionForScientific();
- } else {
- updatePrecisionForFixed();
- }
-}
-
-static void updatePrecisionForScientificMinMax(
- const DigitInterval &min,
- const DigitInterval &max,
- DigitInterval &resultMin,
- DigitInterval &resultMax,
- SignificantDigitInterval &resultSignificant) {
- resultMin.setIntDigitCount(0);
- resultMin.setFracDigitCount(0);
- resultSignificant.clear();
- resultMax.clear();
-
- int32_t maxIntDigitCount = max.getIntDigitCount();
- int32_t minIntDigitCount = min.getIntDigitCount();
- int32_t maxFracDigitCount = max.getFracDigitCount();
- int32_t minFracDigitCount = min.getFracDigitCount();
-
-
- // Not in spec: maxIntDigitCount > 8 assume
- // maxIntDigitCount = minIntDigitCount. Current DecimalFormat API has
- // no provision for unsetting maxIntDigitCount which would be useful for
- // scientific notation. The best we can do is assume that if
- // maxIntDigitCount is the default of 2000000000 or is "big enough" then
- // user did not intend to explicitly set it. The 8 was derived emperically
- // by extensive testing of legacy code.
- if (maxIntDigitCount > 8) {
- maxIntDigitCount = minIntDigitCount;
- }
-
- // Per the spec, exponent grouping happens if maxIntDigitCount is more
- // than 1 and more than minIntDigitCount.
- UBool bExponentGrouping = maxIntDigitCount > 1 && minIntDigitCount < maxIntDigitCount;
- if (bExponentGrouping) {
- resultMax.setIntDigitCount(maxIntDigitCount);
-
- // For exponent grouping minIntDigits is always treated as 1 even
- // if it wasn't set to 1!
- resultMin.setIntDigitCount(1);
- } else {
- // Fixed digit count left of decimal. minIntDigitCount doesn't have
- // to equal maxIntDigitCount i.e minIntDigitCount == 0 while
- // maxIntDigitCount == 1.
- int32_t fixedIntDigitCount = maxIntDigitCount;
-
- // If fixedIntDigitCount is 0 but
- // min or max fraction count is 0 too then use 1. This way we can get
- // unlimited precision for X.XXXEX
- if (fixedIntDigitCount == 0 && (minFracDigitCount == 0 || maxFracDigitCount == 0)) {
- fixedIntDigitCount = 1;
- }
- resultMax.setIntDigitCount(fixedIntDigitCount);
- resultMin.setIntDigitCount(fixedIntDigitCount);
- }
- // Spec says this is how we compute significant digits. 0 means
- // unlimited significant digits.
- int32_t maxSigDigits = minIntDigitCount + maxFracDigitCount;
- if (maxSigDigits > 0) {
- int32_t minSigDigits = minIntDigitCount + minFracDigitCount;
- resultSignificant.setMin(minSigDigits);
- resultSignificant.setMax(maxSigDigits);
- }
-}
-
-void
-DecimalFormatImpl::updatePrecisionForScientific() {
- FixedPrecision *result = &fEffPrecision.fMantissa;
- if (fUseSigDigits) {
- result->fMax.setFracDigitCount(-1);
- result->fMax.setIntDigitCount(1);
- result->fMin.setFracDigitCount(0);
- result->fMin.setIntDigitCount(1);
- result->fSignificant.clear();
- extractSigDigits(result->fSignificant);
- return;
- }
- DigitInterval max;
- DigitInterval min;
- extractMinMaxDigits(min, max);
- updatePrecisionForScientificMinMax(
- min, max,
- result->fMin, result->fMax, result->fSignificant);
-}
-
-void
-DecimalFormatImpl::updatePrecisionForFixed() {
- FixedPrecision *result = &fEffPrecision.fMantissa;
- if (!fUseSigDigits) {
- extractMinMaxDigits(result->fMin, result->fMax);
- result->fSignificant.clear();
- } else {
- extractSigDigits(result->fSignificant);
- result->fMin.setIntDigitCount(1);
- result->fMin.setFracDigitCount(0);
- result->fMax.clear();
- }
-}
-
-void
- DecimalFormatImpl::extractMinMaxDigits(
- DigitInterval &min, DigitInterval &max) const {
- min.setIntDigitCount(fSuper->getMinimumIntegerDigits());
- max.setIntDigitCount(fSuper->getMaximumIntegerDigits());
- min.setFracDigitCount(fSuper->getMinimumFractionDigits());
- max.setFracDigitCount(fSuper->getMaximumFractionDigits());
-}
-
-void
- DecimalFormatImpl::extractSigDigits(
- SignificantDigitInterval &sig) const {
- sig.setMin(fMinSigDigits < 0 ? 0 : fMinSigDigits);
- sig.setMax(fMaxSigDigits < 0 ? 0 : fMaxSigDigits);
-}
-
-void
-DecimalFormatImpl::updateGrouping() {
- if (fSuper->isGroupingUsed()) {
- fEffGrouping = fGrouping;
- } else {
- fEffGrouping.clear();
- }
-}
-
-void
-DecimalFormatImpl::updateCurrency(UErrorCode &status) {
- updateFormatting(kFormattingCurrency, TRUE, status);
-}
-
-void
-DecimalFormatImpl::updateFormatting(
- int32_t changedFormattingFields,
- UErrorCode &status) {
- updateFormatting(changedFormattingFields, TRUE, status);
-}
-
-void
-DecimalFormatImpl::updateFormatting(
- int32_t changedFormattingFields,
- UBool updatePrecisionBasedOnCurrency,
- UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- // Each function updates one field. Order matters. For instance,
- // updatePluralRules comes before updateCurrencyAffixInfo because the
- // fRules field is needed to update the fCurrencyAffixInfo field.
- updateFormattingUsesCurrency(changedFormattingFields);
- updateFormattingFixedPointFormatter(changedFormattingFields);
- updateFormattingAffixParser(changedFormattingFields);
- updateFormattingPluralRules(changedFormattingFields, status);
- updateFormattingCurrencyAffixInfo(
- changedFormattingFields,
- updatePrecisionBasedOnCurrency,
- status);
- updateFormattingLocalizedPositivePrefix(
- changedFormattingFields, status);
- updateFormattingLocalizedPositiveSuffix(
- changedFormattingFields, status);
- updateFormattingLocalizedNegativePrefix(
- changedFormattingFields, status);
- updateFormattingLocalizedNegativeSuffix(
- changedFormattingFields, status);
-}
-
-void
-DecimalFormatImpl::updateFormattingUsesCurrency(
- int32_t &changedFormattingFields) {
- if ((changedFormattingFields & kFormattingAffixes) == 0) {
- // If no affixes changed, don't need to do any work
- return;
- }
- UBool newUsesCurrency =
- fPositivePrefixPattern.usesCurrency() ||
- fPositiveSuffixPattern.usesCurrency() ||
- fNegativePrefixPattern.usesCurrency() ||
- fNegativeSuffixPattern.usesCurrency();
- if (fMonetary != newUsesCurrency) {
- fMonetary = newUsesCurrency;
- changedFormattingFields |= kFormattingUsesCurrency;
- }
-}
-
-void
-DecimalFormatImpl::updateFormattingPluralRules(
- int32_t &changedFormattingFields, UErrorCode &status) {
- if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
- // No work to do if both fSymbols and fMonetary
- // fields are unchanged
- return;
- }
- if (U_FAILURE(status)) {
- return;
- }
- PluralRules *newRules = NULL;
- if (fMonetary) {
- newRules = PluralRules::forLocale(fSymbols->getLocale(), status);
- if (U_FAILURE(status)) {
- return;
- }
- }
- // Its ok to say a field has changed when it really hasn't but not
- // the other way around. Here we assume the field changed unless it
- // was NULL before and is still NULL now
- if (fRules != newRules) {
- delete fRules;
- fRules = newRules;
- changedFormattingFields |= kFormattingPluralRules;
- }
-}
-
-void
-DecimalFormatImpl::updateFormattingCurrencyAffixInfo(
- int32_t &changedFormattingFields,
- UBool updatePrecisionBasedOnCurrency,
- UErrorCode &status) {
- if ((changedFormattingFields & (
- kFormattingSymbols | kFormattingCurrency |
- kFormattingUsesCurrency | kFormattingPluralRules)) == 0) {
- // If all these fields are unchanged, no work to do.
- return;
- }
- if (U_FAILURE(status)) {
- return;
- }
- if (!fMonetary) {
- if (fCurrencyAffixInfo.isDefault()) {
- // In this case don't have to do any work
- return;
- }
- fCurrencyAffixInfo.set(NULL, NULL, NULL, status);
- if (U_FAILURE(status)) {
- return;
- }
- changedFormattingFields |= kFormattingCurrencyAffixInfo;
- } else {
- const UChar *currency = fSuper->getCurrency();
- UChar localeCurr[4];
- if (currency[0] == 0) {
- ucurr_forLocale(fSymbols->getLocale().getName(), localeCurr, UPRV_LENGTHOF(localeCurr), &status);
- if (U_SUCCESS(status)) {
- currency = localeCurr;
- fSuper->NumberFormat::setCurrency(currency, status);
- } else {
- currency = NULL;
- status = U_ZERO_ERROR;
- }
- }
- fCurrencyAffixInfo.set(
- fSymbols->getLocale().getName(), fRules, currency, status);
- if (U_FAILURE(status)) {
- return;
- }
- UBool customCurrencySymbol = FALSE;
- // If DecimalFormatSymbols has custom currency symbol, prefer
- // that over what we just read from the resource bundles
- if (fSymbols->isCustomCurrencySymbol()) {
- fCurrencyAffixInfo.setSymbol(
- fSymbols->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol));
- customCurrencySymbol = TRUE;
- }
- if (fSymbols->isCustomIntlCurrencySymbol()) {
- fCurrencyAffixInfo.setISO(
- fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol));
- customCurrencySymbol = TRUE;
- }
- changedFormattingFields |= kFormattingCurrencyAffixInfo;
- if (currency && !customCurrencySymbol && updatePrecisionBasedOnCurrency) {
- FixedPrecision precision;
- CurrencyAffixInfo::adjustPrecision(
- currency, fCurrencyUsage, precision, status);
- if (U_FAILURE(status)) {
- return;
- }
- fSuper->NumberFormat::setMinimumFractionDigits(
- precision.fMin.getFracDigitCount());
- fSuper->NumberFormat::setMaximumFractionDigits(
- precision.fMax.getFracDigitCount());
- updatePrecision();
- fEffPrecision.fMantissa.fRoundingIncrement =
- precision.fRoundingIncrement;
- }
-
- }
-}
-
-void
-DecimalFormatImpl::updateFormattingFixedPointFormatter(
- int32_t &changedFormattingFields) {
- if ((changedFormattingFields & (kFormattingSymbols | kFormattingUsesCurrency)) == 0) {
- // No work to do if fSymbols is unchanged
- return;
- }
- if (fMonetary) {
- fFormatter.setDecimalFormatSymbolsForMonetary(*fSymbols);
- } else {
- fFormatter.setDecimalFormatSymbols(*fSymbols);
- }
-}
-
-void
-DecimalFormatImpl::updateFormattingAffixParser(
- int32_t &changedFormattingFields) {
- if ((changedFormattingFields & kFormattingSymbols) == 0) {
- // No work to do if fSymbols is unchanged
- return;
- }
- fAffixParser.setDecimalFormatSymbols(*fSymbols);
- changedFormattingFields |= kFormattingAffixParser;
-}
-
-void
-DecimalFormatImpl::updateFormattingLocalizedPositivePrefix(
- int32_t &changedFormattingFields, UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- if ((changedFormattingFields & (
- kFormattingPosPrefix | kFormattingAffixParserWithCurrency)) == 0) {
- // No work to do
- return;
- }
- fAffixes.fPositivePrefix.remove();
- fAffixParser.parse(
- fPositivePrefixPattern,
- fCurrencyAffixInfo,
- fAffixes.fPositivePrefix,
- status);
-}
-
-void
-DecimalFormatImpl::updateFormattingLocalizedPositiveSuffix(
- int32_t &changedFormattingFields, UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- if ((changedFormattingFields & (
- kFormattingPosSuffix | kFormattingAffixParserWithCurrency)) == 0) {
- // No work to do
- return;
- }
- fAffixes.fPositiveSuffix.remove();
- fAffixParser.parse(
- fPositiveSuffixPattern,
- fCurrencyAffixInfo,
- fAffixes.fPositiveSuffix,
- status);
-}
-
-void
-DecimalFormatImpl::updateFormattingLocalizedNegativePrefix(
- int32_t &changedFormattingFields, UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- if ((changedFormattingFields & (
- kFormattingNegPrefix | kFormattingAffixParserWithCurrency)) == 0) {
- // No work to do
- return;
- }
- fAffixes.fNegativePrefix.remove();
- fAffixParser.parse(
- fNegativePrefixPattern,
- fCurrencyAffixInfo,
- fAffixes.fNegativePrefix,
- status);
-}
-
-void
-DecimalFormatImpl::updateFormattingLocalizedNegativeSuffix(
- int32_t &changedFormattingFields, UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- if ((changedFormattingFields & (
- kFormattingNegSuffix | kFormattingAffixParserWithCurrency)) == 0) {
- // No work to do
- return;
- }
- fAffixes.fNegativeSuffix.remove();
- fAffixParser.parse(
- fNegativeSuffixPattern,
- fCurrencyAffixInfo,
- fAffixes.fNegativeSuffix,
- status);
-}
-
-void
-DecimalFormatImpl::updateForApplyPatternFavorCurrencyPrecision(
- UErrorCode &status) {
- updateAll(kFormattingAll & ~kFormattingSymbols, TRUE, status);
-}
-
-void
-DecimalFormatImpl::updateForApplyPattern(UErrorCode &status) {
- updateAll(kFormattingAll & ~kFormattingSymbols, FALSE, status);
-}
-
-void
-DecimalFormatImpl::updateAll(UErrorCode &status) {
- updateAll(kFormattingAll, TRUE, status);
-}
-
-void
-DecimalFormatImpl::updateAll(
- int32_t formattingFlags,
- UBool updatePrecisionBasedOnCurrency,
- UErrorCode &status) {
- if (U_FAILURE(status)) {
- return;
- }
- updatePrecision();
- updateGrouping();
- updateFormatting(
- formattingFlags, updatePrecisionBasedOnCurrency, status);
- setMultiplierScale(getPatternScale());
-}
-
-
-static int32_t
-getMinimumLengthToDescribeGrouping(const DigitGrouping &grouping) {
- if (grouping.fGrouping <= 0) {
- return 0;
- }
- if (grouping.fGrouping2 <= 0) {
- return grouping.fGrouping + 1;
- }
- return grouping.fGrouping + grouping.fGrouping2 + 1;
-}
-
-/**
- * Given a grouping policy, calculates how many digits are needed left of
- * the decimal point to achieve a desired length left of the
- * decimal point.
- * @param grouping the grouping policy
- * @param desiredLength number of characters needed left of decimal point
- * @param minLeftDigits at least this many digits is returned
- * @param leftDigits the number of digits needed stored here
- * which is >= minLeftDigits.
- * @return true if a perfect fit or false if having leftDigits would exceed
- * desiredLength
- */
-static UBool
-getLeftDigitsForLeftLength(
- const DigitGrouping &grouping,
- int32_t desiredLength,
- int32_t minLeftDigits,
- int32_t &leftDigits) {
- leftDigits = minLeftDigits;
- int32_t lengthSoFar = leftDigits + grouping.getSeparatorCount(leftDigits);
- while (lengthSoFar < desiredLength) {
- lengthSoFar += grouping.isSeparatorAt(leftDigits + 1, leftDigits) ? 2 : 1;
- ++leftDigits;
- }
- return (lengthSoFar == desiredLength);
-}
-
-int32_t
-DecimalFormatImpl::computeExponentPatternLength() const {
- if (fUseScientific) {
- return 1 + (fOptions.fExponent.fAlwaysShowSign ? 1 : 0) + fEffPrecision.fMinExponentDigits;
- }
- return 0;
-}
-
-int32_t
-DecimalFormatImpl::countFractionDigitAndDecimalPatternLength(
- int32_t fracDigitCount) const {
- if (!fOptions.fMantissa.fAlwaysShowDecimal && fracDigitCount == 0) {
- return 0;
- }
- return fracDigitCount + 1;
-}
-
-UnicodeString&
-DecimalFormatImpl::toNumberPattern(
- UBool hasPadding, int32_t minimumLength, UnicodeString& result) const {
- // Get a grouping policy like the one in this object that does not
- // have minimum grouping since toPattern doesn't support it.
- DigitGrouping grouping(fEffGrouping);
- grouping.fMinGrouping = 0;
-
- // Only for fixed digits, these are the digits that get 0's.
- DigitInterval minInterval;
-
- // Only for fixed digits, these are the digits that get #'s.
- DigitInterval maxInterval;
-
- // Only for significant digits
- int32_t sigMin = 0; /* initialize to avoid compiler warning */
- int32_t sigMax = 0; /* initialize to avoid compiler warning */
-
- // These are all the digits to be displayed. For significant digits,
- // this interval always starts at the 1's place an extends left.
- DigitInterval fullInterval;
-
- // Digit range of rounding increment. If rounding increment is .025.
- // then roundingIncrementLowerExp = -3 and roundingIncrementUpperExp = -1
- int32_t roundingIncrementLowerExp = 0;
- int32_t roundingIncrementUpperExp = 0;
-
- if (fUseSigDigits) {
- SignificantDigitInterval sigInterval;
- extractSigDigits(sigInterval);
- sigMax = sigInterval.getMax();
- sigMin = sigInterval.getMin();
- fullInterval.setFracDigitCount(0);
- fullInterval.setIntDigitCount(sigMax);
- } else {
- extractMinMaxDigits(minInterval, maxInterval);
- if (fUseScientific) {
- if (maxInterval.getIntDigitCount() > kMaxScientificIntegerDigits) {
- maxInterval.setIntDigitCount(1);
- minInterval.shrinkToFitWithin(maxInterval);
- }
- } else if (hasPadding) {
- // Make max int digits match min int digits for now, we
- // compute necessary padding later.
- maxInterval.setIntDigitCount(minInterval.getIntDigitCount());
- } else {
- // For some reason toPattern adds at least one leading '#'
- maxInterval.setIntDigitCount(minInterval.getIntDigitCount() + 1);
- }
- if (!fEffPrecision.fMantissa.fRoundingIncrement.isZero()) {
- roundingIncrementLowerExp =
- fEffPrecision.fMantissa.fRoundingIncrement.getLowerExponent();
- roundingIncrementUpperExp =
- fEffPrecision.fMantissa.fRoundingIncrement.getUpperExponent();
- // We have to include the rounding increment in what we display
- maxInterval.expandToContainDigit(roundingIncrementLowerExp);
- maxInterval.expandToContainDigit(roundingIncrementUpperExp - 1);
- }
- fullInterval = maxInterval;
- }
- // We have to include enough digits to show grouping strategy
- int32_t minLengthToDescribeGrouping =
- getMinimumLengthToDescribeGrouping(grouping);
- if (minLengthToDescribeGrouping > 0) {
- fullInterval.expandToContainDigit(
- getMinimumLengthToDescribeGrouping(grouping) - 1);
- }
-
- // If we have a minimum length, we have to add digits to the left to
- // depict padding.
- if (hasPadding) {
- // For non scientific notation,
- // minimumLengthForMantissa = minimumLength
- int32_t minimumLengthForMantissa =
- minimumLength - computeExponentPatternLength();
- int32_t mininumLengthForMantissaIntPart =
- minimumLengthForMantissa
- - countFractionDigitAndDecimalPatternLength(
- fullInterval.getFracDigitCount());
- // Because of grouping, we may need fewer than expected digits to
- // achieve the length we need.
- int32_t digitsNeeded;
- if (getLeftDigitsForLeftLength(
- grouping,
- mininumLengthForMantissaIntPart,
- fullInterval.getIntDigitCount(),
- digitsNeeded)) {
-
- // In this case, we achieved the exact length that we want.
- fullInterval.setIntDigitCount(digitsNeeded);
- } else if (digitsNeeded > fullInterval.getIntDigitCount()) {
-
- // Having digitsNeeded digits goes over desired length which
- // means that to have desired length would mean starting on a
- // grouping sepearator e.g ,###,### so add a '#' and use one
- // less digit. This trick gives ####,### but that is the best
- // we can do.
- result.append(kPatternDigit);
- fullInterval.setIntDigitCount(digitsNeeded - 1);
- }
- }
- int32_t maxDigitPos = fullInterval.getMostSignificantExclusive();
- int32_t minDigitPos = fullInterval.getLeastSignificantInclusive();
- for (int32_t i = maxDigitPos - 1; i >= minDigitPos; --i) {
- if (!fOptions.fMantissa.fAlwaysShowDecimal && i == -1) {
- result.append(kPatternDecimalSeparator);
- }
- if (fUseSigDigits) {
- // Use digit symbol
- if (i >= sigMax || i < sigMax - sigMin) {
- result.append(kPatternDigit);
- } else {
- result.append(kPatternSignificantDigit);
- }
- } else {
- if (i < roundingIncrementUpperExp && i >= roundingIncrementLowerExp) {
- result.append((UChar)(fEffPrecision.fMantissa.fRoundingIncrement.getDigitByExponent(i) + kPatternZeroDigit));
- } else if (minInterval.contains(i)) {
- result.append(kPatternZeroDigit);
- } else {
- result.append(kPatternDigit);
- }
- }
- if (grouping.isSeparatorAt(i + 1, i)) {
- result.append(kPatternGroupingSeparator);
- }
- if (fOptions.fMantissa.fAlwaysShowDecimal && i == 0) {
- result.append(kPatternDecimalSeparator);
- }
- }
- if (fUseScientific) {
- result.append(kPatternExponent);
- if (fOptions.fExponent.fAlwaysShowSign) {
- result.append(kPatternPlus);
- }
- for (int32_t i = 0; i < 1 || i < fEffPrecision.fMinExponentDigits; ++i) {
- result.append(kPatternZeroDigit);
- }
- }
- return result;
-}
-
-UnicodeString&
-DecimalFormatImpl::toPattern(UnicodeString& result) const {
- result.remove();
- UnicodeString padSpec;
- if (fAffixes.fWidth > 0) {
- padSpec.append(kPatternPadEscape);
- padSpec.append(fAffixes.fPadChar);
- }
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
- result.append(padSpec);
- }
- fPositivePrefixPattern.toUserString(result);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
- result.append(padSpec);
- }
- toNumberPattern(
- fAffixes.fWidth > 0,
- fAffixes.fWidth - fPositivePrefixPattern.countChar32() - fPositiveSuffixPattern.countChar32(),
- result);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
- result.append(padSpec);
- }
- fPositiveSuffixPattern.toUserString(result);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
- result.append(padSpec);
- }
- AffixPattern withNegative;
- withNegative.add(AffixPattern::kNegative);
- withNegative.append(fPositivePrefixPattern);
- if (!fPositiveSuffixPattern.equals(fNegativeSuffixPattern) ||
- !withNegative.equals(fNegativePrefixPattern)) {
- result.append(kPatternSeparator);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) {
- result.append(padSpec);
- }
- fNegativePrefixPattern.toUserString(result);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) {
- result.append(padSpec);
- }
- toNumberPattern(
- fAffixes.fWidth > 0,
- fAffixes.fWidth - fNegativePrefixPattern.countChar32() - fNegativeSuffixPattern.countChar32(),
- result);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) {
- result.append(padSpec);
- }
- fNegativeSuffixPattern.toUserString(result);
- if (fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) {
- result.append(padSpec);
- }
- }
- return result;
-}
-
-int32_t
-DecimalFormatImpl::getOldFormatWidth() const {
- if (fAffixes.fWidth == 0) {
- return 0;
- }
- return fAffixes.fWidth - fPositiveSuffixPattern.countChar32() - fPositivePrefixPattern.countChar32();
-}
-
-const UnicodeString &
-DecimalFormatImpl::getConstSymbol(
- DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
- return fSymbols->getConstSymbol(symbol);
-}
-
-UBool
-DecimalFormatImpl::isParseFastpath() const {
- AffixPattern negative;
- negative.add(AffixPattern::kNegative);
-
- return fAffixes.fWidth == 0 &&
- fPositivePrefixPattern.countChar32() == 0 &&
- fNegativePrefixPattern.equals(negative) &&
- fPositiveSuffixPattern.countChar32() == 0 &&
- fNegativeSuffixPattern.countChar32() == 0;
-}
-
-
-U_NAMESPACE_END
-
-#endif /* #if !UCONFIG_NO_FORMATTING */