Index: source/i18n/decimfmt.cpp |
diff --git a/source/i18n/decimfmt.cpp b/source/i18n/decimfmt.cpp |
index 825651be08abf5f8f54ba8c3f6065b818813f6a3..9518ef581c7cff907edf9a833a333f80c30adbdf 100644 |
--- a/source/i18n/decimfmt.cpp |
+++ b/source/i18n/decimfmt.cpp |
@@ -1,6 +1,6 @@ |
/* |
******************************************************************************* |
-* Copyright (C) 1997-2014, International Business Machines Corporation and * |
+* Copyright (C) 1997-2015, International Business Machines Corporation and * |
* others. All Rights Reserved. * |
******************************************************************************* |
* |
@@ -41,16 +41,7 @@ |
#if !UCONFIG_NO_FORMATTING |
-#include "fphdlimp.h" |
-#include "unicode/decimfmt.h" |
-#include "unicode/choicfmt.h" |
-#include "unicode/ucurr.h" |
-#include "unicode/ustring.h" |
-#include "unicode/dcfmtsym.h" |
-#include "unicode/ures.h" |
-#include "unicode/uchar.h" |
#include "unicode/uniset.h" |
-#include "unicode/curramt.h" |
#include "unicode/currpinf.h" |
#include "unicode/plurrule.h" |
#include "unicode/utf16.h" |
@@ -59,19 +50,16 @@ |
#include "uresimp.h" |
#include "ucurrimp.h" |
#include "charstr.h" |
-#include "cmemory.h" |
#include "patternprops.h" |
-#include "digitlst.h" |
#include "cstring.h" |
-#include "umutex.h" |
#include "uassert.h" |
-#include "putilimp.h" |
-#include <math.h> |
#include "hash.h" |
#include "decfmtst.h" |
-#include "dcfmtimp.h" |
#include "plurrule_impl.h" |
#include "decimalformatpattern.h" |
+#include "fmtableimp.h" |
+#include "decimfmtimpl.h" |
+#include "visibledigits.h" |
/* |
* On certain platforms, round is a macro defined in math.h |
@@ -102,19 +90,6 @@ static const UnicodeString dbg_null("<NULL>",""); |
#endif |
- |
-/* == Fastpath calculation. == |
- */ |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
-inline DecimalFormatInternal& internalData(uint8_t *reserved) { |
- return *reinterpret_cast<DecimalFormatInternal*>(reserved); |
-} |
-inline const DecimalFormatInternal& internalData(const uint8_t *reserved) { |
- return *reinterpret_cast<const DecimalFormatInternal*>(reserved); |
-} |
-#else |
-#endif |
- |
/* For currency parsing purose, |
* Need to remember all prefix patterns and suffix patterns of |
* every currency format pattern, |
@@ -195,28 +170,10 @@ U_CDECL_BEGIN |
/** |
* @internal ICU 4.2 |
*/ |
-static UBool U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2); |
- |
-/** |
- * @internal ICU 4.2 |
- */ |
static UBool U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2); |
static UBool |
-U_CALLCONV decimfmtAffixValueComparator(UHashTok val1, UHashTok val2) { |
- const AffixesForCurrency* affix_1 = |
- (AffixesForCurrency*)val1.pointer; |
- const AffixesForCurrency* affix_2 = |
- (AffixesForCurrency*)val2.pointer; |
- return affix_1->negPrefixForCurrency == affix_2->negPrefixForCurrency && |
- affix_1->negSuffixForCurrency == affix_2->negSuffixForCurrency && |
- affix_1->posPrefixForCurrency == affix_2->posPrefixForCurrency && |
- affix_1->posSuffixForCurrency == affix_2->posSuffixForCurrency; |
-} |
- |
- |
-static UBool |
U_CALLCONV decimfmtAffixPatternValueComparator(UHashTok val1, UHashTok val2) { |
const AffixPatternsForCurrency* affix_1 = |
(AffixPatternsForCurrency*)val1.pointer; |
@@ -284,32 +241,9 @@ static const char fgPatterns[]="patterns"; |
static const char fgDecimalFormat[]="decimalFormat"; |
static const char fgCurrencyFormat[]="currencyFormat"; |
-static const UChar fgTripleCurrencySign[] = {0xA4, 0xA4, 0xA4, 0}; |
- |
inline int32_t _min(int32_t a, int32_t b) { return (a<b) ? a : b; } |
inline int32_t _max(int32_t a, int32_t b) { return (a<b) ? b : a; } |
-static void copyString(const UnicodeString& src, UBool isBogus, UnicodeString *& dest, UErrorCode &status) { |
- if (U_FAILURE(status)) { |
- return; |
- } |
- if (isBogus) { |
- delete dest; |
- dest = NULL; |
- } else { |
- if (dest != NULL) { |
- *dest = src; |
- } else { |
- dest = new UnicodeString(src); |
- if (dest == NULL) { |
- status = U_MEMORY_ALLOCATION_ERROR; |
- return; |
- } |
- } |
- } |
-} |
- |
- |
//------------------------------------------------------------------------------ |
// Constructs a DecimalFormat instance in the default locale. |
@@ -391,46 +325,16 @@ DecimalFormat::DecimalFormat(const UnicodeString& pattern, |
// or assignment operator can run successfully. |
void |
DecimalFormat::init() { |
- fPosPrefixPattern = 0; |
- fPosSuffixPattern = 0; |
- fNegPrefixPattern = 0; |
- fNegSuffixPattern = 0; |
- fCurrencyChoice = 0; |
- fMultiplier = NULL; |
- fScale = 0; |
- fGroupingSize = 0; |
- fGroupingSize2 = 0; |
- fDecimalSeparatorAlwaysShown = FALSE; |
- fSymbols = NULL; |
- fUseSignificantDigits = FALSE; |
- fMinSignificantDigits = 1; |
- fMaxSignificantDigits = 6; |
- fUseExponentialNotation = FALSE; |
- fMinExponentDigits = 0; |
- fExponentSignAlwaysShown = FALSE; |
fBoolFlags.clear(); |
- fRoundingIncrement = 0; |
- fRoundingMode = kRoundHalfEven; |
- fPad = 0; |
- fFormatWidth = 0; |
- fPadPosition = kPadBeforePrefix; |
fStyle = UNUM_DECIMAL; |
- fCurrencySignCount = fgCurrencySignCountZero; |
fAffixPatternsForCurrency = NULL; |
- fAffixesForCurrency = NULL; |
- fPluralAffixesForCurrency = NULL; |
fCurrencyPluralInfo = NULL; |
- fCurrencyUsage = UCURR_USAGE_STANDARD; |
#if UCONFIG_HAVE_PARSEALLINPUT |
fParseAllInput = UNUM_MAYBE; |
#endif |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- DecimalFormatInternal &data = internalData(fReserved); |
- data.fFastFormatStatus=kFastpathUNKNOWN; // don't try to calculate the fastpath until later. |
- data.fFastParseStatus=kFastpathUNKNOWN; // don't try to calculate the fastpath until later. |
-#endif |
fStaticSets = NULL; |
+ fImpl = NULL; |
} |
//------------------------------------------------------------------------------ |
@@ -444,28 +348,18 @@ DecimalFormat::construct(UErrorCode& status, |
const UnicodeString* pattern, |
DecimalFormatSymbols* symbolsToAdopt) |
{ |
- fSymbols = symbolsToAdopt; // Do this BEFORE aborting on status failure!!! |
- fRoundingIncrement = NULL; |
- fRoundingMode = kRoundHalfEven; |
- fPad = kPatternPadEscape; |
- fPadPosition = kPadBeforePrefix; |
+ LocalPointer<DecimalFormatSymbols> adoptedSymbols(symbolsToAdopt); |
if (U_FAILURE(status)) |
return; |
- fPosPrefixPattern = fPosSuffixPattern = NULL; |
- fNegPrefixPattern = fNegSuffixPattern = NULL; |
- setMultiplier(1); |
- fGroupingSize = 3; |
- fGroupingSize2 = 0; |
- fDecimalSeparatorAlwaysShown = FALSE; |
- fUseExponentialNotation = FALSE; |
- fMinExponentDigits = 0; |
- |
- if (fSymbols == NULL) |
+ if (adoptedSymbols.isNull()) |
{ |
- fSymbols = new DecimalFormatSymbols(Locale::getDefault(), status); |
- if (fSymbols == 0) { |
+ adoptedSymbols.adoptInstead( |
+ new DecimalFormatSymbols(Locale::getDefault(), status)); |
+ if (adoptedSymbols.isNull() && U_SUCCESS(status)) { |
status = U_MEMORY_ALLOCATION_ERROR; |
+ } |
+ if (U_FAILURE(status)) { |
return; |
} |
} |
@@ -473,18 +367,20 @@ DecimalFormat::construct(UErrorCode& status, |
if (U_FAILURE(status)) { |
return; |
} |
- UErrorCode nsStatus = U_ZERO_ERROR; |
- NumberingSystem *ns = NumberingSystem::createInstance(nsStatus); |
- if (U_FAILURE(nsStatus)) { |
- status = nsStatus; |
- return; |
- } |
UnicodeString str; |
// Uses the default locale's number format pattern if there isn't |
// one specified. |
if (pattern == NULL) |
{ |
+ UErrorCode nsStatus = U_ZERO_ERROR; |
+ LocalPointer<NumberingSystem> ns( |
+ NumberingSystem::createInstance(nsStatus)); |
+ if (U_FAILURE(nsStatus)) { |
+ status = nsStatus; |
+ return; |
+ } |
+ |
int32_t len = 0; |
UResourceBundle *top = ures_open(NULL, Locale::getDefault().getName(), &status); |
@@ -505,26 +401,26 @@ DecimalFormat::construct(UErrorCode& status, |
ures_close(top); |
} |
- delete ns; |
+ fImpl = new DecimalFormatImpl(this, *pattern, adoptedSymbols.getAlias(), parseErr, status); |
+ if (fImpl) { |
+ adoptedSymbols.orphan(); |
+ } else if (U_SUCCESS(status)) { |
+ status = U_MEMORY_ALLOCATION_ERROR; |
+ } |
+ if (U_FAILURE(status)) { |
+ return; |
+ } |
if (U_FAILURE(status)) |
{ |
return; |
} |
- if (pattern->indexOf((UChar)kCurrencySign) >= 0) { |
- // If it looks like we are going to use a currency pattern |
- // then do the time consuming lookup. |
- setCurrencyForSymbols(); |
- } else { |
- setCurrencyInternally(NULL, status); |
- } |
- |
const UnicodeString* patternUsed; |
UnicodeString currencyPluralPatternForOther; |
// apply pattern |
if (fStyle == UNUM_CURRENCY_PLURAL) { |
- fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status); |
+ fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status); |
if (U_FAILURE(status)) { |
return; |
} |
@@ -537,9 +433,10 @@ DecimalFormat::construct(UErrorCode& status, |
// plural count. If not, the right pattern need to be re-applied |
// during format. |
fCurrencyPluralInfo->getCurrencyPluralPattern(UNICODE_STRING("other", 5), currencyPluralPatternForOther); |
+ // TODO(refactor): Revisit, we are setting the pattern twice. |
+ fImpl->applyPatternFavorCurrencyPrecision( |
+ currencyPluralPatternForOther, status); |
patternUsed = ¤cyPluralPatternForOther; |
- // TODO: not needed? |
- setCurrencyForSymbols(); |
} else { |
patternUsed = pattern; |
@@ -549,39 +446,44 @@ DecimalFormat::construct(UErrorCode& status, |
// initialize for currency, not only for plural format, |
// but also for mix parsing |
if (fCurrencyPluralInfo == NULL) { |
- fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status); |
+ fCurrencyPluralInfo = new CurrencyPluralInfo(fImpl->fSymbols->getLocale(), status); |
if (U_FAILURE(status)) { |
return; |
} |
} |
// need it for mix parsing |
setupCurrencyAffixPatterns(status); |
- // expanded affixes for plural names |
- if (patternUsed->indexOf(fgTripleCurrencySign, 3, 0) != -1) { |
- setupCurrencyAffixes(*patternUsed, TRUE, TRUE, status); |
- } |
- } |
- |
- applyPatternWithoutExpandAffix(*patternUsed,FALSE, parseErr, status); |
- |
- // expand affixes |
- if (fCurrencySignCount != fgCurrencySignCountInPluralFormat) { |
- expandAffixAdjustWidth(NULL); |
- } |
- |
- // If it was a currency format, apply the appropriate rounding by |
- // resetting the currency. NOTE: this copies fCurrency on top of itself. |
- if (fCurrencySignCount != fgCurrencySignCountZero) { |
- setCurrencyInternally(getCurrency(), status); |
} |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- DecimalFormatInternal &data = internalData(fReserved); |
- data.fFastFormatStatus = kFastpathNO; // allow it to be calculated |
- data.fFastParseStatus = kFastpathNO; // allow it to be calculated |
- handleChanged(); |
-#endif |
} |
+static void |
+applyPatternWithNoSideEffects( |
+ const UnicodeString& pattern, |
+ UParseError& parseError, |
+ UnicodeString &negPrefix, |
+ UnicodeString &negSuffix, |
+ UnicodeString &posPrefix, |
+ UnicodeString &posSuffix, |
+ UErrorCode& status) { |
+ if (U_FAILURE(status)) |
+ { |
+ return; |
+ } |
+ DecimalFormatPatternParser patternParser; |
+ DecimalFormatPattern out; |
+ patternParser.applyPatternWithoutExpandAffix( |
+ pattern, |
+ out, |
+ parseError, |
+ status); |
+ if (U_FAILURE(status)) { |
+ return; |
+ } |
+ negPrefix = out.fNegPrefixPattern; |
+ negSuffix = out.fNegSuffixPattern; |
+ posPrefix = out.fPosPrefixPattern; |
+ posSuffix = out.fPosSuffixPattern; |
+} |
void |
DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
@@ -594,7 +496,7 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
return; |
} |
- NumberingSystem *ns = NumberingSystem::createInstance(fSymbols->getLocale(),status); |
+ NumberingSystem *ns = NumberingSystem::createInstance(fImpl->fSymbols->getLocale(),status); |
if (U_FAILURE(status)) { |
return; |
} |
@@ -605,7 +507,7 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
UnicodeString currencyPattern; |
UErrorCode error = U_ZERO_ERROR; |
- UResourceBundle *resource = ures_open(NULL, fSymbols->getLocale().getName(), &error); |
+ UResourceBundle *resource = ures_open(NULL, fImpl->fSymbols->getLocale().getName(), &error); |
UResourceBundle *numElements = ures_getByKeyWithFallback(resource, fgNumberElements, NULL, &error); |
resource = ures_getByKeyWithFallback(numElements, ns->getName(), resource, &error); |
resource = ures_getByKeyWithFallback(resource, fgPatterns, resource, &error); |
@@ -622,13 +524,18 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
delete ns; |
if (U_SUCCESS(error)) { |
- applyPatternWithoutExpandAffix(UnicodeString(patResStr, patLen), false, |
- parseErr, status); |
+ UnicodeString negPrefix; |
+ UnicodeString negSuffix; |
+ UnicodeString posPrefix; |
+ UnicodeString posSuffix; |
+ applyPatternWithNoSideEffects(UnicodeString(patResStr, patLen), |
+ parseErr, |
+ negPrefix, negSuffix, posPrefix, posSuffix, status); |
AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( |
- *fNegPrefixPattern, |
- *fNegSuffixPattern, |
- *fPosPrefixPattern, |
- *fPosSuffixPattern, |
+ negPrefix, |
+ negSuffix, |
+ posPrefix, |
+ posSuffix, |
UCURR_SYMBOL_NAME); |
fAffixPatternsForCurrency->put(UNICODE_STRING("default", 7), affixPtn, status); |
} |
@@ -636,7 +543,7 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
// save the unique currency plural patterns of this locale. |
Hashtable* pluralPtn = fCurrencyPluralInfo->fPluralCountToCurrencyUnitPattern; |
const UHashElement* element = NULL; |
- int32_t pos = -1; |
+ int32_t pos = UHASH_FIRST; |
Hashtable pluralPatternSet; |
while ((element = pluralPtn->nextElement(pos)) != NULL) { |
const UHashTok valueTok = element->value; |
@@ -644,13 +551,19 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
const UHashTok keyTok = element->key; |
const UnicodeString* key = (UnicodeString*)keyTok.pointer; |
if (pluralPatternSet.geti(*value) != 1) { |
+ UnicodeString negPrefix; |
+ UnicodeString negSuffix; |
+ UnicodeString posPrefix; |
+ UnicodeString posSuffix; |
pluralPatternSet.puti(*value, 1, status); |
- applyPatternWithoutExpandAffix(*value, false, parseErr, status); |
+ applyPatternWithNoSideEffects( |
+ *value, parseErr, |
+ negPrefix, negSuffix, posPrefix, posSuffix, status); |
AffixPatternsForCurrency* affixPtn = new AffixPatternsForCurrency( |
- *fNegPrefixPattern, |
- *fNegSuffixPattern, |
- *fPosPrefixPattern, |
- *fPosSuffixPattern, |
+ negPrefix, |
+ negSuffix, |
+ posPrefix, |
+ posSuffix, |
UCURR_LONG_NAME); |
fAffixPatternsForCurrency->put(*key, affixPtn, status); |
} |
@@ -658,86 +571,13 @@ DecimalFormat::setupCurrencyAffixPatterns(UErrorCode& status) { |
} |
-void |
-DecimalFormat::setupCurrencyAffixes(const UnicodeString& pattern, |
- UBool setupForCurrentPattern, |
- UBool setupForPluralPattern, |
- UErrorCode& status) { |
- if (U_FAILURE(status)) { |
- return; |
- } |
- UParseError parseErr; |
- if (setupForCurrentPattern) { |
- if (fAffixesForCurrency) { |
- deleteHashForAffix(fAffixesForCurrency); |
- } |
- fAffixesForCurrency = initHashForAffix(status); |
- if (U_SUCCESS(status)) { |
- applyPatternWithoutExpandAffix(pattern, false, parseErr, status); |
- const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules(); |
- StringEnumeration* keywords = pluralRules->getKeywords(status); |
- if (U_SUCCESS(status)) { |
- const UnicodeString* pluralCount; |
- while ((pluralCount = keywords->snext(status)) != NULL) { |
- if ( U_SUCCESS(status) ) { |
- expandAffixAdjustWidth(pluralCount); |
- AffixesForCurrency* affix = new AffixesForCurrency( |
- fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix); |
- fAffixesForCurrency->put(*pluralCount, affix, status); |
- } |
- } |
- } |
- delete keywords; |
- } |
- } |
- |
- if (U_FAILURE(status)) { |
- return; |
- } |
- |
- if (setupForPluralPattern) { |
- if (fPluralAffixesForCurrency) { |
- deleteHashForAffix(fPluralAffixesForCurrency); |
- } |
- fPluralAffixesForCurrency = initHashForAffix(status); |
- if (U_SUCCESS(status)) { |
- const PluralRules* pluralRules = fCurrencyPluralInfo->getPluralRules(); |
- StringEnumeration* keywords = pluralRules->getKeywords(status); |
- if (U_SUCCESS(status)) { |
- const UnicodeString* pluralCount; |
- while ((pluralCount = keywords->snext(status)) != NULL) { |
- if ( U_SUCCESS(status) ) { |
- UnicodeString ptn; |
- fCurrencyPluralInfo->getCurrencyPluralPattern(*pluralCount, ptn); |
- applyPatternInternally(*pluralCount, ptn, false, parseErr, status); |
- AffixesForCurrency* affix = new AffixesForCurrency( |
- fNegativePrefix, fNegativeSuffix, fPositivePrefix, fPositiveSuffix); |
- fPluralAffixesForCurrency->put(*pluralCount, affix, status); |
- } |
- } |
- } |
- delete keywords; |
- } |
- } |
-} |
- |
- |
//------------------------------------------------------------------------------ |
DecimalFormat::~DecimalFormat() |
{ |
- delete fPosPrefixPattern; |
- delete fPosSuffixPattern; |
- delete fNegPrefixPattern; |
- delete fNegSuffixPattern; |
- delete fCurrencyChoice; |
- delete fMultiplier; |
- delete fSymbols; |
- delete fRoundingIncrement; |
deleteHashForAffixPattern(); |
- deleteHashForAffix(fAffixesForCurrency); |
- deleteHashForAffix(fPluralAffixesForCurrency); |
delete fCurrencyPluralInfo; |
+ delete fImpl; |
} |
//------------------------------------------------------------------------------ |
@@ -753,18 +593,6 @@ DecimalFormat::DecimalFormat(const DecimalFormat &source) : |
// assignment operator |
template <class T> |
-static void _copy_ptr(T** pdest, const T* source) { |
- if (source == NULL) { |
- delete *pdest; |
- *pdest = NULL; |
- } else if (*pdest == NULL) { |
- *pdest = new T(*source); |
- } else { |
- **pdest = *source; |
- } |
-} |
- |
-template <class T> |
static void _clone_ptr(T** pdest, const T* source) { |
delete *pdest; |
if (source == NULL) { |
@@ -780,41 +608,12 @@ DecimalFormat::operator=(const DecimalFormat& rhs) |
if(this != &rhs) { |
UErrorCode status = U_ZERO_ERROR; |
NumberFormat::operator=(rhs); |
+ if (fImpl == NULL) { |
+ fImpl = new DecimalFormatImpl(this, *rhs.fImpl, status); |
+ } else { |
+ fImpl->assign(*rhs.fImpl, status); |
+ } |
fStaticSets = DecimalFormatStaticSets::getStaticSets(status); |
- fPositivePrefix = rhs.fPositivePrefix; |
- fPositiveSuffix = rhs.fPositiveSuffix; |
- fNegativePrefix = rhs.fNegativePrefix; |
- fNegativeSuffix = rhs.fNegativeSuffix; |
- _copy_ptr(&fPosPrefixPattern, rhs.fPosPrefixPattern); |
- _copy_ptr(&fPosSuffixPattern, rhs.fPosSuffixPattern); |
- _copy_ptr(&fNegPrefixPattern, rhs.fNegPrefixPattern); |
- _copy_ptr(&fNegSuffixPattern, rhs.fNegSuffixPattern); |
- _clone_ptr(&fCurrencyChoice, rhs.fCurrencyChoice); |
- setRoundingIncrement(rhs.getRoundingIncrement()); |
- fRoundingMode = rhs.fRoundingMode; |
- setMultiplier(rhs.getMultiplier()); |
- fGroupingSize = rhs.fGroupingSize; |
- fGroupingSize2 = rhs.fGroupingSize2; |
- fDecimalSeparatorAlwaysShown = rhs.fDecimalSeparatorAlwaysShown; |
- _copy_ptr(&fSymbols, rhs.fSymbols); |
- fUseExponentialNotation = rhs.fUseExponentialNotation; |
- fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown; |
- fBoolFlags = rhs.fBoolFlags; |
- /*Bertrand A. D. Update 98.03.17*/ |
- fCurrencySignCount = rhs.fCurrencySignCount; |
- /*end of Update*/ |
- fMinExponentDigits = rhs.fMinExponentDigits; |
- |
- /* sfb 990629 */ |
- fFormatWidth = rhs.fFormatWidth; |
- fPad = rhs.fPad; |
- fPadPosition = rhs.fPadPosition; |
- /* end sfb */ |
- fMinSignificantDigits = rhs.fMinSignificantDigits; |
- fMaxSignificantDigits = rhs.fMaxSignificantDigits; |
- fUseSignificantDigits = rhs.fUseSignificantDigits; |
- fFormatPattern = rhs.fFormatPattern; |
- fCurrencyUsage = rhs.fCurrencyUsage; |
fStyle = rhs.fStyle; |
_clone_ptr(&fCurrencyPluralInfo, rhs.fCurrencyPluralInfo); |
deleteHashForAffixPattern(); |
@@ -824,24 +623,8 @@ DecimalFormat::operator=(const DecimalFormat& rhs) |
copyHashForAffixPattern(rhs.fAffixPatternsForCurrency, |
fAffixPatternsForCurrency, status); |
} |
- deleteHashForAffix(fAffixesForCurrency); |
- if (rhs.fAffixesForCurrency) { |
- UErrorCode status = U_ZERO_ERROR; |
- fAffixesForCurrency = initHashForAffixPattern(status); |
- copyHashForAffix(rhs.fAffixesForCurrency, fAffixesForCurrency, status); |
- } |
- deleteHashForAffix(fPluralAffixesForCurrency); |
- if (rhs.fPluralAffixesForCurrency) { |
- UErrorCode status = U_ZERO_ERROR; |
- fPluralAffixesForCurrency = initHashForAffixPattern(status); |
- copyHashForAffix(rhs.fPluralAffixesForCurrency, fPluralAffixesForCurrency, status); |
- } |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- DecimalFormatInternal &data = internalData(fReserved); |
- const DecimalFormatInternal &rhsData = internalData(rhs.fReserved); |
- data = rhsData; |
-#endif |
} |
+ |
return *this; |
} |
@@ -856,247 +639,11 @@ DecimalFormat::operator==(const Format& that) const |
// NumberFormat::operator== guarantees this cast is safe |
const DecimalFormat* other = (DecimalFormat*)&that; |
-#ifdef FMT_DEBUG |
- // This code makes it easy to determine why two format objects that should |
- // be equal aren't. |
- UBool first = TRUE; |
- if (!NumberFormat::operator==(that)) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("NumberFormat::!="); |
- } else { |
- if (!((fPosPrefixPattern == other->fPosPrefixPattern && // both null |
- fPositivePrefix == other->fPositivePrefix) |
- || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && |
- *fPosPrefixPattern == *other->fPosPrefixPattern))) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("Pos Prefix !="); |
- } |
- if (!((fPosSuffixPattern == other->fPosSuffixPattern && // both null |
- fPositiveSuffix == other->fPositiveSuffix) |
- || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && |
- *fPosSuffixPattern == *other->fPosSuffixPattern))) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("Pos Suffix !="); |
- } |
- if (!((fNegPrefixPattern == other->fNegPrefixPattern && // both null |
- fNegativePrefix == other->fNegativePrefix) |
- || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && |
- *fNegPrefixPattern == *other->fNegPrefixPattern))) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("Neg Prefix "); |
- if (fNegPrefixPattern == NULL) { |
- debug("NULL("); |
- debugout(fNegativePrefix); |
- debug(")"); |
- } else { |
- debugout(*fNegPrefixPattern); |
- } |
- debug(" != "); |
- if (other->fNegPrefixPattern == NULL) { |
- debug("NULL("); |
- debugout(other->fNegativePrefix); |
- debug(")"); |
- } else { |
- debugout(*other->fNegPrefixPattern); |
- } |
- } |
- if (!((fNegSuffixPattern == other->fNegSuffixPattern && // both null |
- fNegativeSuffix == other->fNegativeSuffix) |
- || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && |
- *fNegSuffixPattern == *other->fNegSuffixPattern))) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("Neg Suffix "); |
- if (fNegSuffixPattern == NULL) { |
- debug("NULL("); |
- debugout(fNegativeSuffix); |
- debug(")"); |
- } else { |
- debugout(*fNegSuffixPattern); |
- } |
- debug(" != "); |
- if (other->fNegSuffixPattern == NULL) { |
- debug("NULL("); |
- debugout(other->fNegativeSuffix); |
- debug(")"); |
- } else { |
- debugout(*other->fNegSuffixPattern); |
- } |
- } |
- if (!((fRoundingIncrement == other->fRoundingIncrement) // both null |
- || (fRoundingIncrement != NULL && |
- other->fRoundingIncrement != NULL && |
- *fRoundingIncrement == *other->fRoundingIncrement))) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("Rounding Increment !="); |
- } |
- if (fRoundingMode != other->fRoundingMode) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- printf("Rounding Mode %d != %d", (int)fRoundingMode, (int)other->fRoundingMode); |
- } |
- if (getMultiplier() != other->getMultiplier()) { |
- if (first) { printf("[ "); first = FALSE; } |
- printf("Multiplier %ld != %ld", getMultiplier(), other->getMultiplier()); |
- } |
- if (fGroupingSize != other->fGroupingSize) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- printf("Grouping Size %ld != %ld", fGroupingSize, other->fGroupingSize); |
- } |
- if (fGroupingSize2 != other->fGroupingSize2) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- printf("Secondary Grouping Size %ld != %ld", fGroupingSize2, other->fGroupingSize2); |
- } |
- if (fDecimalSeparatorAlwaysShown != other->fDecimalSeparatorAlwaysShown) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- printf("fDecimalSeparatorAlwaysShown %d != %d", fDecimalSeparatorAlwaysShown, other->fDecimalSeparatorAlwaysShown); |
- } |
- if (fUseExponentialNotation != other->fUseExponentialNotation) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fUseExponentialNotation !="); |
- } |
- if (fUseExponentialNotation && |
- fMinExponentDigits != other->fMinExponentDigits) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fMinExponentDigits !="); |
- } |
- if (fUseExponentialNotation && |
- fExponentSignAlwaysShown != other->fExponentSignAlwaysShown) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fExponentSignAlwaysShown !="); |
- } |
- if (fBoolFlags.getAll() != other->fBoolFlags.getAll()) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fBoolFlags !="); |
- } |
- if (*fSymbols != *(other->fSymbols)) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("Symbols !="); |
- } |
- // TODO Add debug stuff for significant digits here |
- if (fUseSignificantDigits != other->fUseSignificantDigits) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fUseSignificantDigits !="); |
- } |
- if (fUseSignificantDigits && |
- fMinSignificantDigits != other->fMinSignificantDigits) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fMinSignificantDigits !="); |
- } |
- if (fUseSignificantDigits && |
- fMaxSignificantDigits != other->fMaxSignificantDigits) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fMaxSignificantDigits !="); |
- } |
- if (fFormatWidth != other->fFormatWidth) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fFormatWidth !="); |
- } |
- if (fPad != other->fPad) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fPad !="); |
- } |
- if (fPadPosition != other->fPadPosition) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fPadPosition !="); |
- } |
- if (fStyle == UNUM_CURRENCY_PLURAL && |
- fStyle != other->fStyle) |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fStyle !="); |
- } |
- if (fStyle == UNUM_CURRENCY_PLURAL && |
- fFormatPattern != other->fFormatPattern) { |
- if (first) { printf("[ "); first = FALSE; } else { printf(", "); } |
- debug("fFormatPattern !="); |
- } |
- |
- if (!first) { printf(" ]"); } |
- if (fCurrencySignCount != other->fCurrencySignCount) { |
- debug("fCurrencySignCount !="); |
- } |
- if (fCurrencyPluralInfo == other->fCurrencyPluralInfo) { |
- debug("fCurrencyPluralInfo == "); |
- if (fCurrencyPluralInfo == NULL) { |
- debug("fCurrencyPluralInfo == NULL"); |
- } |
- } |
- if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && |
- *fCurrencyPluralInfo != *(other->fCurrencyPluralInfo)) { |
- debug("fCurrencyPluralInfo !="); |
- } |
- if (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo == NULL || |
- fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo != NULL) { |
- debug("fCurrencyPluralInfo one NULL, the other not"); |
- } |
- if (fCurrencyPluralInfo == NULL && other->fCurrencyPluralInfo == NULL) { |
- debug("fCurrencyPluralInfo == "); |
- } |
- } |
-#endif |
- |
return ( |
NumberFormat::operator==(that) && |
- |
- ((fCurrencySignCount == fgCurrencySignCountInPluralFormat) ? |
- (fAffixPatternsForCurrency->equals(*other->fAffixPatternsForCurrency)) : |
- (((fPosPrefixPattern == other->fPosPrefixPattern && // both null |
- fPositivePrefix == other->fPositivePrefix) |
- || (fPosPrefixPattern != 0 && other->fPosPrefixPattern != 0 && |
- *fPosPrefixPattern == *other->fPosPrefixPattern)) && |
- ((fPosSuffixPattern == other->fPosSuffixPattern && // both null |
- fPositiveSuffix == other->fPositiveSuffix) |
- || (fPosSuffixPattern != 0 && other->fPosSuffixPattern != 0 && |
- *fPosSuffixPattern == *other->fPosSuffixPattern)) && |
- ((fNegPrefixPattern == other->fNegPrefixPattern && // both null |
- fNegativePrefix == other->fNegativePrefix) |
- || (fNegPrefixPattern != 0 && other->fNegPrefixPattern != 0 && |
- *fNegPrefixPattern == *other->fNegPrefixPattern)) && |
- ((fNegSuffixPattern == other->fNegSuffixPattern && // both null |
- fNegativeSuffix == other->fNegativeSuffix) |
- || (fNegSuffixPattern != 0 && other->fNegSuffixPattern != 0 && |
- *fNegSuffixPattern == *other->fNegSuffixPattern)))) && |
- |
- ((fRoundingIncrement == other->fRoundingIncrement) // both null |
- || (fRoundingIncrement != NULL && |
- other->fRoundingIncrement != NULL && |
- *fRoundingIncrement == *other->fRoundingIncrement)) && |
- |
- fRoundingMode == other->fRoundingMode && |
- getMultiplier() == other->getMultiplier() && |
- fGroupingSize == other->fGroupingSize && |
- fGroupingSize2 == other->fGroupingSize2 && |
- fDecimalSeparatorAlwaysShown == other->fDecimalSeparatorAlwaysShown && |
- fUseExponentialNotation == other->fUseExponentialNotation && |
- |
- (!fUseExponentialNotation || |
- (fMinExponentDigits == other->fMinExponentDigits && fExponentSignAlwaysShown == other->fExponentSignAlwaysShown)) && |
- |
fBoolFlags.getAll() == other->fBoolFlags.getAll() && |
- *fSymbols == *(other->fSymbols) && |
- fUseSignificantDigits == other->fUseSignificantDigits && |
- |
- (!fUseSignificantDigits || |
- (fMinSignificantDigits == other->fMinSignificantDigits && fMaxSignificantDigits == other->fMaxSignificantDigits)) && |
- |
- fFormatWidth == other->fFormatWidth && |
- fPad == other->fPad && |
- fPadPosition == other->fPadPosition && |
- |
- (fStyle != UNUM_CURRENCY_PLURAL || |
- (fStyle == other->fStyle && fFormatPattern == other->fFormatPattern)) && |
- |
- fCurrencySignCount == other->fCurrencySignCount && |
+ *fImpl == *other->fImpl); |
- ((fCurrencyPluralInfo == other->fCurrencyPluralInfo && |
- fCurrencyPluralInfo == NULL) || |
- (fCurrencyPluralInfo != NULL && other->fCurrencyPluralInfo != NULL && |
- *fCurrencyPluralInfo == *(other->fCurrencyPluralInfo))) && |
- |
- fCurrencyUsage == other->fCurrencyUsage |
- |
- // depending on other settings we may also need to compare |
- // fCurrencyChoice (mostly deprecated?), |
- // fAffixesForCurrency & fPluralAffixesForCurrency (only relevant in some cases) |
- ); |
} |
//------------------------------------------------------------------------------ |
@@ -1110,86 +657,60 @@ DecimalFormat::clone() const |
FixedDecimal |
DecimalFormat::getFixedDecimal(double number, UErrorCode &status) const { |
- FixedDecimal result; |
- |
+ VisibleDigitsWithExponent digits; |
+ initVisibleDigitsWithExponent(number, digits, status); |
if (U_FAILURE(status)) { |
- return result; |
- } |
- |
- if (uprv_isNaN(number) || uprv_isPositiveInfinity(fabs(number))) { |
- // For NaN and Infinity the state of the formatter is ignored. |
- result.init(number); |
- return result; |
+ return FixedDecimal(); |
} |
+ return FixedDecimal(digits.getMantissa()); |
+} |
- if (fMultiplier == NULL && fScale == 0 && fRoundingIncrement == 0 && areSignificantDigitsUsed() == FALSE && |
- result.quickInit(number) && result.visibleDecimalDigitCount <= getMaximumFractionDigits()) { |
- // Fast Path. Construction of an exact FixedDecimal directly from the double, without passing |
- // through a DigitList, was successful, and the formatter is doing nothing tricky with rounding. |
- // printf("getFixedDecimal(%g): taking fast path.\n", number); |
- result.adjustForMinFractionDigits(getMinimumFractionDigits()); |
- } else { |
- // Slow path. Create a DigitList, and have this formatter round it according to the |
- // requirements of the format, and fill the fixedDecimal from that. |
- DigitList digits; |
- digits.set(number); |
- result = getFixedDecimal(digits, status); |
- } |
- return result; |
+VisibleDigitsWithExponent & |
+DecimalFormat::initVisibleDigitsWithExponent( |
+ double number, |
+ VisibleDigitsWithExponent &digits, |
+ UErrorCode &status) const { |
+ return fImpl->initVisibleDigitsWithExponent(number, digits, status); |
} |
-// MSVC optimizer bug? |
-// turn off optimization as it causes different behavior in the int64->double->int64 conversion |
-#if defined (_MSC_VER) |
-#pragma optimize ( "", off ) |
-#endif |
FixedDecimal |
DecimalFormat::getFixedDecimal(const Formattable &number, UErrorCode &status) const { |
+ VisibleDigitsWithExponent digits; |
+ initVisibleDigitsWithExponent(number, digits, status); |
if (U_FAILURE(status)) { |
return FixedDecimal(); |
} |
+ return FixedDecimal(digits.getMantissa()); |
+} |
+ |
+VisibleDigitsWithExponent & |
+DecimalFormat::initVisibleDigitsWithExponent( |
+ const Formattable &number, |
+ VisibleDigitsWithExponent &digits, |
+ UErrorCode &status) const { |
+ if (U_FAILURE(status)) { |
+ return digits; |
+ } |
if (!number.isNumeric()) { |
status = U_ILLEGAL_ARGUMENT_ERROR; |
- return FixedDecimal(); |
+ return digits; |
} |
DigitList *dl = number.getDigitList(); |
if (dl != NULL) { |
- DigitList clonedDL(*dl); |
- return getFixedDecimal(clonedDL, status); |
+ DigitList dlCopy(*dl); |
+ return fImpl->initVisibleDigitsWithExponent( |
+ dlCopy, digits, status); |
} |
Formattable::Type type = number.getType(); |
if (type == Formattable::kDouble || type == Formattable::kLong) { |
- return getFixedDecimal(number.getDouble(status), status); |
- } |
- |
- if (type == Formattable::kInt64) { |
- // "volatile" here is a workaround to avoid optimization issues. |
- volatile double fdv = number.getDouble(status); |
- // Note: conversion of int64_t -> double rounds with some compilers to |
- // values beyond what can be represented as a 64 bit int. Subsequent |
- // testing or conversion with int64_t produces bad results. |
- // So filter the problematic values, route them to DigitList. |
- if (fdv != (double)U_INT64_MAX && fdv != (double)U_INT64_MIN && |
- number.getInt64() == (int64_t)fdv) { |
- return getFixedDecimal(number.getDouble(status), status); |
- } |
+ return fImpl->initVisibleDigitsWithExponent( |
+ number.getDouble(status), digits, status); |
} |
- |
- // The only case left is type==int64_t, with a value with more digits than a double can represent. |
- // Any formattable originating as a big decimal will have had a pre-existing digit list. |
- // Any originating as a double or int32 will have been handled as a double. |
- |
- U_ASSERT(type == Formattable::kInt64); |
- DigitList digits; |
- digits.set(number.getInt64()); |
- return getFixedDecimal(digits, status); |
+ return fImpl->initVisibleDigitsWithExponent( |
+ number.getInt64(), digits, status); |
} |
-// end workaround MSVC optimizer bug |
-#if defined (_MSC_VER) |
-#pragma optimize ( "", on ) |
-#endif |
// Create a fixed decimal from a DigitList. |
@@ -1197,70 +718,21 @@ DecimalFormat::getFixedDecimal(const Formattable &number, UErrorCode &status) co |
// Internal function only. |
FixedDecimal |
DecimalFormat::getFixedDecimal(DigitList &number, UErrorCode &status) const { |
- // Round the number according to the requirements of this Format. |
- FixedDecimal result; |
- _round(number, number, result.isNegative, status); |
- |
- // The int64_t fields in FixedDecimal can easily overflow. |
- // In deciding what to discard in this event, consider that fixedDecimal |
- // is being used only with PluralRules, and those rules mostly look at least significant |
- // few digits of the integer part, and whether the fraction part is zero or not. |
- // |
- // So, in case of overflow when filling in the fields of the FixedDecimal object, |
- // for the integer part, discard the most significant digits. |
- // for the fraction part, discard the least significant digits, |
- // don't truncate the fraction value to zero. |
- // For simplicity, the int64_t fields are limited to 18 decimal digits, even |
- // though they could hold most (but not all) 19 digit values. |
- |
- // Integer Digits. |
- int32_t di = number.getDecimalAt()-18; // Take at most 18 digits. |
- if (di < 0) { |
- di = 0; |
- } |
- result.intValue = 0; |
- for (; di<number.getDecimalAt(); di++) { |
- result.intValue = result.intValue * 10 + (number.getDigit(di) & 0x0f); |
- } |
- if (result.intValue == 0 && number.getDecimalAt()-18 > 0) { |
- // The number is something like 100000000000000000000000. |
- // More than 18 digits integer digits, but the least significant 18 are all zero. |
- // We don't want to return zero as the int part, but want to keep zeros |
- // for several of the least significant digits. |
- result.intValue = 100000000000000000LL; |
- } |
- |
- // Fraction digits. |
- result.decimalDigits = result.decimalDigitsWithoutTrailingZeros = result.visibleDecimalDigitCount = 0; |
- for (di = number.getDecimalAt(); di < number.getCount(); di++) { |
- result.visibleDecimalDigitCount++; |
- if (result.decimalDigits < 100000000000000000LL) { |
- // 9223372036854775807 Largest 64 bit signed integer |
- int32_t digitVal = number.getDigit(di) & 0x0f; // getDigit() returns a char, '0'-'9'. |
- result.decimalDigits = result.decimalDigits * 10 + digitVal; |
- if (digitVal > 0) { |
- result.decimalDigitsWithoutTrailingZeros = result.decimalDigits; |
- } |
- } |
- } |
- |
- result.hasIntegerValue = (result.decimalDigits == 0); |
- |
- // Trailing fraction zeros. The format specification may require more trailing |
- // zeros than the numeric value. Add any such on now. |
- |
- int32_t minFractionDigits; |
- if (areSignificantDigitsUsed()) { |
- minFractionDigits = getMinimumSignificantDigits() - number.getDecimalAt(); |
- if (minFractionDigits < 0) { |
- minFractionDigits = 0; |
- } |
- } else { |
- minFractionDigits = getMinimumFractionDigits(); |
+ VisibleDigitsWithExponent digits; |
+ initVisibleDigitsWithExponent(number, digits, status); |
+ if (U_FAILURE(status)) { |
+ return FixedDecimal(); |
} |
- result.adjustForMinFractionDigits(minFractionDigits); |
+ return FixedDecimal(digits.getMantissa()); |
+} |
- return result; |
+VisibleDigitsWithExponent & |
+DecimalFormat::initVisibleDigitsWithExponent( |
+ DigitList &number, |
+ VisibleDigitsWithExponent &digits, |
+ UErrorCode &status) const { |
+ return fImpl->initVisibleDigitsWithExponent( |
+ number, digits, status); |
} |
@@ -1271,7 +743,8 @@ DecimalFormat::format(int32_t number, |
UnicodeString& appendTo, |
FieldPosition& fieldPosition) const |
{ |
- return format((int64_t)number, appendTo, fieldPosition); |
+ UErrorCode status = U_ZERO_ERROR; |
+ return fImpl->format(number, appendTo, fieldPosition, status); |
} |
UnicodeString& |
@@ -1280,7 +753,7 @@ DecimalFormat::format(int32_t number, |
FieldPosition& fieldPosition, |
UErrorCode& status) const |
{ |
- return format((int64_t)number, appendTo, fieldPosition, status); |
+ return fImpl->format(number, appendTo, fieldPosition, status); |
} |
UnicodeString& |
@@ -1289,80 +762,10 @@ DecimalFormat::format(int32_t number, |
FieldPositionIterator* posIter, |
UErrorCode& status) const |
{ |
- return format((int64_t)number, appendTo, posIter, status); |
+ return fImpl->format(number, appendTo, posIter, status); |
} |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
-void DecimalFormat::handleChanged() { |
- DecimalFormatInternal &data = internalData(fReserved); |
- |
- if(data.fFastFormatStatus == kFastpathUNKNOWN || data.fFastParseStatus == kFastpathUNKNOWN) { |
- return; // still constructing. Wait. |
- } |
- |
- data.fFastParseStatus = data.fFastFormatStatus = kFastpathNO; |
- |
-#if UCONFIG_HAVE_PARSEALLINPUT |
- if(fParseAllInput == UNUM_NO) { |
- debug("No Parse fastpath: fParseAllInput==UNUM_NO"); |
- } else |
-#endif |
- if (fFormatWidth!=0) { |
- debug("No Parse fastpath: fFormatWidth"); |
- } else if(fPositivePrefix.length()>0) { |
- debug("No Parse fastpath: positive prefix"); |
- } else if(fPositiveSuffix.length()>0) { |
- debug("No Parse fastpath: positive suffix"); |
- } else if(fNegativePrefix.length()>1 |
- || ((fNegativePrefix.length()==1) && (fNegativePrefix.charAt(0)!=0x002D))) { |
- debug("No Parse fastpath: negative prefix that isn't '-'"); |
- } else if(fNegativeSuffix.length()>0) { |
- debug("No Parse fastpath: negative suffix"); |
- } else { |
- data.fFastParseStatus = kFastpathYES; |
- debug("parse fastpath: YES"); |
- } |
- |
- if(fUseExponentialNotation) { |
- debug("No format fastpath: fUseExponentialNotation"); |
- } else if(fFormatWidth!=0) { |
- debug("No format fastpath: fFormatWidth!=0"); |
- } else if(fMinSignificantDigits!=1) { |
- debug("No format fastpath: fMinSignificantDigits!=1"); |
- } else if(fMultiplier!=NULL) { |
- debug("No format fastpath: fMultiplier!=NULL"); |
- } else if(fScale!=0) { |
- debug("No format fastpath: fScale!=0"); |
- } else if(0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0)) { |
- debug("No format fastpath: 0x0030 != getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0)"); |
- } else if(fDecimalSeparatorAlwaysShown) { |
- debug("No format fastpath: fDecimalSeparatorAlwaysShown"); |
- } else if(getMinimumFractionDigits()>0) { |
- debug("No format fastpath: fMinFractionDigits>0"); |
- } else if(fCurrencySignCount != fgCurrencySignCountZero) { |
- debug("No format fastpath: fCurrencySignCount != fgCurrencySignCountZero"); |
- } else if(fRoundingIncrement!=0) { |
- debug("No format fastpath: fRoundingIncrement!=0"); |
- } else if (fGroupingSize!=0 && isGroupingUsed()) { |
- debug("Maybe format fastpath: fGroupingSize!=0 and grouping is used"); |
-#ifdef FMT_DEBUG |
- printf("groupingsize=%d\n", fGroupingSize); |
-#endif |
- |
- if (getMinimumIntegerDigits() <= fGroupingSize) { |
- data.fFastFormatStatus = kFastpathMAYBE; |
- } |
- } else if(fGroupingSize2!=0 && isGroupingUsed()) { |
- debug("No format fastpath: fGroupingSize2!=0"); |
- } else { |
- data.fFastFormatStatus = kFastpathYES; |
- debug("format:kFastpathYES!"); |
- } |
- |
- |
-} |
-#endif |
//------------------------------------------------------------------------------ |
UnicodeString& |
@@ -1371,8 +774,7 @@ DecimalFormat::format(int64_t number, |
FieldPosition& fieldPosition) const |
{ |
UErrorCode status = U_ZERO_ERROR; /* ignored */ |
- FieldPositionOnlyHandler handler(fieldPosition); |
- return _format(number, appendTo, handler, status); |
+ return fImpl->format(number, appendTo, fieldPosition, status); |
} |
UnicodeString& |
@@ -1381,8 +783,7 @@ DecimalFormat::format(int64_t number, |
FieldPosition& fieldPosition, |
UErrorCode& status) const |
{ |
- FieldPositionOnlyHandler handler(fieldPosition); |
- return _format(number, appendTo, handler, status); |
+ return fImpl->format(number, appendTo, fieldPosition, status); |
} |
UnicodeString& |
@@ -1391,108 +792,7 @@ DecimalFormat::format(int64_t number, |
FieldPositionIterator* posIter, |
UErrorCode& status) const |
{ |
- FieldPositionIteratorHandler handler(posIter, status); |
- return _format(number, appendTo, handler, status); |
-} |
- |
-UnicodeString& |
-DecimalFormat::_format(int64_t number, |
- UnicodeString& appendTo, |
- FieldPositionHandler& handler, |
- UErrorCode &status) const |
-{ |
- // Bottleneck function for formatting int64_t |
- if (U_FAILURE(status)) { |
- return appendTo; |
- } |
- |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- // const UnicodeString *posPrefix = fPosPrefixPattern; |
- // const UnicodeString *posSuffix = fPosSuffixPattern; |
- // const UnicodeString *negSuffix = fNegSuffixPattern; |
- |
- const DecimalFormatInternal &data = internalData(fReserved); |
- |
-#ifdef FMT_DEBUG |
- data.dump(); |
- printf("fastpath? [%d]\n", number); |
-#endif |
- |
- if( data.fFastFormatStatus==kFastpathYES || |
- data.fFastFormatStatus==kFastpathMAYBE) { |
- int32_t noGroupingThreshold = 0; |
- |
-#define kZero 0x0030 |
- const int32_t MAX_IDX = MAX_DIGITS+2; |
- UChar outputStr[MAX_IDX]; |
- int32_t destIdx = MAX_IDX; |
- outputStr[--destIdx] = 0; // term |
- |
- if (data.fFastFormatStatus==kFastpathMAYBE) { |
- noGroupingThreshold = destIdx - fGroupingSize; |
- } |
- int64_t n = number; |
- if (number < 1) { |
- // Negative numbers are slightly larger than positive |
- // output the first digit (or the leading zero) |
- outputStr[--destIdx] = (-(n % 10) + kZero); |
- n /= -10; |
- } |
- // get any remaining digits |
- while (n > 0) { |
- if (destIdx == noGroupingThreshold) { |
- goto slowPath; |
- } |
- outputStr[--destIdx] = (n % 10) + kZero; |
- n /= 10; |
- } |
- |
- // Slide the number to the start of the output str |
- U_ASSERT(destIdx >= 0); |
- int32_t length = MAX_IDX - destIdx -1; |
- /*int32_t prefixLen = */ appendAffix(appendTo, static_cast<double>(number), handler, number<0, TRUE); |
- int32_t maxIntDig = getMaximumIntegerDigits(); |
- int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinned to max int digits |
- |
- if(length>maxIntDig && fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS)) { |
- status = U_ILLEGAL_ARGUMENT_ERROR; |
- } |
- |
- int32_t prependZero = getMinimumIntegerDigits() - destlength; |
- |
-#ifdef FMT_DEBUG |
- printf("prependZero=%d, length=%d, minintdig=%d maxintdig=%d destlength=%d skip=%d\n", prependZero, length, getMinimumIntegerDigits(), maxIntDig, destlength, length-destlength); |
-#endif |
- int32_t intBegin = appendTo.length(); |
- |
- while((prependZero--)>0) { |
- appendTo.append((UChar)0x0030); // '0' |
- } |
- |
- appendTo.append(outputStr+destIdx+ |
- (length-destlength), // skip any leading digits |
- destlength); |
- handler.addAttribute(kIntegerField, intBegin, appendTo.length()); |
- |
- /*int32_t suffixLen =*/ appendAffix(appendTo, static_cast<double>(number), handler, number<0, FALSE); |
- |
- //outputStr[length]=0; |
- |
-#ifdef FMT_DEBUG |
- printf("Writing [%s] length [%d] max %d for [%d]\n", outputStr+destIdx, length, MAX_IDX, number); |
-#endif |
- |
-#undef kZero |
- |
- return appendTo; |
- } // end fastpath |
-#endif |
- slowPath: |
- |
- // Else the slow way - via DigitList |
- DigitList digits; |
- digits.set(number); |
- return _format(digits, appendTo, handler, status); |
+ return fImpl->format(number, appendTo, posIter, status); |
} |
//------------------------------------------------------------------------------ |
@@ -1503,8 +803,7 @@ DecimalFormat::format( double number, |
FieldPosition& fieldPosition) const |
{ |
UErrorCode status = U_ZERO_ERROR; /* ignored */ |
- FieldPositionOnlyHandler handler(fieldPosition); |
- return _format(number, appendTo, handler, status); |
+ return fImpl->format(number, appendTo, fieldPosition, status); |
} |
UnicodeString& |
@@ -1513,8 +812,7 @@ DecimalFormat::format( double number, |
FieldPosition& fieldPosition, |
UErrorCode& status) const |
{ |
- FieldPositionOnlyHandler handler(fieldPosition); |
- return _format(number, appendTo, handler, status); |
+ return fImpl->format(number, appendTo, fieldPosition, status); |
} |
UnicodeString& |
@@ -1523,38 +821,7 @@ DecimalFormat::format( double number, |
FieldPositionIterator* posIter, |
UErrorCode& status) const |
{ |
- FieldPositionIteratorHandler handler(posIter, status); |
- return _format(number, appendTo, handler, status); |
-} |
- |
-UnicodeString& |
-DecimalFormat::_format( double number, |
- UnicodeString& appendTo, |
- FieldPositionHandler& handler, |
- UErrorCode &status) const |
-{ |
- if (U_FAILURE(status)) { |
- return appendTo; |
- } |
- // Special case for NaN, sets the begin and end index to be the |
- // the string length of localized name of NaN. |
- // TODO: let NaNs go through DigitList. |
- if (uprv_isNaN(number)) |
- { |
- int begin = appendTo.length(); |
- appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); |
- |
- handler.addAttribute(kIntegerField, begin, appendTo.length()); |
- |
- addPadding(appendTo, handler, 0, 0); |
- return appendTo; |
- } |
- |
- DigitList digits; |
- digits.set(number); |
- _format(digits, appendTo, handler, status); |
- // No way to return status from here. |
- return appendTo; |
+ return fImpl->format(number, appendTo, posIter, status); |
} |
//------------------------------------------------------------------------------ |
@@ -1566,56 +833,8 @@ DecimalFormat::format(const StringPiece &number, |
FieldPositionIterator *posIter, |
UErrorCode &status) const |
{ |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- // don't bother if the int64 path is not optimized |
- int32_t len = number.length(); |
- |
- if(len>0&&len<10) { /* 10 or more digits may not be an int64 */ |
- const char *data = number.data(); |
- int64_t num = 0; |
- UBool neg = FALSE; |
- UBool ok = TRUE; |
- |
- int32_t start = 0; |
- |
- if(data[start]=='+') { |
- start++; |
- } else if(data[start]=='-') { |
- neg=TRUE; |
- start++; |
- } |
- |
- int32_t place = 1; /* 1, 10, ... */ |
- for(int32_t i=len-1;i>=start;i--) { |
- if(data[i]>='0'&&data[i]<='9') { |
- num+=place*(int64_t)(data[i]-'0'); |
- } else { |
- ok=FALSE; |
- break; |
- } |
- place *= 10; |
- } |
- |
- if(ok) { |
- if(neg) { |
- num = -num;// add minus bit |
- } |
- // format as int64_t |
- return format(num, toAppendTo, posIter, status); |
- } |
- // else fall through |
- } |
-#endif |
- |
- DigitList dnum; |
- dnum.set(number, status); |
- if (U_FAILURE(status)) { |
- return toAppendTo; |
- } |
- FieldPositionIteratorHandler handler(posIter, status); |
- _format(dnum, toAppendTo, handler, status); |
- return toAppendTo; |
-} |
+ return fImpl->format(number, toAppendTo, posIter, status); |
+} |
UnicodeString& |
@@ -1623,577 +842,43 @@ DecimalFormat::format(const DigitList &number, |
UnicodeString &appendTo, |
FieldPositionIterator *posIter, |
UErrorCode &status) const { |
- FieldPositionIteratorHandler handler(posIter, status); |
- _format(number, appendTo, handler, status); |
- return appendTo; |
+ return fImpl->format(number, appendTo, posIter, status); |
} |
- |
UnicodeString& |
DecimalFormat::format(const DigitList &number, |
UnicodeString& appendTo, |
FieldPosition& pos, |
UErrorCode &status) const { |
- FieldPositionOnlyHandler handler(pos); |
- _format(number, appendTo, handler, status); |
- return appendTo; |
-} |
- |
-DigitList& |
-DecimalFormat::_round(const DigitList &number, DigitList &adjustedNum, UBool& isNegative, UErrorCode &status) const { |
- if (U_FAILURE(status)) { |
- return adjustedNum; |
- } |
- |
- // note: number and adjustedNum may refer to the same DigitList, in cases where a copy |
- // is not needed by the caller. |
- |
- adjustedNum = number; |
- isNegative = false; |
- if (number.isNaN()) { |
- return adjustedNum; |
- } |
- |
- // Do this BEFORE checking to see if value is infinite or negative! Sets the |
- // begin and end index to be length of the string composed of |
- // localized name of Infinite and the positive/negative localized |
- // signs. |
- |
- adjustedNum.setRoundingMode(fRoundingMode); |
- if (fMultiplier != NULL) { |
- adjustedNum.mult(*fMultiplier, status); |
- if (U_FAILURE(status)) { |
- return adjustedNum; |
- } |
- } |
- |
- if (fScale != 0) { |
- DigitList ten; |
- ten.set((int32_t)10); |
- if (fScale > 0) { |
- for (int32_t i = fScale ; i > 0 ; i--) { |
- adjustedNum.mult(ten, status); |
- if (U_FAILURE(status)) { |
- return adjustedNum; |
- } |
- } |
- } else { |
- for (int32_t i = fScale ; i < 0 ; i++) { |
- adjustedNum.div(ten, status); |
- if (U_FAILURE(status)) { |
- return adjustedNum; |
- } |
- } |
- } |
- } |
- |
- /* |
- * Note: sign is important for zero as well as non-zero numbers. |
- * Proper detection of -0.0 is needed to deal with the |
- * issues raised by bugs 4106658, 4106667, and 4147706. Liu 7/6/98. |
- */ |
- isNegative = !adjustedNum.isPositive(); |
- |
- // Apply rounding after multiplier |
- |
- adjustedNum.fContext.status &= ~DEC_Inexact; |
- if (fRoundingIncrement != NULL) { |
- adjustedNum.div(*fRoundingIncrement, status); |
- adjustedNum.toIntegralValue(); |
- adjustedNum.mult(*fRoundingIncrement, status); |
- adjustedNum.trim(); |
- if (U_FAILURE(status)) { |
- return adjustedNum; |
- } |
- } |
- if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) { |
- status = U_FORMAT_INEXACT_ERROR; |
- return adjustedNum; |
- } |
- |
- if (adjustedNum.isInfinite()) { |
- return adjustedNum; |
- } |
- |
- if (fUseExponentialNotation || areSignificantDigitsUsed()) { |
- int32_t sigDigits = precision(); |
- if (sigDigits > 0) { |
- adjustedNum.round(sigDigits); |
- // Travis Keep (21/2/2014): Calling round on a digitList does not necessarily |
- // preserve the sign of that digit list. Preserving the sign is especially |
- // important when formatting -0.0 for instance. Not preserving the sign seems |
- // like a bug because I cannot think of any case where the sign would actually |
- // have to change when rounding. For now, we preserve the sign by setting the |
- // positive attribute directly. |
- adjustedNum.setPositive(!isNegative); |
- } |
- } else { |
- // Fixed point format. Round to a set number of fraction digits. |
- int32_t numFractionDigits = precision(); |
- adjustedNum.roundFixedPoint(numFractionDigits); |
- } |
- if (fRoundingMode == kRoundUnnecessary && (adjustedNum.fContext.status & DEC_Inexact)) { |
- status = U_FORMAT_INEXACT_ERROR; |
- return adjustedNum; |
- } |
- return adjustedNum; |
+ return fImpl->format(number, appendTo, pos, status); |
} |
UnicodeString& |
-DecimalFormat::_format(const DigitList &number, |
- UnicodeString& appendTo, |
- FieldPositionHandler& handler, |
- UErrorCode &status) const |
-{ |
- if (U_FAILURE(status)) { |
- return appendTo; |
- } |
- |
- // Special case for NaN, sets the begin and end index to be the |
- // the string length of localized name of NaN. |
- if (number.isNaN()) |
- { |
- int begin = appendTo.length(); |
- appendTo += getConstSymbol(DecimalFormatSymbols::kNaNSymbol); |
- |
- handler.addAttribute(kIntegerField, begin, appendTo.length()); |
- |
- addPadding(appendTo, handler, 0, 0); |
- return appendTo; |
- } |
- |
- DigitList adjustedNum; |
- UBool isNegative; |
- _round(number, adjustedNum, isNegative, status); |
- if (U_FAILURE(status)) { |
- return appendTo; |
- } |
- |
- // Special case for INFINITE, |
- if (adjustedNum.isInfinite()) { |
- int32_t prefixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, TRUE); |
- |
- int begin = appendTo.length(); |
- appendTo += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); |
- |
- handler.addAttribute(kIntegerField, begin, appendTo.length()); |
- |
- int32_t suffixLen = appendAffix(appendTo, adjustedNum.getDouble(), handler, isNegative, FALSE); |
- |
- addPadding(appendTo, handler, prefixLen, suffixLen); |
- return appendTo; |
- } |
- return subformat(appendTo, handler, adjustedNum, FALSE, status); |
-} |
- |
-/** |
- * Return true if a grouping separator belongs at the given |
- * position, based on whether grouping is in use and the values of |
- * the primary and secondary grouping interval. |
- * @param pos the number of integer digits to the right of |
- * the current position. Zero indicates the position after the |
- * rightmost integer digit. |
- * @return true if a grouping character belongs at the current |
- * position. |
- */ |
-UBool DecimalFormat::isGroupingPosition(int32_t pos) const { |
- UBool result = FALSE; |
- if (isGroupingUsed() && (pos > 0) && (fGroupingSize > 0)) { |
- if ((fGroupingSize2 > 0) && (pos > fGroupingSize)) { |
- result = ((pos - fGroupingSize) % fGroupingSize2) == 0; |
- } else { |
- result = pos % fGroupingSize == 0; |
- } |
- } |
- return result; |
+DecimalFormat::format(const VisibleDigitsWithExponent &number, |
+ UnicodeString &appendTo, |
+ FieldPositionIterator *posIter, |
+ UErrorCode &status) const { |
+ return fImpl->format(number, appendTo, posIter, status); |
} |
-//------------------------------------------------------------------------------ |
-/** |
- * Complete the formatting of a finite number. On entry, the DigitList must |
- * be filled in with the correct digits. |
- */ |
UnicodeString& |
-DecimalFormat::subformat(UnicodeString& appendTo, |
- FieldPositionHandler& handler, |
- DigitList& digits, |
- UBool isInteger, |
- UErrorCode& status) const |
-{ |
- // char zero = '0'; |
- // DigitList returns digits as '0' thru '9', so we will need to |
- // always need to subtract the character 0 to get the numeric value to use for indexing. |
- |
- UChar32 localizedDigits[10]; |
- localizedDigits[0] = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); |
- localizedDigits[1] = getConstSymbol(DecimalFormatSymbols::kOneDigitSymbol).char32At(0); |
- localizedDigits[2] = getConstSymbol(DecimalFormatSymbols::kTwoDigitSymbol).char32At(0); |
- localizedDigits[3] = getConstSymbol(DecimalFormatSymbols::kThreeDigitSymbol).char32At(0); |
- localizedDigits[4] = getConstSymbol(DecimalFormatSymbols::kFourDigitSymbol).char32At(0); |
- localizedDigits[5] = getConstSymbol(DecimalFormatSymbols::kFiveDigitSymbol).char32At(0); |
- localizedDigits[6] = getConstSymbol(DecimalFormatSymbols::kSixDigitSymbol).char32At(0); |
- localizedDigits[7] = getConstSymbol(DecimalFormatSymbols::kSevenDigitSymbol).char32At(0); |
- localizedDigits[8] = getConstSymbol(DecimalFormatSymbols::kEightDigitSymbol).char32At(0); |
- localizedDigits[9] = getConstSymbol(DecimalFormatSymbols::kNineDigitSymbol).char32At(0); |
- |
- const UnicodeString *grouping ; |
- if(fCurrencySignCount == fgCurrencySignCountZero) { |
- grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol); |
- }else{ |
- grouping = &getConstSymbol(DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol); |
- } |
- const UnicodeString *decimal; |
- if(fCurrencySignCount == fgCurrencySignCountZero) { |
- decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); |
- } else { |
- decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); |
- } |
- UBool useSigDig = areSignificantDigitsUsed(); |
- int32_t maxIntDig = getMaximumIntegerDigits(); |
- int32_t minIntDig = getMinimumIntegerDigits(); |
- |
- // Appends the prefix. |
- double doubleValue = digits.getDouble(); |
- int32_t prefixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), TRUE); |
- |
- if (fUseExponentialNotation) |
- { |
- int currentLength = appendTo.length(); |
- int intBegin = currentLength; |
- int intEnd = -1; |
- int fracBegin = -1; |
- |
- int32_t minFracDig = 0; |
- if (useSigDig) { |
- maxIntDig = minIntDig = 1; |
- minFracDig = getMinimumSignificantDigits() - 1; |
- } else { |
- minFracDig = getMinimumFractionDigits(); |
- if (maxIntDig > kMaxScientificIntegerDigits) { |
- maxIntDig = 1; |
- if (maxIntDig < minIntDig) { |
- maxIntDig = minIntDig; |
- } |
- } |
- if (maxIntDig > minIntDig) { |
- minIntDig = 1; |
- } |
- } |
- |
- // Minimum integer digits are handled in exponential format by |
- // adjusting the exponent. For example, 0.01234 with 3 minimum |
- // integer digits is "123.4E-4". |
- |
- // Maximum integer digits are interpreted as indicating the |
- // repeating range. This is useful for engineering notation, in |
- // which the exponent is restricted to a multiple of 3. For |
- // example, 0.01234 with 3 maximum integer digits is "12.34e-3". |
- // If maximum integer digits are defined and are larger than |
- // minimum integer digits, then minimum integer digits are |
- // ignored. |
- digits.reduce(); // Removes trailing zero digits. |
- int32_t exponent = digits.getDecimalAt(); |
- if (maxIntDig > 1 && maxIntDig != minIntDig) { |
- // A exponent increment is defined; adjust to it. |
- exponent = (exponent > 0) ? (exponent - 1) / maxIntDig |
- : (exponent / maxIntDig) - 1; |
- exponent *= maxIntDig; |
- } else { |
- // No exponent increment is defined; use minimum integer digits. |
- // If none is specified, as in "#E0", generate 1 integer digit. |
- exponent -= (minIntDig > 0 || minFracDig > 0) |
- ? minIntDig : 1; |
- } |
- |
- // We now output a minimum number of digits, and more if there |
- // are more digits, up to the maximum number of digits. We |
- // place the decimal point after the "integer" digits, which |
- // are the first (decimalAt - exponent) digits. |
- int32_t minimumDigits = minIntDig + minFracDig; |
- // The number of integer digits is handled specially if the number |
- // is zero, since then there may be no digits. |
- int32_t integerDigits = digits.isZero() ? minIntDig : |
- digits.getDecimalAt() - exponent; |
- int32_t totalDigits = digits.getCount(); |
- if (minimumDigits > totalDigits) |
- totalDigits = minimumDigits; |
- if (integerDigits > totalDigits) |
- totalDigits = integerDigits; |
- |
- // totalDigits records total number of digits needs to be processed |
- int32_t i; |
- for (i=0; i<totalDigits; ++i) |
- { |
- if (i == integerDigits) |
- { |
- intEnd = appendTo.length(); |
- handler.addAttribute(kIntegerField, intBegin, intEnd); |
- |
- appendTo += *decimal; |
- |
- fracBegin = appendTo.length(); |
- handler.addAttribute(kDecimalSeparatorField, fracBegin - 1, fracBegin); |
- } |
- // Restores the digit character or pads the buffer with zeros. |
- UChar32 c = (UChar32)((i < digits.getCount()) ? |
- localizedDigits[digits.getDigitValue(i)] : |
- localizedDigits[0]); |
- appendTo += c; |
- } |
- |
- currentLength = appendTo.length(); |
- |
- if (intEnd < 0) { |
- handler.addAttribute(kIntegerField, intBegin, currentLength); |
- } |
- if (fracBegin > 0) { |
- handler.addAttribute(kFractionField, fracBegin, currentLength); |
- } |
- |
- // The exponent is output using the pattern-specified minimum |
- // exponent digits. There is no maximum limit to the exponent |
- // digits, since truncating the exponent would appendTo in an |
- // unacceptable inaccuracy. |
- appendTo += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); |
- |
- handler.addAttribute(kExponentSymbolField, currentLength, appendTo.length()); |
- currentLength = appendTo.length(); |
- |
- // For zero values, we force the exponent to zero. We |
- // must do this here, and not earlier, because the value |
- // is used to determine integer digit count above. |
- if (digits.isZero()) |
- exponent = 0; |
- |
- if (exponent < 0) { |
- appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
- handler.addAttribute(kExponentSignField, currentLength, appendTo.length()); |
- } else if (fExponentSignAlwaysShown) { |
- appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
- handler.addAttribute(kExponentSignField, currentLength, appendTo.length()); |
- } |
- |
- currentLength = appendTo.length(); |
- |
- DigitList expDigits; |
- expDigits.set(exponent); |
- { |
- int expDig = fMinExponentDigits; |
- if (fUseExponentialNotation && expDig < 1) { |
- expDig = 1; |
- } |
- for (i=expDigits.getDecimalAt(); i<expDig; ++i) |
- appendTo += (localizedDigits[0]); |
- } |
- for (i=0; i<expDigits.getDecimalAt(); ++i) |
- { |
- UChar32 c = (UChar32)((i < expDigits.getCount()) ? |
- localizedDigits[expDigits.getDigitValue(i)] : |
- localizedDigits[0]); |
- appendTo += c; |
- } |
- |
- handler.addAttribute(kExponentField, currentLength, appendTo.length()); |
- } |
- else // Not using exponential notation |
- { |
- int currentLength = appendTo.length(); |
- int intBegin = currentLength; |
- |
- int32_t sigCount = 0; |
- int32_t minSigDig = getMinimumSignificantDigits(); |
- int32_t maxSigDig = getMaximumSignificantDigits(); |
- if (!useSigDig) { |
- minSigDig = 0; |
- maxSigDig = INT32_MAX; |
- } |
- |
- // Output the integer portion. Here 'count' is the total |
- // number of integer digits we will display, including both |
- // leading zeros required to satisfy getMinimumIntegerDigits, |
- // and actual digits present in the number. |
- int32_t count = useSigDig ? |
- _max(1, digits.getDecimalAt()) : minIntDig; |
- if (digits.getDecimalAt() > 0 && count < digits.getDecimalAt()) { |
- count = digits.getDecimalAt(); |
- } |
- |
- // Handle the case where getMaximumIntegerDigits() is smaller |
- // than the real number of integer digits. If this is so, we |
- // output the least significant max integer digits. For example, |
- // the value 1997 printed with 2 max integer digits is just "97". |
- |
- int32_t digitIndex = 0; // Index into digitList.fDigits[] |
- if (count > maxIntDig && maxIntDig >= 0) { |
- count = maxIntDig; |
- digitIndex = digits.getDecimalAt() - count; |
- if(fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS)) { |
- status = U_ILLEGAL_ARGUMENT_ERROR; |
- } |
- } |
- |
- int32_t sizeBeforeIntegerPart = appendTo.length(); |
- |
- int32_t i; |
- for (i=count-1; i>=0; --i) |
- { |
- if (i < digits.getDecimalAt() && digitIndex < digits.getCount() && |
- sigCount < maxSigDig) { |
- // Output a real digit |
- appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)]; |
- ++sigCount; |
- } |
- else |
- { |
- // Output a zero (leading or trailing) |
- appendTo += localizedDigits[0]; |
- if (sigCount > 0) { |
- ++sigCount; |
- } |
- } |
- |
- // Output grouping separator if necessary. |
- if (isGroupingPosition(i)) { |
- currentLength = appendTo.length(); |
- appendTo.append(*grouping); |
- handler.addAttribute(kGroupingSeparatorField, currentLength, appendTo.length()); |
- } |
- } |
- |
- // This handles the special case of formatting 0. For zero only, we count the |
- // zero to the left of the decimal point as one signficant digit. Ordinarily we |
- // do not count any leading 0's as significant. If the number we are formatting |
- // is not zero, then either sigCount or digits.getCount() will be non-zero. |
- if (sigCount == 0 && digits.getCount() == 0) { |
- sigCount = 1; |
- } |
- |
- // TODO(dlf): this looks like it was a bug, we marked the int field as ending |
- // before the zero was generated. |
- // Record field information for caller. |
- // if (fieldPosition.getField() == NumberFormat::kIntegerField) |
- // fieldPosition.setEndIndex(appendTo.length()); |
- |
- // Determine whether or not there are any printable fractional |
- // digits. If we've used up the digits we know there aren't. |
- UBool fractionPresent = (!isInteger && digitIndex < digits.getCount()) || |
- (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0)); |
- |
- // If there is no fraction present, and we haven't printed any |
- // integer digits, then print a zero. Otherwise we won't print |
- // _any_ digits, and we won't be able to parse this string. |
- if (!fractionPresent && appendTo.length() == sizeBeforeIntegerPart) |
- appendTo += localizedDigits[0]; |
- |
- currentLength = appendTo.length(); |
- handler.addAttribute(kIntegerField, intBegin, currentLength); |
- |
- // Output the decimal separator if we always do so. |
- if (fDecimalSeparatorAlwaysShown || fractionPresent) { |
- appendTo += *decimal; |
- handler.addAttribute(kDecimalSeparatorField, currentLength, appendTo.length()); |
- currentLength = appendTo.length(); |
- } |
- |
- int fracBegin = currentLength; |
- |
- count = useSigDig ? INT32_MAX : getMaximumFractionDigits(); |
- if (useSigDig && (sigCount == maxSigDig || |
- (sigCount >= minSigDig && digitIndex == digits.getCount()))) { |
- count = 0; |
- } |
- |
- for (i=0; i < count; ++i) { |
- // Here is where we escape from the loop. We escape |
- // if we've output the maximum fraction digits |
- // (specified in the for expression above). We also |
- // stop when we've output the minimum digits and |
- // either: we have an integer, so there is no |
- // fractional stuff to display, or we're out of |
- // significant digits. |
- if (!useSigDig && i >= getMinimumFractionDigits() && |
- (isInteger || digitIndex >= digits.getCount())) { |
- break; |
- } |
- |
- // Output leading fractional zeros. These are zeros |
- // that come after the decimal but before any |
- // significant digits. These are only output if |
- // abs(number being formatted) < 1.0. |
- if (-1-i > (digits.getDecimalAt()-1)) { |
- appendTo += localizedDigits[0]; |
- continue; |
- } |
- |
- // Output a digit, if we have any precision left, or a |
- // zero if we don't. We don't want to output noise digits. |
- if (!isInteger && digitIndex < digits.getCount()) { |
- appendTo += (UChar32)localizedDigits[digits.getDigitValue(digitIndex++)]; |
- } else { |
- appendTo += localizedDigits[0]; |
- } |
- |
- // If we reach the maximum number of significant |
- // digits, or if we output all the real digits and |
- // reach the minimum, then we are done. |
- ++sigCount; |
- if (useSigDig && |
- (sigCount == maxSigDig || |
- (digitIndex == digits.getCount() && sigCount >= minSigDig))) { |
- break; |
- } |
- } |
- |
- handler.addAttribute(kFractionField, fracBegin, appendTo.length()); |
- } |
- |
- int32_t suffixLen = appendAffix(appendTo, doubleValue, handler, !digits.isPositive(), FALSE); |
- |
- addPadding(appendTo, handler, prefixLen, suffixLen); |
- return appendTo; |
+DecimalFormat::format(const VisibleDigitsWithExponent &number, |
+ UnicodeString& appendTo, |
+ FieldPosition& pos, |
+ UErrorCode &status) const { |
+ return fImpl->format(number, appendTo, pos, status); |
} |
-/** |
- * Inserts the character fPad as needed to expand result to fFormatWidth. |
- * @param result the string to be padded |
- */ |
-void DecimalFormat::addPadding(UnicodeString& appendTo, |
- FieldPositionHandler& handler, |
- int32_t prefixLen, |
- int32_t suffixLen) const |
-{ |
- if (fFormatWidth > 0) { |
- int32_t len = fFormatWidth - appendTo.length(); |
- if (len > 0) { |
- UnicodeString padding; |
- for (int32_t i=0; i<len; ++i) { |
- padding += fPad; |
- } |
- switch (fPadPosition) { |
- case kPadAfterPrefix: |
- appendTo.insert(prefixLen, padding); |
- break; |
- case kPadBeforePrefix: |
- appendTo.insert(0, padding); |
- break; |
- case kPadBeforeSuffix: |
- appendTo.insert(appendTo.length() - suffixLen, padding); |
- break; |
- case kPadAfterSuffix: |
- appendTo += padding; |
- break; |
- } |
- if (fPadPosition == kPadBeforePrefix || fPadPosition == kPadAfterPrefix) { |
- handler.shiftLast(len); |
- } |
- } |
- } |
+DigitList& |
+DecimalFormat::_round(const DigitList& number, DigitList& adjustedNum, UBool& isNegative, UErrorCode& status) const { |
+ adjustedNum = number; |
+ fImpl->round(adjustedNum, status); |
+ isNegative = !adjustedNum.isPositive(); |
+ return adjustedNum; |
} |
-//------------------------------------------------------------------------------ |
- |
void |
DecimalFormat::parse(const UnicodeString& text, |
Formattable& result, |
@@ -2209,7 +894,7 @@ CurrencyAmount* DecimalFormat::parseCurrency(const UnicodeString& text, |
parse(text, parseResult, pos, curbuf); |
if (pos.getIndex() != start) { |
UErrorCode ec = U_ZERO_ERROR; |
- LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curbuf, ec)); |
+ LocalPointer<CurrencyAmount> currAmt(new CurrencyAmount(parseResult, curbuf, ec), ec); |
if (U_FAILURE(ec)) { |
pos.setIndex(start); // indicate failure |
} else { |
@@ -2250,10 +935,12 @@ void DecimalFormat::parse(const UnicodeString& text, |
} |
// Handle NaN as a special case: |
+ int32_t formatWidth = fImpl->getOldFormatWidth(); |
// Skip padding characters, if around prefix |
- if (fFormatWidth > 0 && (fPadPosition == kPadBeforePrefix || |
- fPadPosition == kPadAfterPrefix)) { |
+ if (formatWidth > 0 && ( |
+ fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix || |
+ fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix)) { |
i = skipPadding(text, i); |
} |
@@ -2263,13 +950,12 @@ void DecimalFormat::parse(const UnicodeString& text, |
} |
// If the text is composed of the representation of NaN, returns NaN.length |
- const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol); |
+ const UnicodeString *nan = &fImpl->getConstSymbol(DecimalFormatSymbols::kNaNSymbol); |
int32_t nanLen = (text.compare(i, nan->length(), *nan) |
? 0 : nan->length()); |
if (nanLen) { |
i += nanLen; |
- if (fFormatWidth > 0 && (fPadPosition == kPadBeforeSuffix || |
- fPadPosition == kPadAfterSuffix)) { |
+ if (formatWidth > 0 && (fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix || fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix)) { |
i = skipPadding(text, i); |
} |
parsePosition.setIndex(i); |
@@ -2289,15 +975,17 @@ void DecimalFormat::parse(const UnicodeString& text, |
return; // no way to report error from here. |
} |
- if (fCurrencySignCount != fgCurrencySignCountZero) { |
+ if (fImpl->fMonetary) { |
if (!parseForCurrency(text, parsePosition, *digits, |
status, currency)) { |
return; |
} |
} else { |
if (!subparse(text, |
- fNegPrefixPattern, fNegSuffixPattern, |
- fPosPrefixPattern, fPosSuffixPattern, |
+ &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(), |
+ &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(), |
+ &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(), |
+ &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(), |
FALSE, UCURR_SYMBOL_NAME, |
parsePosition, *digits, status, currency)) { |
debug("!subparse(...) - rewind"); |
@@ -2315,21 +1003,21 @@ void DecimalFormat::parse(const UnicodeString& text, |
else { |
- if (fMultiplier != NULL) { |
+ if (!fImpl->fMultiplier.isZero()) { |
UErrorCode ec = U_ZERO_ERROR; |
- digits->div(*fMultiplier, ec); |
+ digits->div(fImpl->fMultiplier, ec); |
} |
- if (fScale != 0) { |
+ if (fImpl->fScale != 0) { |
DigitList ten; |
ten.set((int32_t)10); |
- if (fScale > 0) { |
- for (int32_t i = fScale; i > 0; i--) { |
+ if (fImpl->fScale > 0) { |
+ for (int32_t i = fImpl->fScale; i > 0; i--) { |
UErrorCode ec = U_ZERO_ERROR; |
digits->div(ten,ec); |
} |
} else { |
- for (int32_t i = fScale; i < 0; i++) { |
+ for (int32_t i = fImpl->fScale; i < 0; i++) { |
UErrorCode ec = U_ZERO_ERROR; |
digits->mult(ten,ec); |
} |
@@ -2354,6 +1042,15 @@ DecimalFormat::parseForCurrency(const UnicodeString& text, |
DigitList& digits, |
UBool* status, |
UChar* currency) const { |
+ UnicodeString positivePrefix; |
+ UnicodeString positiveSuffix; |
+ UnicodeString negativePrefix; |
+ UnicodeString negativeSuffix; |
+ fImpl->fPositivePrefixPattern.toString(positivePrefix); |
+ fImpl->fPositiveSuffixPattern.toString(positiveSuffix); |
+ fImpl->fNegativePrefixPattern.toString(negativePrefix); |
+ fImpl->fNegativeSuffixPattern.toString(negativeSuffix); |
+ |
int origPos = parsePosition.getIndex(); |
int maxPosIndex = origPos; |
int maxErrorPos = -1; |
@@ -2367,14 +1064,14 @@ DecimalFormat::parseForCurrency(const UnicodeString& text, |
UBool found; |
if (fStyle == UNUM_CURRENCY_PLURAL) { |
found = subparse(text, |
- fNegPrefixPattern, fNegSuffixPattern, |
- fPosPrefixPattern, fPosSuffixPattern, |
+ &negativePrefix, &negativeSuffix, |
+ &positivePrefix, &positiveSuffix, |
TRUE, UCURR_LONG_NAME, |
tmpPos, tmpDigitList, tmpStatus, currency); |
} else { |
found = subparse(text, |
- fNegPrefixPattern, fNegSuffixPattern, |
- fPosPrefixPattern, fPosSuffixPattern, |
+ &negativePrefix, &negativeSuffix, |
+ &positivePrefix, &positiveSuffix, |
TRUE, UCURR_SYMBOL_NAME, |
tmpPos, tmpDigitList, tmpStatus, currency); |
} |
@@ -2391,7 +1088,7 @@ DecimalFormat::parseForCurrency(const UnicodeString& text, |
} |
// Then, parse against affix patterns. |
// Those are currency patterns and currency plural patterns. |
- int32_t pos = -1; |
+ int32_t pos = UHASH_FIRST; |
const UHashElement* element = NULL; |
while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { |
const UHashTok valueTok = element->value; |
@@ -2446,8 +1143,10 @@ DecimalFormat::parseForCurrency(const UnicodeString& text, |
// Disable complex currency parsing and try it again. |
UBool result = subparse(text, |
- &fNegativePrefix, &fNegativeSuffix, |
- &fPositivePrefix, &fPositiveSuffix, |
+ &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(), |
+ &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(), |
+ &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(), |
+ &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(), |
FALSE /* disable complex currency parsing */, UCURR_SYMBOL_NAME, |
tmpPos_2, tmpDigitList_2, tmpStatus_2, |
currency); |
@@ -2518,9 +1217,10 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
int32_t oldStart = position; |
int32_t textLength = text.length(); // One less pointer to follow |
UBool strictParse = !isLenient(); |
- UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); |
- const UnicodeString *groupingString = &getConstSymbol(fCurrencySignCount == fgCurrencySignCountZero ? |
- DecimalFormatSymbols::kGroupingSeparatorSymbol : DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol); |
+ UChar32 zero = fImpl->getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); |
+ const UnicodeString *groupingString = &fImpl->getConstSymbol( |
+ !fImpl->fMonetary ? |
+ DecimalFormatSymbols::kGroupingSeparatorSymbol : DecimalFormatSymbols::kMonetaryGroupingSeparatorSymbol); |
UChar32 groupingChar = groupingString->char32At(0); |
int32_t groupingStringLength = groupingString->length(); |
int32_t groupingCharLength = U16_LENGTH(groupingChar); |
@@ -2535,15 +1235,11 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
DBGAPPD(posPrefix); |
DBGAPPD(posSuffix); |
debugout(s); |
- printf("currencyParsing=%d, fFormatWidth=%d, isParseIntegerOnly=%c text.length=%d negPrefLen=%d\n", currencyParsing, fFormatWidth, (isParseIntegerOnly())?'Y':'N', text.length(), negPrefix!=NULL?negPrefix->length():-1); |
#endif |
UBool fastParseOk = false; /* TRUE iff fast parse is OK */ |
// UBool fastParseHadDecimal = FALSE; /* true if fast parse saw a decimal point. */ |
- const DecimalFormatInternal &data = internalData(fReserved); |
- if((data.fFastParseStatus==kFastpathYES) && |
- fCurrencySignCount == fgCurrencySignCountZero && |
- // (negPrefix!=NULL&&negPrefix->isEmpty()) || |
+ if((fImpl->isParseFastpath()) && !fImpl->fMonetary && |
text.length()>0 && |
text.length()<32 && |
(posPrefix==NULL||posPrefix->isEmpty()) && |
@@ -2555,7 +1251,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
int l=text.length(); |
int digitCount=0; |
UChar32 ch = text.char32At(j); |
- const UnicodeString *decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); |
+ const UnicodeString *decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); |
UChar32 decimalChar = 0; |
UBool intOnly = FALSE; |
UChar32 lookForGroup = (groupingUsed&&intOnly&&strictParse)?groupingChar:0; |
@@ -2617,9 +1313,6 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
if( |
((j==l)||intOnly) // end OR only parsing integer |
&& (digitCount>0)) { // and have at least one digit |
-#ifdef FMT_DEBUG |
- printf("PP -> %d, good = [%s] digitcount=%d, fGroupingSize=%d fGroupingSize2=%d!\n", j, parsedNum.data(), digitCount, fGroupingSize, fGroupingSize2); |
-#endif |
fastParseOk=true; // Fast parse OK! |
#ifdef SKIP_OPT |
@@ -2641,7 +1334,6 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
} else { |
#ifdef FMT_DEBUG |
printf("Could not fastpath parse. "); |
- printf("fFormatWidth=%d ", fFormatWidth); |
printf("text.length()=%d ", text.length()); |
printf("posPrefix=%p posSuffix=%p ", posPrefix, posSuffix); |
@@ -2649,14 +1341,18 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
#endif |
} |
+ UnicodeString formatPattern; |
+ toPattern(formatPattern); |
+ |
if(!fastParseOk |
#if UCONFIG_HAVE_PARSEALLINPUT |
&& fParseAllInput!=UNUM_YES |
#endif |
) |
{ |
+ int32_t formatWidth = fImpl->getOldFormatWidth(); |
// Match padding before prefix |
- if (fFormatWidth > 0 && fPadPosition == kPadBeforePrefix) { |
+ if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforePrefix) { |
position = skipPadding(text, position); |
} |
@@ -2685,7 +1381,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
} |
// Match padding before prefix |
- if (fFormatWidth > 0 && fPadPosition == kPadAfterPrefix) { |
+ if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterPrefix) { |
position = skipPadding(text, position); |
} |
@@ -2694,7 +1390,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
} |
// process digits or Inf, find decimal position |
- const UnicodeString *inf = &getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); |
+ const UnicodeString *inf = &fImpl->getConstSymbol(DecimalFormatSymbols::kInfinitySymbol); |
int32_t infLen = (text.compare(position, inf->length(), *inf) |
? 0 : inf->length()); |
position += infLen; // infLen is non-zero when it does equal to infinity |
@@ -2714,13 +1410,13 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
UBool strictFail = FALSE; // did we exit with a strict parse failure? |
int32_t lastGroup = -1; // where did we last see a grouping separator? |
int32_t digitStart = position; |
- int32_t gs2 = fGroupingSize2 == 0 ? fGroupingSize : fGroupingSize2; |
+ int32_t gs2 = fImpl->fEffGrouping.fGrouping2 == 0 ? fImpl->fEffGrouping.fGrouping : fImpl->fEffGrouping.fGrouping2; |
const UnicodeString *decimalString; |
- if (fCurrencySignCount != fgCurrencySignCountZero) { |
- decimalString = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); |
+ if (fImpl->fMonetary) { |
+ decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol); |
} else { |
- decimalString = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); |
+ decimalString = &fImpl->getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); |
} |
UChar32 decimalChar = decimalString->char32At(0); |
int32_t decimalStringLength = decimalString->length(); |
@@ -2784,11 +1480,11 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
// is not a "standard" Unicode digit. |
if ( (digit < 0 || digit > 9) && u_charDigitValue(zero) != 0) { |
digit = 0; |
- if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) { |
+ if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kZeroDigitSymbol)).char32At(0) == ch ) { |
break; |
} |
for (digit = 1 ; digit < 10 ; digit++ ) { |
- if ( getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) { |
+ if ( fImpl->getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)(DecimalFormatSymbols::kOneDigitSymbol+digit-1)).char32At(0) == ch ) { |
break; |
} |
} |
@@ -2860,7 +1556,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
{ |
if (strictParse) { |
if (backup != -1 || |
- (lastGroup != -1 && position - lastGroup != fGroupingSize + 1)) { |
+ (lastGroup != -1 && position - lastGroup != fImpl->fEffGrouping.fGrouping + 1)) { |
strictFail = TRUE; |
break; |
} |
@@ -2884,7 +1580,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't parse if this is set unless.. |
isScientificNotation()) { // .. it's an exponent format - ignore setting and parse anyways |
const UnicodeString *tmp; |
- tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); |
+ tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); |
// TODO: CASE |
if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit |
{ |
@@ -2894,13 +1590,13 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
if (pos < textLength) |
{ |
- tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
+ tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
if (!text.compare(pos, tmp->length(), *tmp)) |
{ |
pos += tmp->length(); |
} |
else { |
- tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
+ tmp = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
if (!text.compare(pos, tmp->length(), *tmp)) |
{ |
exponentSign = '-'; |
@@ -2947,7 +1643,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
// if we didn't see a decimal and it is required, check to see if the pattern had one |
if(!sawDecimal && isDecimalPatternMatchRequired()) |
{ |
- if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0) |
+ if(formatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0) |
{ |
parsePosition.setIndex(oldStart); |
parsePosition.setErrorIndex(position); |
@@ -2962,7 +1658,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
} |
if (strictParse && !sawDecimal) { |
- if (lastGroup != -1 && position - lastGroup != fGroupingSize + 1) { |
+ if (lastGroup != -1 && position - lastGroup != fImpl->fEffGrouping.fGrouping + 1) { |
strictFail = TRUE; |
} |
} |
@@ -2994,7 +1690,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
} |
// Match padding before suffix |
- if (fFormatWidth > 0 && fPadPosition == kPadBeforeSuffix) { |
+ if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadBeforeSuffix) { |
position = skipPadding(text, position); |
} |
@@ -3025,7 +1721,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text, |
position += (posSuffixMatch >= 0 ? posSuffixMatch : (negSuffixMatch >= 0 ? negSuffixMatch : 0)); |
// Match padding before suffix |
- if (fFormatWidth > 0 && fPadPosition == kPadAfterSuffix) { |
+ if (formatWidth > 0 && fImpl->fAffixes.fPadPosition == DigitAffixesAndPadding::kPadAfterSuffix) { |
position = skipPadding(text, position); |
} |
@@ -3073,7 +1769,7 @@ printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d |
// check if we missed a required decimal point |
if(fastParseOk && isDecimalPatternMatchRequired()) |
{ |
- if(fFormatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0) |
+ if(formatPattern.indexOf(DecimalFormatSymbols::kDecimalSeparatorSymbol) != 0) |
{ |
parsePosition.setIndex(oldStart); |
parsePosition.setErrorIndex(position); |
@@ -3092,9 +1788,9 @@ printf("PP -> %d, SLOW = [%s]! pp=%d, os=%d, err=%s\n", position, parsedNum.d |
* character. Result is >= position. |
*/ |
int32_t DecimalFormat::skipPadding(const UnicodeString& text, int32_t position) const { |
- int32_t padLen = U16_LENGTH(fPad); |
+ int32_t padLen = U16_LENGTH(fImpl->fAffixes.fPadChar); |
while (position < text.length() && |
- text.char32At(position) == fPad) { |
+ text.char32At(position) == fImpl->fAffixes.fPadChar) { |
position += padLen; |
} |
return position; |
@@ -3128,8 +1824,8 @@ int32_t DecimalFormat::compareAffix(const UnicodeString& text, |
UChar* currency) const |
{ |
const UnicodeString *patternToCompare; |
- if (fCurrencyChoice != NULL || currency != NULL || |
- (fCurrencySignCount != fgCurrencySignCountZero && complexCurrencyParsing)) { |
+ if (currency != NULL || |
+ (fImpl->fMonetary && complexCurrencyParsing)) { |
if (affixPat != NULL) { |
return compareComplexAffix(*affixPat, text, pos, type, currency); |
@@ -3138,18 +1834,18 @@ int32_t DecimalFormat::compareAffix(const UnicodeString& text, |
if (isNegative) { |
if (isPrefix) { |
- patternToCompare = &fNegativePrefix; |
+ patternToCompare = &fImpl->fAffixes.fNegativePrefix.getOtherVariant().toString(); |
} |
else { |
- patternToCompare = &fNegativeSuffix; |
+ patternToCompare = &fImpl->fAffixes.fNegativeSuffix.getOtherVariant().toString(); |
} |
} |
else { |
if (isPrefix) { |
- patternToCompare = &fPositivePrefix; |
+ patternToCompare = &fImpl->fAffixes.fPositivePrefix.getOtherVariant().toString(); |
} |
else { |
- patternToCompare = &fPositiveSuffix; |
+ patternToCompare = &fImpl->fAffixes.fPositiveSuffix.getOtherVariant().toString(); |
} |
} |
return compareSimpleAffix(*patternToCompare, text, pos, isLenient()); |
@@ -3420,9 +2116,7 @@ int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat, |
UChar* currency) const |
{ |
int32_t start = pos; |
- U_ASSERT(currency != NULL || |
- (fCurrencyChoice != NULL && *getCurrency() != 0) || |
- fCurrencySignCount != fgCurrencySignCountZero); |
+ U_ASSERT(currency != NULL || fImpl->fMonetary); |
for (int32_t i=0; |
i<affixPat.length() && pos >= 0; ) { |
@@ -3487,16 +2181,16 @@ int32_t DecimalFormat::compareComplexAffix(const UnicodeString& affixPat, |
continue; |
} |
case kPatternPercent: |
- affix = &getConstSymbol(DecimalFormatSymbols::kPercentSymbol); |
+ affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPercentSymbol); |
break; |
case kPatternPerMill: |
- affix = &getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); |
+ affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); |
break; |
case kPatternPlus: |
- affix = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
+ affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
break; |
case kPatternMinus: |
- affix = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
+ affix = &fImpl->getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
break; |
default: |
// fall through to affix!=0 test, which will fail |
@@ -3603,7 +2297,7 @@ UBool DecimalFormat::matchGrouping(UChar32 groupingChar, |
const DecimalFormatSymbols* |
DecimalFormat::getDecimalFormatSymbols() const |
{ |
- return fSymbols; |
+ return &fImpl->getDecimalFormatSymbols(); |
} |
//------------------------------------------------------------------------------ |
@@ -3615,25 +2309,7 @@ DecimalFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) |
if (symbolsToAdopt == NULL) { |
return; // do not allow caller to set fSymbols to NULL |
} |
- |
- UBool sameSymbols = FALSE; |
- if (fSymbols != NULL) { |
- sameSymbols = (UBool)(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == |
- symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) && |
- getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == |
- symbolsToAdopt->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); |
- delete fSymbols; |
- } |
- |
- fSymbols = symbolsToAdopt; |
- if (!sameSymbols) { |
- // If the currency symbols are the same, there is no need to recalculate. |
- setCurrencyForSymbols(); |
- } |
- expandAffixes(NULL); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->adoptDecimalFormatSymbols(symbolsToAdopt); |
} |
//------------------------------------------------------------------------------ |
// Setting the symbols is equlivalent to adopting a newly created localized |
@@ -3643,9 +2319,6 @@ void |
DecimalFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) |
{ |
adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
} |
@@ -3663,73 +2336,20 @@ DecimalFormat::adoptCurrencyPluralInfo(CurrencyPluralInfo* toAdopt) |
delete fCurrencyPluralInfo; |
fCurrencyPluralInfo = toAdopt; |
// re-set currency affix patterns and currency affixes. |
- if (fCurrencySignCount != fgCurrencySignCountZero) { |
+ if (fImpl->fMonetary) { |
UErrorCode status = U_ZERO_ERROR; |
if (fAffixPatternsForCurrency) { |
deleteHashForAffixPattern(); |
} |
setupCurrencyAffixPatterns(status); |
- if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) { |
- // only setup the affixes of the plural pattern. |
- setupCurrencyAffixes(fFormatPattern, FALSE, TRUE, status); |
- } |
} |
} |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
} |
void |
DecimalFormat::setCurrencyPluralInfo(const CurrencyPluralInfo& info) |
{ |
adoptCurrencyPluralInfo(info.clone()); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
-} |
- |
- |
-/** |
- * Update the currency object to match the symbols. This method |
- * is used only when the caller has passed in a symbols object |
- * that may not be the default object for its locale. |
- */ |
-void |
-DecimalFormat::setCurrencyForSymbols() { |
- /*Bug 4212072 |
- Update the affix strings accroding to symbols in order to keep |
- the affix strings up to date. |
- [Richard/GCL] |
- */ |
- |
- // With the introduction of the Currency object, the currency |
- // symbols in the DFS object are ignored. For backward |
- // compatibility, we check any explicitly set DFS object. If it |
- // is a default symbols object for its locale, we change the |
- // currency object to one for that locale. If it is custom, |
- // we set the currency to null. |
- UErrorCode ec = U_ZERO_ERROR; |
- const UChar* c = NULL; |
- const char* loc = fSymbols->getLocale().getName(); |
- UChar intlCurrencySymbol[4]; |
- ucurr_forLocale(loc, intlCurrencySymbol, 4, &ec); |
- UnicodeString currencySymbol; |
- |
- uprv_getStaticCurrencyName(intlCurrencySymbol, loc, currencySymbol, ec); |
- if (U_SUCCESS(ec) |
- && getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) == currencySymbol |
- && getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) == UnicodeString(intlCurrencySymbol)) |
- { |
- // Trap an error in mapping locale to currency. If we can't |
- // map, then don't fail and set the currency to "". |
- c = intlCurrencySymbol; |
- } |
- ec = U_ZERO_ERROR; // reset local error code! |
- setCurrencyInternally(c, ec); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
} |
@@ -3739,8 +2359,7 @@ DecimalFormat::setCurrencyForSymbols() { |
UnicodeString& |
DecimalFormat::getPositivePrefix(UnicodeString& result) const |
{ |
- result = fPositivePrefix; |
- return result; |
+ return fImpl->getPositivePrefix(result); |
} |
//------------------------------------------------------------------------------ |
@@ -3749,12 +2368,7 @@ DecimalFormat::getPositivePrefix(UnicodeString& result) const |
void |
DecimalFormat::setPositivePrefix(const UnicodeString& newValue) |
{ |
- fPositivePrefix = newValue; |
- delete fPosPrefixPattern; |
- fPosPrefixPattern = 0; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setPositivePrefix(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -3763,8 +2377,7 @@ DecimalFormat::setPositivePrefix(const UnicodeString& newValue) |
UnicodeString& |
DecimalFormat::getNegativePrefix(UnicodeString& result) const |
{ |
- result = fNegativePrefix; |
- return result; |
+ return fImpl->getNegativePrefix(result); |
} |
//------------------------------------------------------------------------------ |
@@ -3773,12 +2386,7 @@ DecimalFormat::getNegativePrefix(UnicodeString& result) const |
void |
DecimalFormat::setNegativePrefix(const UnicodeString& newValue) |
{ |
- fNegativePrefix = newValue; |
- delete fNegPrefixPattern; |
- fNegPrefixPattern = 0; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setNegativePrefix(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -3787,8 +2395,7 @@ DecimalFormat::setNegativePrefix(const UnicodeString& newValue) |
UnicodeString& |
DecimalFormat::getPositiveSuffix(UnicodeString& result) const |
{ |
- result = fPositiveSuffix; |
- return result; |
+ return fImpl->getPositiveSuffix(result); |
} |
//------------------------------------------------------------------------------ |
@@ -3797,12 +2404,7 @@ DecimalFormat::getPositiveSuffix(UnicodeString& result) const |
void |
DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) |
{ |
- fPositiveSuffix = newValue; |
- delete fPosSuffixPattern; |
- fPosSuffixPattern = 0; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setPositiveSuffix(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -3811,8 +2413,7 @@ DecimalFormat::setPositiveSuffix(const UnicodeString& newValue) |
UnicodeString& |
DecimalFormat::getNegativeSuffix(UnicodeString& result) const |
{ |
- result = fNegativeSuffix; |
- return result; |
+ return fImpl->getNegativeSuffix(result); |
} |
//------------------------------------------------------------------------------ |
@@ -3821,12 +2422,7 @@ DecimalFormat::getNegativeSuffix(UnicodeString& result) const |
void |
DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) |
{ |
- fNegativeSuffix = newValue; |
- delete fNegSuffixPattern; |
- fNegSuffixPattern = 0; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setNegativeSuffix(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -3838,11 +2434,7 @@ DecimalFormat::setNegativeSuffix(const UnicodeString& newValue) |
int32_t |
DecimalFormat::getMultiplier() const |
{ |
- if (fMultiplier == NULL) { |
- return 1; |
- } else { |
- return fMultiplier->getLong(); |
- } |
+ return fImpl->getMultiplier(); |
} |
//------------------------------------------------------------------------------ |
@@ -3850,26 +2442,7 @@ DecimalFormat::getMultiplier() const |
void |
DecimalFormat::setMultiplier(int32_t newValue) |
{ |
-// if (newValue == 0) { |
-// throw new IllegalArgumentException("Bad multiplier: " + newValue); |
-// } |
- if (newValue == 0) { |
- newValue = 1; // one being the benign default value for a multiplier. |
- } |
- if (newValue == 1) { |
- delete fMultiplier; |
- fMultiplier = NULL; |
- } else { |
- if (fMultiplier == NULL) { |
- fMultiplier = new DigitList; |
- } |
- if (fMultiplier != NULL) { |
- fMultiplier->set(newValue); |
- } |
- } |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setMultiplier(newValue); |
} |
/** |
@@ -3881,11 +2454,7 @@ DecimalFormat::setMultiplier(int32_t newValue) |
* @see #setRoundingMode |
*/ |
double DecimalFormat::getRoundingIncrement() const { |
- if (fRoundingIncrement == NULL) { |
- return 0.0; |
- } else { |
- return fRoundingIncrement->getDouble(); |
- } |
+ return fImpl->getRoundingIncrement(); |
} |
/** |
@@ -3898,22 +2467,7 @@ double DecimalFormat::getRoundingIncrement() const { |
* @see #setRoundingMode |
*/ |
void DecimalFormat::setRoundingIncrement(double newValue) { |
- if (newValue > 0.0) { |
- if (fRoundingIncrement == NULL) { |
- fRoundingIncrement = new DigitList(); |
- } |
- if (fRoundingIncrement != NULL) { |
- fRoundingIncrement->set(newValue); |
- return; |
- } |
- } |
- // These statements are executed if newValue is less than 0.0 |
- // or fRoundingIncrement could not be created. |
- delete fRoundingIncrement; |
- fRoundingIncrement = NULL; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setRoundingIncrement(newValue); |
} |
/** |
@@ -3924,7 +2478,7 @@ void DecimalFormat::setRoundingIncrement(double newValue) { |
* @see #setRoundingMode |
*/ |
DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const { |
- return fRoundingMode; |
+ return fImpl->getRoundingMode(); |
} |
/** |
@@ -3936,10 +2490,7 @@ DecimalFormat::ERoundingMode DecimalFormat::getRoundingMode() const { |
* @see #getRoundingMode |
*/ |
void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { |
- fRoundingMode = roundingMode; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setRoundingMode(roundingMode); |
} |
/** |
@@ -3952,7 +2503,7 @@ void DecimalFormat::setRoundingMode(ERoundingMode roundingMode) { |
* @see #setPadPosition |
*/ |
int32_t DecimalFormat::getFormatWidth() const { |
- return fFormatWidth; |
+ return fImpl->getFormatWidth(); |
} |
/** |
@@ -3968,26 +2519,40 @@ int32_t DecimalFormat::getFormatWidth() const { |
* @see #setPadPosition |
*/ |
void DecimalFormat::setFormatWidth(int32_t width) { |
- fFormatWidth = (width > 0) ? width : 0; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ int32_t formatWidth = (width > 0) ? width : 0; |
+ fImpl->setFormatWidth(formatWidth); |
} |
UnicodeString DecimalFormat::getPadCharacterString() const { |
- return UnicodeString(fPad); |
+ return UnicodeString(fImpl->getPadCharacter()); |
} |
void DecimalFormat::setPadCharacter(const UnicodeString &padChar) { |
+ UChar pad; |
if (padChar.length() > 0) { |
- fPad = padChar.char32At(0); |
+ pad = padChar.char32At(0); |
} |
else { |
- fPad = kDefaultPad; |
+ pad = kDefaultPad; |
} |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setPadCharacter(pad); |
+} |
+ |
+static DecimalFormat::EPadPosition fromPadPosition(DigitAffixesAndPadding::EPadPosition padPos) { |
+ switch (padPos) { |
+ case DigitAffixesAndPadding::kPadBeforePrefix: |
+ return DecimalFormat::kPadBeforePrefix; |
+ case DigitAffixesAndPadding::kPadAfterPrefix: |
+ return DecimalFormat::kPadAfterPrefix; |
+ case DigitAffixesAndPadding::kPadBeforeSuffix: |
+ return DecimalFormat::kPadBeforeSuffix; |
+ case DigitAffixesAndPadding::kPadAfterSuffix: |
+ return DecimalFormat::kPadAfterSuffix; |
+ default: |
+ U_ASSERT(FALSE); |
+ break; |
+ } |
+ return DecimalFormat::kPadBeforePrefix; |
} |
/** |
@@ -4008,7 +2573,24 @@ void DecimalFormat::setPadCharacter(const UnicodeString &padChar) { |
* @see #kPadAfterSuffix |
*/ |
DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const { |
- return fPadPosition; |
+ return fromPadPosition(fImpl->getPadPosition()); |
+} |
+ |
+static DigitAffixesAndPadding::EPadPosition toPadPosition(DecimalFormat::EPadPosition padPos) { |
+ switch (padPos) { |
+ case DecimalFormat::kPadBeforePrefix: |
+ return DigitAffixesAndPadding::kPadBeforePrefix; |
+ case DecimalFormat::kPadAfterPrefix: |
+ return DigitAffixesAndPadding::kPadAfterPrefix; |
+ case DecimalFormat::kPadBeforeSuffix: |
+ return DigitAffixesAndPadding::kPadBeforeSuffix; |
+ case DecimalFormat::kPadAfterSuffix: |
+ return DigitAffixesAndPadding::kPadAfterSuffix; |
+ default: |
+ U_ASSERT(FALSE); |
+ break; |
+ } |
+ return DigitAffixesAndPadding::kPadBeforePrefix; |
} |
/** |
@@ -4031,10 +2613,7 @@ DecimalFormat::EPadPosition DecimalFormat::getPadPosition() const { |
* @see #kPadAfterSuffix |
*/ |
void DecimalFormat::setPadPosition(EPadPosition padPos) { |
- fPadPosition = padPos; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setPadPosition(toPadPosition(padPos)); |
} |
/** |
@@ -4047,7 +2626,7 @@ void DecimalFormat::setPadPosition(EPadPosition padPos) { |
* @see #setExponentSignAlwaysShown |
*/ |
UBool DecimalFormat::isScientificNotation() const { |
- return fUseExponentialNotation; |
+ return fImpl->isScientificNotation(); |
} |
/** |
@@ -4061,10 +2640,7 @@ UBool DecimalFormat::isScientificNotation() const { |
* @see #setExponentSignAlwaysShown |
*/ |
void DecimalFormat::setScientificNotation(UBool useScientific) { |
- fUseExponentialNotation = useScientific; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setScientificNotation(useScientific); |
} |
/** |
@@ -4077,7 +2653,7 @@ void DecimalFormat::setScientificNotation(UBool useScientific) { |
* @see #setExponentSignAlwaysShown |
*/ |
int8_t DecimalFormat::getMinimumExponentDigits() const { |
- return fMinExponentDigits; |
+ return fImpl->getMinimumExponentDigits(); |
} |
/** |
@@ -4092,10 +2668,8 @@ int8_t DecimalFormat::getMinimumExponentDigits() const { |
* @see #setExponentSignAlwaysShown |
*/ |
void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { |
- fMinExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ int32_t minExponentDigits = (int8_t)((minExpDig > 0) ? minExpDig : 1); |
+ fImpl->setMinimumExponentDigits(minExponentDigits); |
} |
/** |
@@ -4110,7 +2684,7 @@ void DecimalFormat::setMinimumExponentDigits(int8_t minExpDig) { |
* @see #setExponentSignAlwaysShown |
*/ |
UBool DecimalFormat::isExponentSignAlwaysShown() const { |
- return fExponentSignAlwaysShown; |
+ return fImpl->isExponentSignAlwaysShown(); |
} |
/** |
@@ -4126,10 +2700,7 @@ UBool DecimalFormat::isExponentSignAlwaysShown() const { |
* @see #isExponentSignAlwaysShown |
*/ |
void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { |
- fExponentSignAlwaysShown = expSignAlways; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setExponentSignAlwaysShown(expSignAlways); |
} |
//------------------------------------------------------------------------------ |
@@ -4139,7 +2710,7 @@ void DecimalFormat::setExponentSignAlwaysShown(UBool expSignAlways) { |
int32_t |
DecimalFormat::getGroupingSize() const |
{ |
- return isGroupingUsed() ? fGroupingSize : 0; |
+ return fImpl->getGroupingSize(); |
} |
//------------------------------------------------------------------------------ |
@@ -4148,10 +2719,7 @@ DecimalFormat::getGroupingSize() const |
void |
DecimalFormat::setGroupingSize(int32_t newValue) |
{ |
- fGroupingSize = newValue; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setGroupingSize(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -4159,7 +2727,7 @@ DecimalFormat::setGroupingSize(int32_t newValue) |
int32_t |
DecimalFormat::getSecondaryGroupingSize() const |
{ |
- return fGroupingSize2; |
+ return fImpl->getSecondaryGroupingSize(); |
} |
//------------------------------------------------------------------------------ |
@@ -4167,10 +2735,23 @@ DecimalFormat::getSecondaryGroupingSize() const |
void |
DecimalFormat::setSecondaryGroupingSize(int32_t newValue) |
{ |
- fGroupingSize2 = newValue; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setSecondaryGroupingSize(newValue); |
+} |
+ |
+//------------------------------------------------------------------------------ |
+ |
+int32_t |
+DecimalFormat::getMinimumGroupingDigits() const |
+{ |
+ return fImpl->getMinimumGroupingDigits(); |
+} |
+ |
+//------------------------------------------------------------------------------ |
+ |
+void |
+DecimalFormat::setMinimumGroupingDigits(int32_t newValue) |
+{ |
+ fImpl->setMinimumGroupingDigits(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -4179,7 +2760,7 @@ DecimalFormat::setSecondaryGroupingSize(int32_t newValue) |
UBool |
DecimalFormat::isDecimalSeparatorAlwaysShown() const |
{ |
- return fDecimalSeparatorAlwaysShown; |
+ return fImpl->isDecimalSeparatorAlwaysShown(); |
} |
//------------------------------------------------------------------------------ |
@@ -4188,10 +2769,7 @@ DecimalFormat::isDecimalSeparatorAlwaysShown() const |
void |
DecimalFormat::setDecimalSeparatorAlwaysShown(UBool newValue) |
{ |
- fDecimalSeparatorAlwaysShown = newValue; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setDecimalSeparatorAlwaysShown(newValue); |
} |
//------------------------------------------------------------------------------ |
@@ -4218,7 +2796,7 @@ DecimalFormat::setDecimalPatternMatchRequired(UBool newValue) |
UnicodeString& |
DecimalFormat::toPattern(UnicodeString& result) const |
{ |
- return toPattern(result, FALSE); |
+ return fImpl->toPattern(result); |
} |
//------------------------------------------------------------------------------ |
@@ -4227,690 +2805,9 @@ DecimalFormat::toPattern(UnicodeString& result) const |
UnicodeString& |
DecimalFormat::toLocalizedPattern(UnicodeString& result) const |
{ |
- return toPattern(result, TRUE); |
-} |
- |
-//------------------------------------------------------------------------------ |
-/** |
- * Expand the affix pattern strings into the expanded affix strings. If any |
- * affix pattern string is null, do not expand it. This method should be |
- * called any time the symbols or the affix patterns change in order to keep |
- * the expanded affix strings up to date. |
- * This method also will be called before formatting if format currency |
- * plural names, since the plural name is not a static one, it is |
- * based on the currency plural count, the affix will be known only |
- * after the currency plural count is know. |
- * In which case, the parameter |
- * 'pluralCount' will be a non-null currency plural count. |
- * In all other cases, the 'pluralCount' is null, which means it is not needed. |
- */ |
-void DecimalFormat::expandAffixes(const UnicodeString* pluralCount) { |
- FieldPositionHandler none; |
- if (fPosPrefixPattern != 0) { |
- expandAffix(*fPosPrefixPattern, fPositivePrefix, 0, none, FALSE, pluralCount); |
- } |
- if (fPosSuffixPattern != 0) { |
- expandAffix(*fPosSuffixPattern, fPositiveSuffix, 0, none, FALSE, pluralCount); |
- } |
- if (fNegPrefixPattern != 0) { |
- expandAffix(*fNegPrefixPattern, fNegativePrefix, 0, none, FALSE, pluralCount); |
- } |
- if (fNegSuffixPattern != 0) { |
- expandAffix(*fNegSuffixPattern, fNegativeSuffix, 0, none, FALSE, pluralCount); |
- } |
-#ifdef FMT_DEBUG |
- UnicodeString s; |
- s.append(UnicodeString("[")) |
- .append(DEREFSTR(fPosPrefixPattern)).append((UnicodeString)"|").append(DEREFSTR(fPosSuffixPattern)) |
- .append((UnicodeString)";") .append(DEREFSTR(fNegPrefixPattern)).append((UnicodeString)"|").append(DEREFSTR(fNegSuffixPattern)) |
- .append((UnicodeString)"]->[") |
- .append(fPositivePrefix).append((UnicodeString)"|").append(fPositiveSuffix) |
- .append((UnicodeString)";") .append(fNegativePrefix).append((UnicodeString)"|").append(fNegativeSuffix) |
- .append((UnicodeString)"]\n"); |
- debugout(s); |
-#endif |
-} |
- |
-/** |
- * Expand an affix pattern into an affix string. All characters in the |
- * pattern are literal unless prefixed by kQuote. The following characters |
- * after kQuote are recognized: PATTERN_PERCENT, PATTERN_PER_MILLE, |
- * PATTERN_MINUS, and kCurrencySign. If kCurrencySign is doubled (kQuote + |
- * kCurrencySign + kCurrencySign), it is interpreted as an international |
- * currency sign. If CURRENCY_SIGN is tripled, it is interpreted as |
- * currency plural long names, such as "US Dollars". |
- * Any other character after a kQuote represents itself. |
- * kQuote must be followed by another character; kQuote may not occur by |
- * itself at the end of the pattern. |
- * |
- * This method is used in two distinct ways. First, it is used to expand |
- * the stored affix patterns into actual affixes. For this usage, doFormat |
- * must be false. Second, it is used to expand the stored affix patterns |
- * given a specific number (doFormat == true), for those rare cases in |
- * which a currency format references a ChoiceFormat (e.g., en_IN display |
- * name for INR). The number itself is taken from digitList. |
- * |
- * When used in the first way, this method has a side effect: It sets |
- * currencyChoice to a ChoiceFormat object, if the currency's display name |
- * in this locale is a ChoiceFormat pattern (very rare). It only does this |
- * if currencyChoice is null to start with. |
- * |
- * @param pattern the non-null, fPossibly empty pattern |
- * @param affix string to receive the expanded equivalent of pattern. |
- * Previous contents are deleted. |
- * @param doFormat if false, then the pattern will be expanded, and if a |
- * currency symbol is encountered that expands to a ChoiceFormat, the |
- * currencyChoice member variable will be initialized if it is null. If |
- * doFormat is true, then it is assumed that the currencyChoice has been |
- * created, and it will be used to format the value in digitList. |
- * @param pluralCount the plural count. It is only used for currency |
- * plural format. In which case, it is the plural |
- * count of the currency amount. For example, |
- * in en_US, it is the singular "one", or the plural |
- * "other". For all other cases, it is null, and |
- * is not being used. |
- */ |
-void DecimalFormat::expandAffix(const UnicodeString& pattern, |
- UnicodeString& affix, |
- double number, |
- FieldPositionHandler& handler, |
- UBool doFormat, |
- const UnicodeString* pluralCount) const { |
- affix.remove(); |
- for (int i=0; i<pattern.length(); ) { |
- UChar32 c = pattern.char32At(i); |
- i += U16_LENGTH(c); |
- if (c == kQuote) { |
- c = pattern.char32At(i); |
- i += U16_LENGTH(c); |
- int beginIdx = affix.length(); |
- switch (c) { |
- case kCurrencySign: { |
- // As of ICU 2.2 we use the currency object, and |
- // ignore the currency symbols in the DFS, unless |
- // we have a null currency object. This occurs if |
- // resurrecting a pre-2.2 object or if the user |
- // sets a custom DFS. |
- UBool intl = i<pattern.length() && |
- pattern.char32At(i) == kCurrencySign; |
- UBool plural = FALSE; |
- if (intl) { |
- ++i; |
- plural = i<pattern.length() && |
- pattern.char32At(i) == kCurrencySign; |
- if (plural) { |
- intl = FALSE; |
- ++i; |
- } |
- } |
- const UChar* currencyUChars = getCurrency(); |
- if (currencyUChars[0] != 0) { |
- UErrorCode ec = U_ZERO_ERROR; |
- if (plural && pluralCount != NULL) { |
- // plural name is only needed when pluralCount != null, |
- // which means when formatting currency plural names. |
- // For other cases, pluralCount == null, |
- // and plural names are not needed. |
- int32_t len; |
- CharString pluralCountChar; |
- pluralCountChar.appendInvariantChars(*pluralCount, ec); |
- UBool isChoiceFormat; |
- const UChar* s = ucurr_getPluralName(currencyUChars, |
- fSymbols != NULL ? fSymbols->getLocale().getName() : |
- Locale::getDefault().getName(), &isChoiceFormat, |
- pluralCountChar.data(), &len, &ec); |
- affix += UnicodeString(s, len); |
- handler.addAttribute(kCurrencyField, beginIdx, affix.length()); |
- } else if(intl) { |
- affix.append(currencyUChars, -1); |
- handler.addAttribute(kCurrencyField, beginIdx, affix.length()); |
- } else { |
- int32_t len; |
- UBool isChoiceFormat; |
- // If fSymbols is NULL, use default locale |
- const UChar* s = ucurr_getName(currencyUChars, |
- fSymbols != NULL ? fSymbols->getLocale().getName() : Locale::getDefault().getName(), |
- UCURR_SYMBOL_NAME, &isChoiceFormat, &len, &ec); |
- if (isChoiceFormat) { |
- // Two modes here: If doFormat is false, we set up |
- // currencyChoice. If doFormat is true, we use the |
- // previously created currencyChoice to format the |
- // value in digitList. |
- if (!doFormat) { |
- // If the currency is handled by a ChoiceFormat, |
- // then we're not going to use the expanded |
- // patterns. Instantiate the ChoiceFormat and |
- // return. |
- if (fCurrencyChoice == NULL) { |
- // TODO Replace double-check with proper thread-safe code |
- ChoiceFormat* fmt = new ChoiceFormat(UnicodeString(s), ec); |
- if (U_SUCCESS(ec)) { |
- umtx_lock(NULL); |
- if (fCurrencyChoice == NULL) { |
- // Cast away const |
- ((DecimalFormat*)this)->fCurrencyChoice = fmt; |
- fmt = NULL; |
- } |
- umtx_unlock(NULL); |
- delete fmt; |
- } |
- } |
- // We could almost return null or "" here, since the |
- // expanded affixes are almost not used at all |
- // in this situation. However, one method -- |
- // toPattern() -- still does use the expanded |
- // affixes, in order to set up a padding |
- // pattern. We use the CURRENCY_SIGN as a |
- // placeholder. |
- affix.append(kCurrencySign); |
- } else { |
- if (fCurrencyChoice != NULL) { |
- FieldPosition pos(0); // ignored |
- if (number < 0) { |
- number = -number; |
- } |
- fCurrencyChoice->format(number, affix, pos); |
- } else { |
- // We only arrive here if the currency choice |
- // format in the locale data is INVALID. |
- affix.append(currencyUChars, -1); |
- handler.addAttribute(kCurrencyField, beginIdx, affix.length()); |
- } |
- } |
- continue; |
- } |
- affix += UnicodeString(s, len); |
- handler.addAttribute(kCurrencyField, beginIdx, affix.length()); |
- } |
- } else { |
- if(intl) { |
- affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); |
- } else { |
- affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); |
- } |
- handler.addAttribute(kCurrencyField, beginIdx, affix.length()); |
- } |
- break; |
- } |
- case kPatternPercent: |
- affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); |
- handler.addAttribute(kPercentField, beginIdx, affix.length()); |
- break; |
- case kPatternPerMill: |
- affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); |
- handler.addAttribute(kPermillField, beginIdx, affix.length()); |
- break; |
- case kPatternPlus: |
- affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
- handler.addAttribute(kSignField, beginIdx, affix.length()); |
- break; |
- case kPatternMinus: |
- affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
- handler.addAttribute(kSignField, beginIdx, affix.length()); |
- break; |
- default: |
- affix.append(c); |
- break; |
- } |
- } |
- else { |
- affix.append(c); |
- } |
- } |
-} |
- |
-/** |
- * Append an affix to the given StringBuffer. |
- * @param buf buffer to append to |
- * @param isNegative |
- * @param isPrefix |
- */ |
-int32_t DecimalFormat::appendAffix(UnicodeString& buf, double number, |
- FieldPositionHandler& handler, |
- UBool isNegative, UBool isPrefix) const { |
- // plural format precedes choice format |
- if (fCurrencyChoice != 0 && |
- fCurrencySignCount != fgCurrencySignCountInPluralFormat) { |
- const UnicodeString* affixPat; |
- if (isPrefix) { |
- affixPat = isNegative ? fNegPrefixPattern : fPosPrefixPattern; |
- } else { |
- affixPat = isNegative ? fNegSuffixPattern : fPosSuffixPattern; |
- } |
- if (affixPat) { |
- UnicodeString affixBuf; |
- expandAffix(*affixPat, affixBuf, number, handler, TRUE, NULL); |
- buf.append(affixBuf); |
- return affixBuf.length(); |
- } |
- // else someone called a function that reset the pattern. |
- } |
- |
- const UnicodeString* affix; |
- if (fCurrencySignCount == fgCurrencySignCountInPluralFormat) { |
- // TODO: get an accurate count of visible fraction digits. |
- UnicodeString pluralCount; |
- int32_t minFractionDigits = this->getMinimumFractionDigits(); |
- if (minFractionDigits > 0) { |
- FixedDecimal ni(number, this->getMinimumFractionDigits()); |
- pluralCount = fCurrencyPluralInfo->getPluralRules()->select(ni); |
- } else { |
- pluralCount = fCurrencyPluralInfo->getPluralRules()->select(number); |
- } |
- AffixesForCurrency* oneSet; |
- if (fStyle == UNUM_CURRENCY_PLURAL) { |
- oneSet = (AffixesForCurrency*)fPluralAffixesForCurrency->get(pluralCount); |
- } else { |
- oneSet = (AffixesForCurrency*)fAffixesForCurrency->get(pluralCount); |
- } |
- if (isPrefix) { |
- affix = isNegative ? &oneSet->negPrefixForCurrency : |
- &oneSet->posPrefixForCurrency; |
- } else { |
- affix = isNegative ? &oneSet->negSuffixForCurrency : |
- &oneSet->posSuffixForCurrency; |
- } |
- } else { |
- if (isPrefix) { |
- affix = isNegative ? &fNegativePrefix : &fPositivePrefix; |
- } else { |
- affix = isNegative ? &fNegativeSuffix : &fPositiveSuffix; |
- } |
- } |
- |
- int32_t begin = (int) buf.length(); |
- |
- buf.append(*affix); |
- |
- if (handler.isRecording()) { |
- int32_t offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kCurrencySymbol)); |
- if (offset > -1) { |
- UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kCurrencySymbol); |
- handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length()); |
- } |
- |
- offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)); |
- if (offset > -1) { |
- UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); |
- handler.addAttribute(kCurrencyField, begin + offset, begin + offset + aff.length()); |
- } |
- |
- offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)); |
- if (offset > -1) { |
- UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
- handler.addAttribute(kSignField, begin + offset, begin + offset + aff.length()); |
- } |
- |
- offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)); |
- if (offset > -1) { |
- UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPercentSymbol); |
- handler.addAttribute(kPercentField, begin + offset, begin + offset + aff.length()); |
- } |
- |
- offset = (int) (*affix).indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)); |
- if (offset > -1) { |
- UnicodeString aff = getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); |
- handler.addAttribute(kPermillField, begin + offset, begin + offset + aff.length()); |
- } |
- } |
- return affix->length(); |
-} |
- |
-/** |
- * Appends an affix pattern to the given StringBuffer, quoting special |
- * characters as needed. Uses the internal affix pattern, if that exists, |
- * or the literal affix, if the internal affix pattern is null. The |
- * appended string will generate the same affix pattern (or literal affix) |
- * when passed to toPattern(). |
- * |
- * @param appendTo the affix string is appended to this |
- * @param affixPattern a pattern such as fPosPrefixPattern; may be null |
- * @param expAffix a corresponding expanded affix, such as fPositivePrefix. |
- * Ignored unless affixPattern is null. If affixPattern is null, then |
- * expAffix is appended as a literal affix. |
- * @param localized true if the appended pattern should contain localized |
- * pattern characters; otherwise, non-localized pattern chars are appended |
- */ |
-void DecimalFormat::appendAffixPattern(UnicodeString& appendTo, |
- const UnicodeString* affixPattern, |
- const UnicodeString& expAffix, |
- UBool localized) const { |
- if (affixPattern == 0) { |
- appendAffixPattern(appendTo, expAffix, localized); |
- } else { |
- int i; |
- for (int pos=0; pos<affixPattern->length(); pos=i) { |
- i = affixPattern->indexOf(kQuote, pos); |
- if (i < 0) { |
- UnicodeString s; |
- affixPattern->extractBetween(pos, affixPattern->length(), s); |
- appendAffixPattern(appendTo, s, localized); |
- break; |
- } |
- if (i > pos) { |
- UnicodeString s; |
- affixPattern->extractBetween(pos, i, s); |
- appendAffixPattern(appendTo, s, localized); |
- } |
- UChar32 c = affixPattern->char32At(++i); |
- ++i; |
- if (c == kQuote) { |
- appendTo.append(c).append(c); |
- // Fall through and append another kQuote below |
- } else if (c == kCurrencySign && |
- i<affixPattern->length() && |
- affixPattern->char32At(i) == kCurrencySign) { |
- ++i; |
- appendTo.append(c).append(c); |
- } else if (localized) { |
- switch (c) { |
- case kPatternPercent: |
- appendTo += getConstSymbol(DecimalFormatSymbols::kPercentSymbol); |
- break; |
- case kPatternPerMill: |
- appendTo += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol); |
- break; |
- case kPatternPlus: |
- appendTo += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
- break; |
- case kPatternMinus: |
- appendTo += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol); |
- break; |
- default: |
- appendTo.append(c); |
- } |
- } else { |
- appendTo.append(c); |
- } |
- } |
- } |
-} |
- |
-/** |
- * Append an affix to the given StringBuffer, using quotes if |
- * there are special characters. Single quotes themselves must be |
- * escaped in either case. |
- */ |
-void |
-DecimalFormat::appendAffixPattern(UnicodeString& appendTo, |
- const UnicodeString& affix, |
- UBool localized) const { |
- UBool needQuote; |
- if(localized) { |
- needQuote = affix.indexOf(getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0 |
- || affix.indexOf(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0 |
- || affix.indexOf(kCurrencySign) >= 0; |
- } |
- else { |
- needQuote = affix.indexOf(kPatternZeroDigit) >= 0 |
- || affix.indexOf(kPatternGroupingSeparator) >= 0 |
- || affix.indexOf(kPatternDecimalSeparator) >= 0 |
- || affix.indexOf(kPatternPercent) >= 0 |
- || affix.indexOf(kPatternPerMill) >= 0 |
- || affix.indexOf(kPatternDigit) >= 0 |
- || affix.indexOf(kPatternSeparator) >= 0 |
- || affix.indexOf(kPatternExponent) >= 0 |
- || affix.indexOf(kPatternPlus) >= 0 |
- || affix.indexOf(kPatternMinus) >= 0 |
- || affix.indexOf(kCurrencySign) >= 0; |
- } |
- if (needQuote) |
- appendTo += (UChar)0x0027 /*'\''*/; |
- if (affix.indexOf((UChar)0x0027 /*'\''*/) < 0) |
- appendTo += affix; |
- else { |
- for (int32_t j = 0; j < affix.length(); ) { |
- UChar32 c = affix.char32At(j); |
- j += U16_LENGTH(c); |
- appendTo += c; |
- if (c == 0x0027 /*'\''*/) |
- appendTo += c; |
- } |
- } |
- if (needQuote) |
- appendTo += (UChar)0x0027 /*'\''*/; |
-} |
- |
-//------------------------------------------------------------------------------ |
- |
-UnicodeString& |
-DecimalFormat::toPattern(UnicodeString& result, UBool localized) const |
-{ |
- if (fStyle == UNUM_CURRENCY_PLURAL) { |
- // the prefix or suffix pattern might not be defined yet, |
- // so they can not be synthesized, |
- // instead, get them directly. |
- // but it might not be the actual pattern used in formatting. |
- // the actual pattern used in formatting depends on the |
- // formatted number's plural count. |
- result = fFormatPattern; |
- return result; |
- } |
- result.remove(); |
- UChar32 zero, sigDigit = kPatternSignificantDigit; |
- UnicodeString digit, group; |
- int32_t i; |
- int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits |
- UnicodeString roundingDigits; |
- int32_t padPos = (fFormatWidth > 0) ? fPadPosition : -1; |
- UnicodeString padSpec; |
- UBool useSigDig = areSignificantDigitsUsed(); |
- |
- if (localized) { |
- digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol)); |
- group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)); |
- zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0); |
- if (useSigDig) { |
- sigDigit = getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol).char32At(0); |
- } |
- } |
- else { |
- digit.append((UChar)kPatternDigit); |
- group.append((UChar)kPatternGroupingSeparator); |
- zero = (UChar32)kPatternZeroDigit; |
- } |
- if (fFormatWidth > 0) { |
- if (localized) { |
- padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol)); |
- } |
- else { |
- padSpec.append((UChar)kPatternPadEscape); |
- } |
- padSpec.append(fPad); |
- } |
- if (fRoundingIncrement != NULL) { |
- for(i=0; i<fRoundingIncrement->getCount(); ++i) { |
- roundingDigits.append(zero+(fRoundingIncrement->getDigitValue(i))); // Convert to Unicode digit |
- } |
- roundingDecimalPos = fRoundingIncrement->getDecimalAt(); |
- } |
- for (int32_t part=0; part<2; ++part) { |
- if (padPos == kPadBeforePrefix) { |
- result.append(padSpec); |
- } |
- appendAffixPattern(result, |
- (part==0 ? fPosPrefixPattern : fNegPrefixPattern), |
- (part==0 ? fPositivePrefix : fNegativePrefix), |
- localized); |
- if (padPos == kPadAfterPrefix && ! padSpec.isEmpty()) { |
- result.append(padSpec); |
- } |
- int32_t sub0Start = result.length(); |
- int32_t g = isGroupingUsed() ? _max(0, fGroupingSize) : 0; |
- if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) { |
- g += fGroupingSize2; |
- } |
- int32_t maxDig = 0, minDig = 0, maxSigDig = 0; |
- if (useSigDig) { |
- minDig = getMinimumSignificantDigits(); |
- maxDig = maxSigDig = getMaximumSignificantDigits(); |
- } else { |
- minDig = getMinimumIntegerDigits(); |
- maxDig = getMaximumIntegerDigits(); |
- } |
- if (fUseExponentialNotation) { |
- if (maxDig > kMaxScientificIntegerDigits) { |
- maxDig = 1; |
- } |
- } else if (useSigDig) { |
- maxDig = _max(maxDig, g+1); |
- } else { |
- maxDig = _max(_max(g, getMinimumIntegerDigits()), |
- roundingDecimalPos) + 1; |
- } |
- for (i = maxDig; i > 0; --i) { |
- if (!fUseExponentialNotation && i<maxDig && |
- isGroupingPosition(i)) { |
- result.append(group); |
- } |
- if (useSigDig) { |
- // #@,@### (maxSigDig == 5, minSigDig == 2) |
- // 65 4321 (1-based pos, count from the right) |
- // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig) |
- // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig |
- if (maxSigDig >= i && i > (maxSigDig - minDig)) { |
- result.append(sigDigit); |
- } else { |
- result.append(digit); |
- } |
- } else { |
- if (! roundingDigits.isEmpty()) { |
- int32_t pos = roundingDecimalPos - i; |
- if (pos >= 0 && pos < roundingDigits.length()) { |
- result.append((UChar) (roundingDigits.char32At(pos) - kPatternZeroDigit + zero)); |
- continue; |
- } |
- } |
- if (i<=minDig) { |
- result.append(zero); |
- } else { |
- result.append(digit); |
- } |
- } |
- } |
- if (!useSigDig) { |
- if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) { |
- if (localized) { |
- result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol); |
- } |
- else { |
- result.append((UChar)kPatternDecimalSeparator); |
- } |
- } |
- int32_t pos = roundingDecimalPos; |
- for (i = 0; i < getMaximumFractionDigits(); ++i) { |
- if (! roundingDigits.isEmpty() && pos < roundingDigits.length()) { |
- if (pos < 0) { |
- result.append(zero); |
- } |
- else { |
- result.append((UChar)(roundingDigits.char32At(pos) - kPatternZeroDigit + zero)); |
- } |
- ++pos; |
- continue; |
- } |
- if (i<getMinimumFractionDigits()) { |
- result.append(zero); |
- } |
- else { |
- result.append(digit); |
- } |
- } |
- } |
- if (fUseExponentialNotation) { |
- if (localized) { |
- result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol); |
- } |
- else { |
- result.append((UChar)kPatternExponent); |
- } |
- if (fExponentSignAlwaysShown) { |
- if (localized) { |
- result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol); |
- } |
- else { |
- result.append((UChar)kPatternPlus); |
- } |
- } |
- for (i=0; i<fMinExponentDigits; ++i) { |
- result.append(zero); |
- } |
- } |
- if (! padSpec.isEmpty() && !fUseExponentialNotation) { |
- int32_t add = fFormatWidth - result.length() + sub0Start |
- - ((part == 0) |
- ? fPositivePrefix.length() + fPositiveSuffix.length() |
- : fNegativePrefix.length() + fNegativeSuffix.length()); |
- while (add > 0) { |
- result.insert(sub0Start, digit); |
- ++maxDig; |
- --add; |
- // Only add a grouping separator if we have at least |
- // 2 additional characters to be added, so we don't |
- // end up with ",###". |
- if (add>1 && isGroupingPosition(maxDig)) { |
- result.insert(sub0Start, group); |
- --add; |
- } |
- } |
- } |
- if (fPadPosition == kPadBeforeSuffix && ! padSpec.isEmpty()) { |
- result.append(padSpec); |
- } |
- if (part == 0) { |
- appendAffixPattern(result, fPosSuffixPattern, fPositiveSuffix, localized); |
- if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { |
- result.append(padSpec); |
- } |
- UBool isDefault = FALSE; |
- if ((fNegSuffixPattern == fPosSuffixPattern && // both null |
- fNegativeSuffix == fPositiveSuffix) |
- || (fNegSuffixPattern != 0 && fPosSuffixPattern != 0 && |
- *fNegSuffixPattern == *fPosSuffixPattern)) |
- { |
- if (fNegPrefixPattern != NULL && fPosPrefixPattern != NULL) |
- { |
- int32_t length = fPosPrefixPattern->length(); |
- isDefault = fNegPrefixPattern->length() == (length+2) && |
- (*fNegPrefixPattern)[(int32_t)0] == kQuote && |
- (*fNegPrefixPattern)[(int32_t)1] == kPatternMinus && |
- fNegPrefixPattern->compare(2, length, *fPosPrefixPattern, 0, length) == 0; |
- } |
- if (!isDefault && |
- fNegPrefixPattern == NULL && fPosPrefixPattern == NULL) |
- { |
- int32_t length = fPositivePrefix.length(); |
- isDefault = fNegativePrefix.length() == (length+1) && |
- fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 && |
- fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0; |
- } |
- } |
- if (isDefault) { |
- break; // Don't output default negative subpattern |
- } else { |
- if (localized) { |
- result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol); |
- } |
- else { |
- result.append((UChar)kPatternSeparator); |
- } |
- } |
- } else { |
- appendAffixPattern(result, fNegSuffixPattern, fNegativeSuffix, localized); |
- if (fPadPosition == kPadAfterSuffix && ! padSpec.isEmpty()) { |
- result.append(padSpec); |
- } |
- } |
- } |
- |
- return result; |
+ // toLocalizedPattern is deprecated, so we just make it the same as |
+ // toPattern. |
+ return fImpl->toPattern(result); |
} |
//------------------------------------------------------------------------------ |
@@ -4918,8 +2815,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const |
void |
DecimalFormat::applyPattern(const UnicodeString& pattern, UErrorCode& status) |
{ |
- UParseError parseError; |
- applyPattern(pattern, FALSE, parseError, status); |
+ fImpl->applyPattern(pattern, status); |
} |
//------------------------------------------------------------------------------ |
@@ -4929,15 +2825,14 @@ DecimalFormat::applyPattern(const UnicodeString& pattern, |
UParseError& parseError, |
UErrorCode& status) |
{ |
- applyPattern(pattern, FALSE, parseError, status); |
+ fImpl->applyPattern(pattern, parseError, status); |
} |
//------------------------------------------------------------------------------ |
void |
DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, UErrorCode& status) |
{ |
- UParseError parseError; |
- applyPattern(pattern, TRUE,parseError,status); |
+ fImpl->applyLocalizedPattern(pattern, status); |
} |
//------------------------------------------------------------------------------ |
@@ -4947,160 +2842,20 @@ DecimalFormat::applyLocalizedPattern(const UnicodeString& pattern, |
UParseError& parseError, |
UErrorCode& status) |
{ |
- applyPattern(pattern, TRUE,parseError,status); |
+ fImpl->applyLocalizedPattern(pattern, parseError, status); |
} |
//------------------------------------------------------------------------------ |
-void |
-DecimalFormat::applyPatternWithoutExpandAffix(const UnicodeString& pattern, |
- UBool localized, |
- UParseError& parseError, |
- UErrorCode& status) |
-{ |
- if (U_FAILURE(status)) |
- { |
- return; |
- } |
- DecimalFormatPatternParser patternParser; |
- if (localized) { |
- patternParser.useSymbols(*fSymbols); |
- } |
- fFormatPattern = pattern; |
- DecimalFormatPattern out; |
- patternParser.applyPatternWithoutExpandAffix( |
- pattern, |
- out, |
- parseError, |
- status); |
- if (U_FAILURE(status)) { |
- return; |
- } |
- |
- setMinimumIntegerDigits(out.fMinimumIntegerDigits); |
- setMaximumIntegerDigits(out.fMaximumIntegerDigits); |
- setMinimumFractionDigits(out.fMinimumFractionDigits); |
- setMaximumFractionDigits(out.fMaximumFractionDigits); |
- setSignificantDigitsUsed(out.fUseSignificantDigits); |
- if (out.fUseSignificantDigits) { |
- setMinimumSignificantDigits(out.fMinimumSignificantDigits); |
- setMaximumSignificantDigits(out.fMaximumSignificantDigits); |
- } |
- fUseExponentialNotation = out.fUseExponentialNotation; |
- if (out.fUseExponentialNotation) { |
- fMinExponentDigits = out.fMinExponentDigits; |
- } |
- fExponentSignAlwaysShown = out.fExponentSignAlwaysShown; |
- fCurrencySignCount = out.fCurrencySignCount; |
- setGroupingUsed(out.fGroupingUsed); |
- if (out.fGroupingUsed) { |
- fGroupingSize = out.fGroupingSize; |
- fGroupingSize2 = out.fGroupingSize2; |
- } |
- setMultiplier(out.fMultiplier); |
- fDecimalSeparatorAlwaysShown = out.fDecimalSeparatorAlwaysShown; |
- fFormatWidth = out.fFormatWidth; |
- if (out.fRoundingIncrementUsed) { |
- if (fRoundingIncrement != NULL) { |
- *fRoundingIncrement = out.fRoundingIncrement; |
- } else { |
- fRoundingIncrement = new DigitList(out.fRoundingIncrement); |
- /* test for NULL */ |
- if (fRoundingIncrement == NULL) { |
- status = U_MEMORY_ALLOCATION_ERROR; |
- return; |
- } |
- } |
- } else { |
- setRoundingIncrement(0.0); |
- } |
- fPad = out.fPad; |
- switch (out.fPadPosition) { |
- case DecimalFormatPattern::kPadBeforePrefix: |
- fPadPosition = kPadBeforePrefix; |
- break; |
- case DecimalFormatPattern::kPadAfterPrefix: |
- fPadPosition = kPadAfterPrefix; |
- break; |
- case DecimalFormatPattern::kPadBeforeSuffix: |
- fPadPosition = kPadBeforeSuffix; |
- break; |
- case DecimalFormatPattern::kPadAfterSuffix: |
- fPadPosition = kPadAfterSuffix; |
- break; |
- } |
- copyString(out.fNegPrefixPattern, out.fNegPatternsBogus, fNegPrefixPattern, status); |
- copyString(out.fNegSuffixPattern, out.fNegPatternsBogus, fNegSuffixPattern, status); |
- copyString(out.fPosPrefixPattern, out.fPosPatternsBogus, fPosPrefixPattern, status); |
- copyString(out.fPosSuffixPattern, out.fPosPatternsBogus, fPosSuffixPattern, status); |
-} |
- |
- |
-void |
-DecimalFormat::expandAffixAdjustWidth(const UnicodeString* pluralCount) { |
- expandAffixes(pluralCount); |
- if (fFormatWidth > 0) { |
- // Finish computing format width (see above) |
- // TODO: how to handle fFormatWidth, |
- // need to save in f(Plural)AffixesForCurrecy? |
- fFormatWidth += fPositivePrefix.length() + fPositiveSuffix.length(); |
- } |
-} |
- |
- |
-void |
-DecimalFormat::applyPattern(const UnicodeString& pattern, |
- UBool localized, |
- UParseError& parseError, |
- UErrorCode& status) |
-{ |
- // do the following re-set first. since they change private data by |
- // apply pattern again. |
- if (pattern.indexOf(kCurrencySign) != -1) { |
- if (fCurrencyPluralInfo == NULL) { |
- // initialize currencyPluralInfo if needed |
- fCurrencyPluralInfo = new CurrencyPluralInfo(fSymbols->getLocale(), status); |
- } |
- if (fAffixPatternsForCurrency == NULL) { |
- setupCurrencyAffixPatterns(status); |
- } |
- if (pattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) { |
- // only setup the affixes of the current pattern. |
- setupCurrencyAffixes(pattern, TRUE, FALSE, status); |
- } |
- } |
- applyPatternWithoutExpandAffix(pattern, localized, parseError, status); |
- expandAffixAdjustWidth(NULL); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
-} |
- |
- |
-void |
-DecimalFormat::applyPatternInternally(const UnicodeString& pluralCount, |
- const UnicodeString& pattern, |
- UBool localized, |
- UParseError& parseError, |
- UErrorCode& status) { |
- applyPatternWithoutExpandAffix(pattern, localized, parseError, status); |
- expandAffixAdjustWidth(&pluralCount); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
-} |
- |
- |
/** |
* Sets the maximum number of digits allowed in the integer portion of a |
* number. |
* @see NumberFormat#setMaximumIntegerDigits |
*/ |
void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { |
- NumberFormat::setMaximumIntegerDigits(_min(newValue, gDefaultMaxIntegerDigits)); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ newValue = _min(newValue, gDefaultMaxIntegerDigits); |
+ NumberFormat::setMaximumIntegerDigits(newValue); |
+ fImpl->updatePrecision(); |
} |
/** |
@@ -5109,10 +2864,9 @@ void DecimalFormat::setMaximumIntegerDigits(int32_t newValue) { |
* @see NumberFormat#setMinimumIntegerDigits |
*/ |
void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { |
- NumberFormat::setMinimumIntegerDigits(_min(newValue, kDoubleIntegerDigits)); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ newValue = _min(newValue, kDoubleIntegerDigits); |
+ NumberFormat::setMinimumIntegerDigits(newValue); |
+ fImpl->updatePrecision(); |
} |
/** |
@@ -5121,10 +2875,9 @@ void DecimalFormat::setMinimumIntegerDigits(int32_t newValue) { |
* @see NumberFormat#setMaximumFractionDigits |
*/ |
void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { |
- NumberFormat::setMaximumFractionDigits(_min(newValue, kDoubleFractionDigits)); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ newValue = _min(newValue, kDoubleFractionDigits); |
+ NumberFormat::setMaximumFractionDigits(newValue); |
+ fImpl->updatePrecision(); |
} |
/** |
@@ -5133,18 +2886,17 @@ void DecimalFormat::setMaximumFractionDigits(int32_t newValue) { |
* @see NumberFormat#setMinimumFractionDigits |
*/ |
void DecimalFormat::setMinimumFractionDigits(int32_t newValue) { |
- NumberFormat::setMinimumFractionDigits(_min(newValue, kDoubleFractionDigits)); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ newValue = _min(newValue, kDoubleFractionDigits); |
+ NumberFormat::setMinimumFractionDigits(newValue); |
+ fImpl->updatePrecision(); |
} |
int32_t DecimalFormat::getMinimumSignificantDigits() const { |
- return fMinSignificantDigits; |
+ return fImpl->getMinimumSignificantDigits(); |
} |
int32_t DecimalFormat::getMaximumSignificantDigits() const { |
- return fMaxSignificantDigits; |
+ return fImpl->getMaximumSignificantDigits(); |
} |
void DecimalFormat::setMinimumSignificantDigits(int32_t min) { |
@@ -5152,13 +2904,8 @@ void DecimalFormat::setMinimumSignificantDigits(int32_t min) { |
min = 1; |
} |
// pin max sig dig to >= min |
- int32_t max = _max(fMaxSignificantDigits, min); |
- fMinSignificantDigits = min; |
- fMaxSignificantDigits = max; |
- fUseSignificantDigits = TRUE; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ int32_t max = _max(fImpl->fMaxSigDigits, min); |
+ fImpl->setMinMaxSignificantDigits(min, max); |
} |
void DecimalFormat::setMaximumSignificantDigits(int32_t max) { |
@@ -5166,113 +2913,41 @@ void DecimalFormat::setMaximumSignificantDigits(int32_t max) { |
max = 1; |
} |
// pin min sig dig to 1..max |
- U_ASSERT(fMinSignificantDigits >= 1); |
- int32_t min = _min(fMinSignificantDigits, max); |
- fMinSignificantDigits = min; |
- fMaxSignificantDigits = max; |
- fUseSignificantDigits = TRUE; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ U_ASSERT(fImpl->fMinSigDigits >= 1); |
+ int32_t min = _min(fImpl->fMinSigDigits, max); |
+ fImpl->setMinMaxSignificantDigits(min, max); |
} |
UBool DecimalFormat::areSignificantDigitsUsed() const { |
- return fUseSignificantDigits; |
+ return fImpl->areSignificantDigitsUsed(); |
} |
void DecimalFormat::setSignificantDigitsUsed(UBool useSignificantDigits) { |
- fUseSignificantDigits = useSignificantDigits; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
-} |
- |
-void DecimalFormat::setCurrencyInternally(const UChar* theCurrency, |
- UErrorCode& ec) { |
- // If we are a currency format, then modify our affixes to |
- // encode the currency symbol for the given currency in our |
- // locale, and adjust the decimal digits and rounding for the |
- // given currency. |
- |
- // Note: The code is ordered so that this object is *not changed* |
- // until we are sure we are going to succeed. |
- |
- // NULL or empty currency is *legal* and indicates no currency. |
- UBool isCurr = (theCurrency && *theCurrency); |
- |
- double rounding = 0.0; |
- int32_t frac = 0; |
- if (fCurrencySignCount != fgCurrencySignCountZero && isCurr) { |
- rounding = ucurr_getRoundingIncrementForUsage(theCurrency, fCurrencyUsage, &ec); |
- frac = ucurr_getDefaultFractionDigitsForUsage(theCurrency, fCurrencyUsage, &ec); |
- } |
- |
- NumberFormat::setCurrency(theCurrency, ec); |
- if (U_FAILURE(ec)) return; |
- |
- if (fCurrencySignCount != fgCurrencySignCountZero) { |
- // NULL or empty currency is *legal* and indicates no currency. |
- if (isCurr) { |
- setRoundingIncrement(rounding); |
- setMinimumFractionDigits(frac); |
- setMaximumFractionDigits(frac); |
- } |
- expandAffixes(NULL); |
- } |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->setSignificantDigitsUsed(useSignificantDigits); |
} |
void DecimalFormat::setCurrency(const UChar* theCurrency, UErrorCode& ec) { |
// set the currency before compute affixes to get the right currency names |
NumberFormat::setCurrency(theCurrency, ec); |
- if (fFormatPattern.indexOf(fgTripleCurrencySign, 3, 0) != -1) { |
- UnicodeString savedPtn = fFormatPattern; |
- setupCurrencyAffixes(fFormatPattern, TRUE, TRUE, ec); |
- UParseError parseErr; |
- applyPattern(savedPtn, FALSE, parseErr, ec); |
- } |
- // set the currency after apply pattern to get the correct rounding/fraction |
- setCurrencyInternally(theCurrency, ec); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
+ fImpl->updateCurrency(ec); |
} |
void DecimalFormat::setCurrencyUsage(UCurrencyUsage newContext, UErrorCode* ec){ |
- fCurrencyUsage = newContext; |
- |
- const UChar* theCurrency = getCurrency(); |
- |
- // We set rounding/digit based on currency context |
- if(theCurrency){ |
- double rounding = ucurr_getRoundingIncrementForUsage(theCurrency, fCurrencyUsage, ec); |
- int32_t frac = ucurr_getDefaultFractionDigitsForUsage(theCurrency, fCurrencyUsage, ec); |
- |
- if (U_SUCCESS(*ec)) { |
- setRoundingIncrement(rounding); |
- setMinimumFractionDigits(frac); |
- setMaximumFractionDigits(frac); |
- } |
- } |
+ fImpl->setCurrencyUsage(newContext, *ec); |
} |
UCurrencyUsage DecimalFormat::getCurrencyUsage() const { |
- return fCurrencyUsage; |
+ return fImpl->getCurrencyUsage(); |
} |
// Deprecated variant with no UErrorCode parameter |
void DecimalFormat::setCurrency(const UChar* theCurrency) { |
UErrorCode ec = U_ZERO_ERROR; |
setCurrency(theCurrency, ec); |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
} |
void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const { |
- if (fSymbols == NULL) { |
+ if (fImpl->fSymbols == NULL) { |
ec = U_MEMORY_ALLOCATION_ERROR; |
return; |
} |
@@ -5280,49 +2955,13 @@ void DecimalFormat::getEffectiveCurrency(UChar* result, UErrorCode& ec) const { |
const UChar* c = getCurrency(); |
if (*c == 0) { |
const UnicodeString &intl = |
- fSymbols->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); |
+ fImpl->getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol); |
c = intl.getBuffer(); // ok for intl to go out of scope |
} |
u_strncpy(result, c, 3); |
result[3] = 0; |
} |
-/** |
- * Return the number of fraction digits to display, or the total |
- * number of digits for significant digit formats and exponential |
- * formats. |
- */ |
-int32_t |
-DecimalFormat::precision() const { |
- if (areSignificantDigitsUsed()) { |
- return getMaximumSignificantDigits(); |
- } else if (fUseExponentialNotation) { |
- return getMinimumIntegerDigits() + getMaximumFractionDigits(); |
- } else { |
- return getMaximumFractionDigits(); |
- } |
-} |
- |
- |
-// TODO: template algorithm |
-Hashtable* |
-DecimalFormat::initHashForAffix(UErrorCode& status) { |
- if ( U_FAILURE(status) ) { |
- return NULL; |
- } |
- Hashtable* hTable; |
- if ( (hTable = new Hashtable(TRUE, status)) == NULL ) { |
- status = U_MEMORY_ALLOCATION_ERROR; |
- return NULL; |
- } |
- if ( U_FAILURE(status) ) { |
- delete hTable; |
- return NULL; |
- } |
- hTable->setValueComparator(decimfmtAffixValueComparator); |
- return hTable; |
-} |
- |
Hashtable* |
DecimalFormat::initHashForAffixPattern(UErrorCode& status) { |
if ( U_FAILURE(status) ) { |
@@ -5342,31 +2981,12 @@ DecimalFormat::initHashForAffixPattern(UErrorCode& status) { |
} |
void |
-DecimalFormat::deleteHashForAffix(Hashtable*& table) |
-{ |
- if ( table == NULL ) { |
- return; |
- } |
- int32_t pos = -1; |
- const UHashElement* element = NULL; |
- while ( (element = table->nextElement(pos)) != NULL ) { |
- const UHashTok valueTok = element->value; |
- const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer; |
- delete value; |
- } |
- delete table; |
- table = NULL; |
-} |
- |
- |
- |
-void |
DecimalFormat::deleteHashForAffixPattern() |
{ |
if ( fAffixPatternsForCurrency == NULL ) { |
return; |
} |
- int32_t pos = -1; |
+ int32_t pos = UHASH_FIRST; |
const UHashElement* element = NULL; |
while ( (element = fAffixPatternsForCurrency->nextElement(pos)) != NULL ) { |
const UHashTok valueTok = element->value; |
@@ -5385,7 +3005,7 @@ DecimalFormat::copyHashForAffixPattern(const Hashtable* source, |
if ( U_FAILURE(status) ) { |
return; |
} |
- int32_t pos = -1; |
+ int32_t pos = UHASH_FIRST; |
const UHashElement* element = NULL; |
if ( source ) { |
while ( (element = source->nextElement(pos)) != NULL ) { |
@@ -5407,29 +3027,22 @@ DecimalFormat::copyHashForAffixPattern(const Hashtable* source, |
} |
} |
-// this is only overridden to call handleChanged() for fastpath purposes. |
void |
DecimalFormat::setGroupingUsed(UBool newValue) { |
NumberFormat::setGroupingUsed(newValue); |
- handleChanged(); |
+ fImpl->updateGrouping(); |
} |
-// this is only overridden to call handleChanged() for fastpath purposes. |
void |
DecimalFormat::setParseIntegerOnly(UBool newValue) { |
NumberFormat::setParseIntegerOnly(newValue); |
- handleChanged(); |
} |
-// this is only overridden to call handleChanged() for fastpath purposes. |
-// setContext doesn't affect the fastPath right now, but this is called for completeness |
void |
DecimalFormat::setContext(UDisplayContext value, UErrorCode& status) { |
NumberFormat::setContext(value, status); |
- handleChanged(); |
} |
- |
DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr, |
int32_t newValue, |
UErrorCode &status) { |
@@ -5528,16 +3141,24 @@ DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr, |
if(!fBoolFlags.isValidValue(newValue)) { |
status = U_ILLEGAL_ARGUMENT_ERROR; |
} else { |
+ if (attr == UNUM_FORMAT_FAIL_IF_MORE_THAN_MAX_DIGITS) { |
+ fImpl->setFailIfMoreThanMaxDigits((UBool) newValue); |
+ } |
fBoolFlags.set(attr, newValue); |
} |
break; |
case UNUM_SCALE: |
- fScale = newValue; |
+ fImpl->setScale(newValue); |
break; |
case UNUM_CURRENCY_USAGE: |
setCurrencyUsage((UCurrencyUsage)newValue, &status); |
+ break; |
+ |
+ case UNUM_MINIMUM_GROUPING_DIGITS: |
+ setMinimumGroupingDigits(newValue); |
+ break; |
default: |
status = U_UNSUPPORTED_ERROR; |
@@ -5616,10 +3237,13 @@ int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr, |
return fBoolFlags.get(attr); |
case UNUM_SCALE: |
- return fScale; |
+ return fImpl->fScale; |
case UNUM_CURRENCY_USAGE: |
- return fCurrencyUsage; |
+ return fImpl->getCurrencyUsage(); |
+ |
+ case UNUM_MINIMUM_GROUPING_DIGITS: |
+ return getMinimumGroupingDigits(); |
default: |
status = U_UNSUPPORTED_ERROR; |
@@ -5632,41 +3256,9 @@ int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr, |
#if UCONFIG_HAVE_PARSEALLINPUT |
void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) { |
fParseAllInput = value; |
-#if UCONFIG_FORMAT_FASTPATHS_49 |
- handleChanged(); |
-#endif |
} |
#endif |
-void |
-DecimalFormat::copyHashForAffix(const Hashtable* source, |
- Hashtable* target, |
- UErrorCode& status) { |
- if ( U_FAILURE(status) ) { |
- return; |
- } |
- int32_t pos = -1; |
- const UHashElement* element = NULL; |
- if ( source ) { |
- while ( (element = source->nextElement(pos)) != NULL ) { |
- const UHashTok keyTok = element->key; |
- const UnicodeString* key = (UnicodeString*)keyTok.pointer; |
- |
- const UHashTok valueTok = element->value; |
- const AffixesForCurrency* value = (AffixesForCurrency*)valueTok.pointer; |
- AffixesForCurrency* copy = new AffixesForCurrency( |
- value->negPrefixForCurrency, |
- value->negSuffixForCurrency, |
- value->posPrefixForCurrency, |
- value->posSuffixForCurrency); |
- target->put(UnicodeString(*key), copy, status); |
- if ( U_FAILURE(status) ) { |
- return; |
- } |
- } |
- } |
-} |
- |
U_NAMESPACE_END |
#endif /* #if !UCONFIG_NO_FORMATTING */ |