LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - decimfmtimpl.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 809 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 99 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13