diff options
Diffstat (limited to 'deps/icu-small/source/i18n/decimfmtimpl.cpp')
-rw-r--r-- | deps/icu-small/source/i18n/decimfmtimpl.cpp | 1596 |
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 */ |