ICU-11564 Improve the thread safety of RBNF.
The recursion count is now a method argument instead of a data member. Setting the DecimalFormatSymbols no longer reparses the rules, but it just sets a new version of DecimalFormatSymbols instead. X-SVN-Rev: 37387
This commit is contained in:
parent
5c4fe2e90a
commit
e7b812f712
@ -1,6 +1,6 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfrs.cpp
|
||||
@ -125,7 +125,6 @@ NFRuleSet::NFRuleSet(UnicodeString* descriptions, int32_t index, UErrorCode& sta
|
||||
, fIsFractionRuleSet(FALSE)
|
||||
, fIsPublic(FALSE)
|
||||
, fIsParseable(TRUE)
|
||||
, fRecursionCount(0)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
fractionRules[i] = NULL;
|
||||
@ -332,36 +331,39 @@ NFRuleSet::operator==(const NFRuleSet& rhs) const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define RECURSION_LIMIT 50
|
||||
void
|
||||
NFRuleSet::setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status) {
|
||||
for (uint32_t i = 0; i < rules.size(); ++i) {
|
||||
rules[i]->setDecimalFormatSymbols(newSymbols, status);
|
||||
}
|
||||
}
|
||||
|
||||
#define RECURSION_LIMIT 64
|
||||
|
||||
void
|
||||
NFRuleSet::format(int64_t number, UnicodeString& toAppendTo, int32_t pos, UErrorCode& status) const
|
||||
NFRuleSet::format(int64_t number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
NFRule *rule = findNormalRule(number);
|
||||
if (rule) { // else error, but can't report it
|
||||
NFRuleSet* ncThis = (NFRuleSet*)this;
|
||||
if (ncThis->fRecursionCount++ >= RECURSION_LIMIT) {
|
||||
if (recursionCount >= RECURSION_LIMIT) {
|
||||
// stop recursion
|
||||
ncThis->fRecursionCount = 0;
|
||||
status = U_INVALID_STATE_ERROR;
|
||||
} else {
|
||||
rule->doFormat(number, toAppendTo, pos, status);
|
||||
ncThis->fRecursionCount--;
|
||||
rule->doFormat(number, toAppendTo, pos, ++recursionCount, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NFRuleSet::format(double number, UnicodeString& toAppendTo, int32_t pos, UErrorCode& status) const
|
||||
NFRuleSet::format(double number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
NFRule *rule = findDoubleRule(number);
|
||||
if (rule) { // else error, but can't report it
|
||||
NFRuleSet* ncThis = (NFRuleSet*)this;
|
||||
if (ncThis->fRecursionCount++ >= RECURSION_LIMIT) {
|
||||
if (recursionCount >= RECURSION_LIMIT) {
|
||||
// stop recursion
|
||||
ncThis->fRecursionCount = 0;
|
||||
status = U_INVALID_STATE_ERROR;
|
||||
} else {
|
||||
rule->doFormat(number, toAppendTo, pos, status);
|
||||
ncThis->fRecursionCount--;
|
||||
rule->doFormat(number, toAppendTo, pos, ++recursionCount, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfrs.h
|
||||
@ -48,13 +48,15 @@ public:
|
||||
void getName(UnicodeString& result) const { result.setTo(name); }
|
||||
UBool isNamed(const UnicodeString& _name) const { return this->name == _name; }
|
||||
|
||||
void format(int64_t number, UnicodeString& toAppendTo, int32_t pos, UErrorCode& status) const;
|
||||
void format(double number, UnicodeString& toAppendTo, int32_t pos, UErrorCode& status) const;
|
||||
void format(int64_t number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
void format(double number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
|
||||
UBool parse(const UnicodeString& text, ParsePosition& pos, double upperBound, Formattable& result) const;
|
||||
|
||||
void appendRules(UnicodeString& result) const; // toString
|
||||
|
||||
void setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status);
|
||||
|
||||
private:
|
||||
NFRule * findNormalRule(int64_t number) const;
|
||||
NFRule * findDoubleRule(double number) const;
|
||||
@ -68,7 +70,6 @@ private:
|
||||
UBool fIsFractionRuleSet;
|
||||
UBool fIsPublic;
|
||||
UBool fIsParseable;
|
||||
int32_t fRecursionCount;
|
||||
|
||||
NFRuleSet(const NFRuleSet &other); // forbid copying of this class
|
||||
NFRuleSet &operator=(const NFRuleSet &other); // forbid copying of this class
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfrule.cpp
|
||||
@ -682,7 +682,7 @@ NFRule::_appendRuleText(UnicodeString& result) const
|
||||
* should be inserted
|
||||
*/
|
||||
void
|
||||
NFRule::doFormat(int64_t number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const
|
||||
NFRule::doFormat(int64_t number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
// first, insert the rule's rule text into toInsertInto at the
|
||||
// specified position, then insert the results of the substitutions
|
||||
@ -710,10 +710,10 @@ NFRule::doFormat(int64_t number, UnicodeString& toInsertInto, int32_t pos, UErro
|
||||
}
|
||||
|
||||
if (!sub2->isNullSubstitution()) {
|
||||
sub2->doSubstitution(number, toInsertInto, pos - (sub2->getPos() > pluralRuleStart ? lengthOffset : 0), status);
|
||||
sub2->doSubstitution(number, toInsertInto, pos - (sub2->getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount, status);
|
||||
}
|
||||
if (!sub1->isNullSubstitution()) {
|
||||
sub1->doSubstitution(number, toInsertInto, pos - (sub1->getPos() > pluralRuleStart ? lengthOffset : 0), status);
|
||||
sub1->doSubstitution(number, toInsertInto, pos - (sub1->getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount, status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -727,7 +727,7 @@ NFRule::doFormat(int64_t number, UnicodeString& toInsertInto, int32_t pos, UErro
|
||||
* should be inserted
|
||||
*/
|
||||
void
|
||||
NFRule::doFormat(double number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const
|
||||
NFRule::doFormat(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
// first, insert the rule's rule text into toInsertInto at the
|
||||
// specified position, then insert the results of the substitutions
|
||||
@ -756,10 +756,10 @@ NFRule::doFormat(double number, UnicodeString& toInsertInto, int32_t pos, UError
|
||||
}
|
||||
|
||||
if (!sub2->isNullSubstitution()) {
|
||||
sub2->doSubstitution(number, toInsertInto, pos - (sub2->getPos() > pluralRuleStart ? lengthOffset : 0), status);
|
||||
sub2->doSubstitution(number, toInsertInto, pos - (sub2->getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount, status);
|
||||
}
|
||||
if (!sub1->isNullSubstitution()) {
|
||||
sub1->doSubstitution(number, toInsertInto, pos - (sub1->getPos() > pluralRuleStart ? lengthOffset : 0), status);
|
||||
sub1->doSubstitution(number, toInsertInto, pos - (sub1->getPos() > pluralRuleStart ? lengthOffset : 0), recursionCount, status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1522,6 +1522,16 @@ NFRule::allIgnorable(const UnicodeString& str, UErrorCode& status) const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
NFRule::setDecimalFormatSymbols(const DecimalFormatSymbols& newSymbols, UErrorCode& status) {
|
||||
if (sub1 != NULL) {
|
||||
sub1->setDecimalFormatSymbols(newSymbols, status);
|
||||
}
|
||||
if (sub2 != NULL) {
|
||||
sub2->setDecimalFormatSymbols(newSymbols, status);
|
||||
}
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
/* U_HAVE_RBNF */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -62,8 +62,8 @@ public:
|
||||
|
||||
double getDivisor() const { return uprv_pow(radix, exponent); }
|
||||
|
||||
void doFormat(int64_t number, UnicodeString& toAppendTo, int32_t pos, UErrorCode& status) const;
|
||||
void doFormat(double number, UnicodeString& toAppendTo, int32_t pos, UErrorCode& status) const;
|
||||
void doFormat(int64_t number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
void doFormat(double number, UnicodeString& toAppendTo, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
|
||||
UBool doParse(const UnicodeString& text,
|
||||
ParsePosition& pos,
|
||||
@ -78,6 +78,8 @@ public:
|
||||
int32_t findTextLenient(const UnicodeString& str, const UnicodeString& key,
|
||||
int32_t startingAt, int32_t* resultCount) const;
|
||||
|
||||
void setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status);
|
||||
|
||||
private:
|
||||
void parseRuleDescriptor(UnicodeString& descriptor, UErrorCode& status);
|
||||
void extractSubstitutions(const NFRuleSet* ruleSet, const UnicodeString &ruleText, const NFRule* predecessor, UErrorCode& status);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfsubs.cpp
|
||||
@ -149,8 +149,8 @@ public:
|
||||
|
||||
virtual UBool operator==(const NFSubstitution& rhs) const;
|
||||
|
||||
virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const;
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const;
|
||||
virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
|
||||
virtual int64_t transformNumber(int64_t number) const { return number % ldivisor; }
|
||||
virtual double transformNumber(double number) const { return uprv_fmod(number, divisor); }
|
||||
@ -218,8 +218,8 @@ public:
|
||||
|
||||
virtual UBool operator==(const NFSubstitution& rhs) const;
|
||||
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const;
|
||||
virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {}
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, int32_t /*recursionCount*/, UErrorCode& /*status*/) const {}
|
||||
virtual int64_t transformNumber(int64_t /*number*/) const { return 0; }
|
||||
virtual double transformNumber(double number) const { return number - uprv_floor(number); }
|
||||
|
||||
@ -294,8 +294,8 @@ public:
|
||||
virtual int64_t transformNumber(int64_t number) const { return number * ldenominator; }
|
||||
virtual double transformNumber(double number) const { return uprv_round(number * denominator); }
|
||||
|
||||
virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {}
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const;
|
||||
virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, int32_t /*recursionCount*/, UErrorCode& /*status*/) const {}
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
virtual UBool doParse(const UnicodeString& text,
|
||||
ParsePosition& parsePosition,
|
||||
double baseValue,
|
||||
@ -327,8 +327,8 @@ public:
|
||||
virtual ~NullSubstitution();
|
||||
|
||||
virtual void toString(UnicodeString& /*result*/) const {}
|
||||
virtual void doSubstitution(double /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {}
|
||||
virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, UErrorCode& /*status*/) const {}
|
||||
virtual void doSubstitution(double /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, int32_t /*recursionCount*/, UErrorCode& /*status*/) const {}
|
||||
virtual void doSubstitution(int64_t /*number*/, UnicodeString& /*toInsertInto*/, int32_t /*_pos*/, int32_t /*recursionCount*/, UErrorCode& /*status*/) const {}
|
||||
virtual int64_t transformNumber(int64_t /*number*/) const { return 0; }
|
||||
virtual double transformNumber(double /*number*/) const { return 0; }
|
||||
virtual UBool doParse(const UnicodeString& /*text*/,
|
||||
@ -518,8 +518,9 @@ NFSubstitution::NFSubstitution(int32_t _pos,
|
||||
|
||||
NFSubstitution::~NFSubstitution()
|
||||
{
|
||||
// cast away const
|
||||
delete (NumberFormat*)numberFormat; numberFormat = NULL;
|
||||
// cast away const
|
||||
delete (NumberFormat*)numberFormat;
|
||||
numberFormat = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -534,6 +535,12 @@ NFSubstitution::setDivisor(int32_t /*radix*/, int32_t /*exponent*/, UErrorCode&
|
||||
// a no-op for all substitutions except multiplier and modulus substitutions
|
||||
}
|
||||
|
||||
void
|
||||
NFSubstitution::setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& /*status*/) {
|
||||
if (numberFormat != NULL) {
|
||||
numberFormat->setDecimalFormatSymbols(newSymbols);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// boilerplate
|
||||
@ -602,13 +609,13 @@ NFSubstitution::toString(UnicodeString& text) const
|
||||
* position to determine exactly where to insert the new text)
|
||||
*/
|
||||
void
|
||||
NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, UErrorCode& status) const
|
||||
NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
if (ruleSet != NULL) {
|
||||
// perform a transformation on the number that is dependent
|
||||
// on the type of substitution this is, then just call its
|
||||
// rule set's format() method to format the result
|
||||
ruleSet->format(transformNumber(number), toInsertInto, _pos + this->pos, status);
|
||||
ruleSet->format(transformNumber(number), toInsertInto, _pos + this->pos, recursionCount, status);
|
||||
} else if (numberFormat != NULL) {
|
||||
// or perform the transformation on the number (preserving
|
||||
// the result's fractional part if the formatter it set
|
||||
@ -636,7 +643,7 @@ NFSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int3
|
||||
* position to determine exactly where to insert the new text)
|
||||
*/
|
||||
void
|
||||
NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos, UErrorCode& status) const {
|
||||
NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const {
|
||||
// perform a transformation on the number being formatted that
|
||||
// is dependent on the type of substitution this is
|
||||
double numberToFormat = transformNumber(number);
|
||||
@ -644,14 +651,14 @@ NFSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32
|
||||
// if the result is an integer, from here on out we work in integer
|
||||
// space (saving time and memory and preserving accuracy)
|
||||
if (numberToFormat == uprv_floor(numberToFormat) && ruleSet != NULL) {
|
||||
ruleSet->format(util64_fromDouble(numberToFormat), toInsertInto, _pos + this->pos, status);
|
||||
ruleSet->format(util64_fromDouble(numberToFormat), toInsertInto, _pos + this->pos, recursionCount, status);
|
||||
|
||||
// if the result isn't an integer, then call either our rule set's
|
||||
// format() method or our DecimalFormat's format() method to
|
||||
// format the result
|
||||
} else {
|
||||
if (ruleSet != NULL) {
|
||||
ruleSet->format(numberToFormat, toInsertInto, _pos + this->pos, status);
|
||||
ruleSet->format(numberToFormat, toInsertInto, _pos + this->pos, recursionCount, status);
|
||||
} else if (numberFormat != NULL) {
|
||||
UnicodeString temp;
|
||||
numberFormat->format(numberToFormat, temp);
|
||||
@ -894,19 +901,19 @@ UBool ModulusSubstitution::operator==(const NFSubstitution& rhs) const
|
||||
* @param pos The position of the rule text in toInsertInto
|
||||
*/
|
||||
void
|
||||
ModulusSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, UErrorCode& status) const
|
||||
ModulusSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
// if this isn't a >>> substitution, just use the inherited version
|
||||
// of this function (which uses either a rule set or a DecimalFormat
|
||||
// to format its substitution value)
|
||||
if (ruleToUse == NULL) {
|
||||
NFSubstitution::doSubstitution(number, toInsertInto, _pos, status);
|
||||
NFSubstitution::doSubstitution(number, toInsertInto, _pos, recursionCount, status);
|
||||
|
||||
// a >>> substitution goes straight to a particular rule to
|
||||
// format the substitution value
|
||||
} else {
|
||||
int64_t numberToFormat = transformNumber(number);
|
||||
ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), status);
|
||||
ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), recursionCount, status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -919,20 +926,20 @@ ModulusSubstitution::doSubstitution(int64_t number, UnicodeString& toInsertInto,
|
||||
* @param pos The position of the rule text in toInsertInto
|
||||
*/
|
||||
void
|
||||
ModulusSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos, UErrorCode& status) const
|
||||
ModulusSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t _pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
// if this isn't a >>> substitution, just use the inherited version
|
||||
// of this function (which uses either a rule set or a DecimalFormat
|
||||
// to format its substitution value)
|
||||
if (ruleToUse == NULL) {
|
||||
NFSubstitution::doSubstitution(number, toInsertInto, _pos, status);
|
||||
NFSubstitution::doSubstitution(number, toInsertInto, _pos, recursionCount, status);
|
||||
|
||||
// a >>> substitution goes straight to a particular rule to
|
||||
// format the substitution value
|
||||
} else {
|
||||
double numberToFormat = transformNumber(number);
|
||||
|
||||
ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), status);
|
||||
ruleToUse->doFormat(numberToFormat, toInsertInto, _pos + getPos(), recursionCount, status);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1058,12 +1065,12 @@ FractionalPartSubstitution::FractionalPartSubstitution(int32_t _pos,
|
||||
*/
|
||||
void
|
||||
FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInsertInto,
|
||||
int32_t _pos, UErrorCode& status) const
|
||||
int32_t _pos, int32_t recursionCount, UErrorCode& status) const
|
||||
{
|
||||
// if we're not in "byDigits" mode, just use the inherited
|
||||
// doSubstitution() routine
|
||||
if (!byDigits) {
|
||||
NFSubstitution::doSubstitution(number, toInsertInto, _pos, status);
|
||||
NFSubstitution::doSubstitution(number, toInsertInto, _pos, recursionCount, status);
|
||||
|
||||
// if we're in "byDigits" mode, transform the value into an integer
|
||||
// by moving the decimal point eight places to the right and
|
||||
@ -1105,13 +1112,13 @@ FractionalPartSubstitution::doSubstitution(double number, UnicodeString& toInser
|
||||
pad = TRUE;
|
||||
}
|
||||
int64_t digit = didx>=0 ? dl.getDigit(didx) - '0' : 0;
|
||||
getRuleSet()->format(digit, toInsertInto, _pos + getPos(), status);
|
||||
getRuleSet()->format(digit, toInsertInto, _pos + getPos(), recursionCount, status);
|
||||
}
|
||||
|
||||
if (!pad) {
|
||||
// hack around lack of precision in digitlist. if we would end up with
|
||||
// "foo point" make sure we add a " zero" to the end.
|
||||
getRuleSet()->format((int64_t)0, toInsertInto, _pos + getPos(), status);
|
||||
getRuleSet()->format((int64_t)0, toInsertInto, _pos + getPos(), recursionCount, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1230,7 +1237,7 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(AbsoluteValueSubstitution)
|
||||
//===================================================================
|
||||
|
||||
void
|
||||
NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t apos, UErrorCode& status) const {
|
||||
NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto, int32_t apos, int32_t recursionCount, UErrorCode& status) const {
|
||||
// perform a transformation on the number being formatted that
|
||||
// is dependent on the type of substitution this is
|
||||
|
||||
@ -1244,7 +1251,7 @@ NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto
|
||||
int32_t len = toInsertInto.length();
|
||||
while ((nf *= 10) < denominator) {
|
||||
toInsertInto.insert(apos + getPos(), gSpace);
|
||||
aruleSet->format((int64_t)0, toInsertInto, apos + getPos(), status);
|
||||
aruleSet->format((int64_t)0, toInsertInto, apos + getPos(), recursionCount, status);
|
||||
}
|
||||
apos += toInsertInto.length() - len;
|
||||
}
|
||||
@ -1252,14 +1259,14 @@ NumeratorSubstitution::doSubstitution(double number, UnicodeString& toInsertInto
|
||||
// if the result is an integer, from here on out we work in integer
|
||||
// space (saving time and memory and preserving accuracy)
|
||||
if (numberToFormat == longNF && aruleSet != NULL) {
|
||||
aruleSet->format(longNF, toInsertInto, apos + getPos(), status);
|
||||
aruleSet->format(longNF, toInsertInto, apos + getPos(), recursionCount, status);
|
||||
|
||||
// if the result isn't an integer, then call either our rule set's
|
||||
// format() method or our DecimalFormat's format() method to
|
||||
// format the result
|
||||
} else {
|
||||
if (aruleSet != NULL) {
|
||||
aruleSet->format(numberToFormat, toInsertInto, apos + getPos(), status);
|
||||
aruleSet->format(numberToFormat, toInsertInto, apos + getPos(), recursionCount, status);
|
||||
} else {
|
||||
UnicodeString temp;
|
||||
getNumberFormat()->format(numberToFormat, temp, status);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines
|
||||
* Copyright (C) 1997-2015, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: nfsubs.h
|
||||
@ -32,7 +32,7 @@ U_NAMESPACE_BEGIN
|
||||
class NFSubstitution : public UObject {
|
||||
int32_t pos;
|
||||
const NFRuleSet* ruleSet;
|
||||
const DecimalFormat* numberFormat;
|
||||
DecimalFormat* numberFormat;
|
||||
|
||||
protected:
|
||||
NFSubstitution(int32_t pos,
|
||||
@ -98,6 +98,8 @@ public:
|
||||
*/
|
||||
virtual void toString(UnicodeString& result) const;
|
||||
|
||||
void setDecimalFormatSymbols(const DecimalFormatSymbols &newSymbols, UErrorCode& status);
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// formatting
|
||||
//-----------------------------------------------------------------------
|
||||
@ -112,7 +114,7 @@ public:
|
||||
* rule text begins (this value is added to this substitution's
|
||||
* position to determine exactly where to insert the new text)
|
||||
*/
|
||||
virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const;
|
||||
virtual void doSubstitution(int64_t number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Performs a mathematical operation on the number, formats it using
|
||||
@ -124,7 +126,7 @@ public:
|
||||
* rule text begins (this value is added to this substitution's
|
||||
* position to determine exactly where to insert the new text)
|
||||
*/
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, UErrorCode& status) const;
|
||||
virtual void doSubstitution(double number, UnicodeString& toInsertInto, int32_t pos, int32_t recursionCount, UErrorCode& status) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2014, International Business Machines Corporation
|
||||
* Copyright (C) 1997-2015, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
@ -1068,7 +1068,7 @@ RuleBasedNumberFormat::format(int32_t number,
|
||||
if (defaultRuleSet) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t startPos = toAppendTo.length();
|
||||
defaultRuleSet->format((int64_t)number, toAppendTo, toAppendTo.length(), status);
|
||||
defaultRuleSet->format((int64_t)number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
adjustForCapitalizationContext(startPos, toAppendTo);
|
||||
}
|
||||
return toAppendTo;
|
||||
@ -1083,7 +1083,7 @@ RuleBasedNumberFormat::format(int64_t number,
|
||||
if (defaultRuleSet) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t startPos = toAppendTo.length();
|
||||
defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), status);
|
||||
defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
adjustForCapitalizationContext(startPos, toAppendTo);
|
||||
}
|
||||
return toAppendTo;
|
||||
@ -1104,7 +1104,7 @@ RuleBasedNumberFormat::format(double number,
|
||||
}
|
||||
} else if (defaultRuleSet) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), status);
|
||||
defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
}
|
||||
return adjustForCapitalizationContext(startPos, toAppendTo);
|
||||
}
|
||||
@ -1126,7 +1126,7 @@ RuleBasedNumberFormat::format(int32_t number,
|
||||
NFRuleSet *rs = findRuleSet(ruleSetName, status);
|
||||
if (rs) {
|
||||
int32_t startPos = toAppendTo.length();
|
||||
rs->format((int64_t)number, toAppendTo, toAppendTo.length(), status);
|
||||
rs->format((int64_t)number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
adjustForCapitalizationContext(startPos, toAppendTo);
|
||||
}
|
||||
}
|
||||
@ -1150,7 +1150,7 @@ RuleBasedNumberFormat::format(int64_t number,
|
||||
NFRuleSet *rs = findRuleSet(ruleSetName, status);
|
||||
if (rs) {
|
||||
int32_t startPos = toAppendTo.length();
|
||||
rs->format(number, toAppendTo, toAppendTo.length(), status);
|
||||
rs->format(number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
adjustForCapitalizationContext(startPos, toAppendTo);
|
||||
}
|
||||
}
|
||||
@ -1174,7 +1174,7 @@ RuleBasedNumberFormat::format(double number,
|
||||
NFRuleSet *rs = findRuleSet(ruleSetName, status);
|
||||
if (rs) {
|
||||
int32_t startPos = toAppendTo.length();
|
||||
rs->format(number, toAppendTo, toAppendTo.length(), status);
|
||||
rs->format(number, toAppendTo, toAppendTo.length(), 0, status);
|
||||
adjustForCapitalizationContext(startPos, toAppendTo);
|
||||
}
|
||||
}
|
||||
@ -1735,7 +1735,7 @@ RuleBasedNumberFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsTo
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
for (int32_t i = 0; i < numRuleSets; i++) {
|
||||
ruleSets[i]->parseRules(ruleSetDescriptions[i], this, status);
|
||||
ruleSets[i]->setDecimalFormatSymbols(*symbolsToAdopt, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user