ICU-2296 optimize use of UnicodeString, copy string objects less often

X-SVN-Rev: 10029
This commit is contained in:
Markus Scherer 2002-10-12 01:09:00 +00:00
parent b6de7e771f
commit d8cd28cf02
8 changed files with 320 additions and 268 deletions

View File

@ -68,7 +68,8 @@ DecimalFormatSymbols::DecimalFormatSymbols(const DecimalFormatSymbols &source)
{
int i;
for(i = 0; i < (int)kFormatSymbolCount; ++i) {
fSymbols[(ENumberFormatSymbol)i] = source.fSymbols[(ENumberFormatSymbol)i];
// fastCopyFrom is safe, see docs on fSymbols
fSymbols[(ENumberFormatSymbol)i].fastCopyFrom(source.fSymbols[(ENumberFormatSymbol)i]);
}
}
@ -82,7 +83,8 @@ DecimalFormatSymbols::operator=(const DecimalFormatSymbols& rhs)
{
int i;
for(i = 0; i < (int)kFormatSymbolCount; ++i) {
fSymbols[(ENumberFormatSymbol)i] = rhs.fSymbols[(ENumberFormatSymbol)i];
// fastCopyFrom is safe, see docs on fSymbols
fSymbols[(ENumberFormatSymbol)i].fastCopyFrom(rhs.fSymbols[(ENumberFormatSymbol)i]);
}
}
return *this;
@ -139,7 +141,7 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
return;
}
for(i = 0; i<numberElementsLength; i++) {
numberElements[i] = numberElementsRes.getStringEx(i, status);
numberElements[i].fastCopyFrom(numberElementsRes.getStringEx(i, status));
}
// Gets the currency element array.
@ -153,7 +155,7 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
return;
}
for(i = 0; i<currencyElementsLength; i++) {
currencyElements[i] = currencyElementsRes.getStringEx(i, status);
currencyElements[i].fastCopyFrom(currencyElementsRes.getStringEx(i, status));
}
if (U_FAILURE(status)) return;
@ -178,30 +180,30 @@ DecimalFormatSymbols::initialize(const Locale& loc, UErrorCode& status,
void
DecimalFormatSymbols::initialize(const UnicodeString* numberElements, const UnicodeString* currencyElements)
{
fSymbols[kDecimalSeparatorSymbol] = numberElements[0];
fSymbols[kGroupingSeparatorSymbol] = numberElements[1];
fSymbols[kPatternSeparatorSymbol] = numberElements[2];
fSymbols[kPercentSymbol] = numberElements[3];
fSymbols[kZeroDigitSymbol] = numberElements[4];
fSymbols[kDigitSymbol] = numberElements[5];
fSymbols[kMinusSignSymbol] = numberElements[6];
fSymbols[kDecimalSeparatorSymbol].fastCopyFrom(numberElements[0]);
fSymbols[kGroupingSeparatorSymbol].fastCopyFrom(numberElements[1]);
fSymbols[kPatternSeparatorSymbol].fastCopyFrom(numberElements[2]);
fSymbols[kPercentSymbol].fastCopyFrom(numberElements[3]);
fSymbols[kZeroDigitSymbol].fastCopyFrom(numberElements[4]);
fSymbols[kDigitSymbol].fastCopyFrom(numberElements[5]);
fSymbols[kMinusSignSymbol].fastCopyFrom(numberElements[6]);
fSymbols[kPlusSignSymbol] = (UChar)0x002b; // '+' Hard coded for now; get from resource later
fSymbols[kCurrencySymbol] = currencyElements[0];
fSymbols[kIntlCurrencySymbol] = currencyElements[1];
fSymbols[kCurrencySymbol].fastCopyFrom(currencyElements[0]);
fSymbols[kIntlCurrencySymbol].fastCopyFrom(currencyElements[1]);
// if the resource data specified the empty string as the monetary decimal
// separator, that means we should just use the regular separator as the
// monetary separator
fSymbols[kMonetarySeparatorSymbol] =
fSymbols[kMonetarySeparatorSymbol].fastCopyFrom(
currencyElements[2].length() > 0 ?
currencyElements[2] :
fSymbols[kDecimalSeparatorSymbol];
fSymbols[kDecimalSeparatorSymbol]);
fSymbols[kExponentialSymbol] = numberElements[7];
fSymbols[kPerMillSymbol] = numberElements[8];
fSymbols[kExponentialSymbol].fastCopyFrom(numberElements[7]);
fSymbols[kPerMillSymbol].fastCopyFrom(numberElements[8]);
fSymbols[kPadEscapeSymbol] = (UChar)0x002a; // '*' Hard coded for now; get from resource later
fSymbols[kInfinitySymbol] = numberElements[9];
fSymbols[kNaNSymbol] = numberElements[10];
fSymbols[kInfinitySymbol].fastCopyFrom(numberElements[9]);
fSymbols[kNaNSymbol].fastCopyFrom(numberElements[10]);
}
// initialize with default values

View File

@ -577,7 +577,7 @@ DecimalFormat::format( double number,
if (fieldPosition.getField() == NumberFormat::kIntegerField)
fieldPosition.setBeginIndex(result.length());
result += fSymbols->getSymbol(DecimalFormatSymbols::kNaNSymbol);
result += getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
if (fieldPosition.getField() == NumberFormat::kIntegerField)
fieldPosition.setEndIndex(result.length());
@ -623,7 +623,7 @@ DecimalFormat::format( double number,
if (fieldPosition.getField() == NumberFormat::kIntegerField)
fieldPosition.setBeginIndex(result.length());
result += fSymbols->getSymbol(DecimalFormatSymbols::kInfinitySymbol);
result += getConstSymbol(DecimalFormatSymbols::kInfinitySymbol);
if (fieldPosition.getField() == NumberFormat::kIntegerField)
fieldPosition.setEndIndex(result.length());
@ -724,12 +724,15 @@ DecimalFormat::subformat(UnicodeString& result,
UBool isInteger) const
{
// Gets the localized zero Unicode character.
UChar32 zero = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
int32_t zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
UnicodeString grouping(fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
UnicodeString decimal(fIsCurrencyFormat ?
fSymbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol) :
fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
const UnicodeString *grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
const UnicodeString *decimal;
if(fIsCurrencyFormat) {
decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
} else {
decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
}
int32_t maxIntDig = getMaximumIntegerDigits();
int32_t minIntDig = getMinimumIntegerDigits();
@ -809,7 +812,7 @@ DecimalFormat::subformat(UnicodeString& result,
if (fieldPosition.getField() == NumberFormat::kIntegerField)
fieldPosition.setEndIndex(result.length());
result += (decimal);
result += *decimal;
// Record field information for caller.
if (fieldPosition.getField() == NumberFormat::kFractionField)
@ -839,8 +842,8 @@ DecimalFormat::subformat(UnicodeString& result,
// exponent digits. There is no maximum limit to the exponent
// digits, since truncating the exponent would result in an
// unacceptable inaccuracy.
result += fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol);
result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
// 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.
@ -848,9 +851,9 @@ DecimalFormat::subformat(UnicodeString& result,
exponent = 0;
if (exponent < 0) {
result += fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol);
result += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
} else if (fExponentSignAlwaysShown) {
result += fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol);
result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
}
DigitList expDigits;
@ -908,7 +911,7 @@ DecimalFormat::subformat(UnicodeString& result,
// Output grouping separator if necessary.
if (isGroupingPosition(i)) {
result.append(grouping);
result.append(*grouping);
}
}
@ -929,7 +932,7 @@ DecimalFormat::subformat(UnicodeString& result,
// Output the decimal separator if we always do so.
if (fDecimalSeparatorAlwaysShown || fractionPresent)
result += (decimal);
result += *decimal;
// Record field information for caller.
if (fieldPosition.getField() == NumberFormat::kFractionField)
@ -1061,9 +1064,9 @@ DecimalFormat::parse(const UnicodeString& text,
// special case NaN
// If the text is composed of the representation of NaN, returns NaN.length
UnicodeString nan(fSymbols->getSymbol(DecimalFormatSymbols::kNaNSymbol));
int32_t nanLen = (text.compare(parsePosition.getIndex(), nan.length(), nan)
? 0 : nan.length());
const UnicodeString *nan = &getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
int32_t nanLen = (text.compare(parsePosition.getIndex(), nan->length(), *nan)
? 0 : nan->length());
if (nanLen) {
parsePosition.setIndex(parsePosition.getIndex() + nanLen);
result.setDouble(uprv_getNaN());
@ -1175,9 +1178,9 @@ UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePos
}
// process digits or Inf, find decimal position
UnicodeString inf(fSymbols->getSymbol(DecimalFormatSymbols::kInfinitySymbol));
int32_t infLen = (text.compare(position, inf.length(), inf)
? 0 : inf.length());
const UnicodeString *inf = &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
status[fgStatusInfinite] = (UBool)infLen;
if (!infLen)
@ -1190,20 +1193,24 @@ UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePos
// exponent as needed.
digits.fDecimalAt = digits.fCount = 0;
UChar32 zero = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
UnicodeString decimal(fIsCurrencyFormat
? fSymbols->getSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol)
: fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
UnicodeString grouping(fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
UnicodeString exponentChar(fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol));
UChar32 zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
const UnicodeString *decimal;
if(fIsCurrencyFormat) {
decimal = &getConstSymbol(DecimalFormatSymbols::kMonetarySeparatorSymbol);
} else {
decimal = &getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
}
const UnicodeString *grouping = &getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
const UnicodeString *exponentChar = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
UBool sawDecimal = FALSE;
UBool sawDigit = FALSE;
int32_t backup = -1;
UChar32 ch;
int32_t digit;
int32_t textLength = text.length(); // One less pointer to follow
int32_t groupingLen = grouping.length();
int32_t decimalLen = decimal.length();
int32_t groupingLen = grouping->length();
int32_t decimalLen = decimal->length();
// We have to track digitCount ourselves, because digits.fCount will
// pin when the maximum allowable digits is reached.
@ -1262,14 +1269,14 @@ UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePos
}
// else ignore leading zeros in integer part of number.
}
else if (!text.compare(position, groupingLen, grouping) && isGroupingUsed())
else if (!text.compare(position, groupingLen, *grouping) && isGroupingUsed())
{
// Ignore grouping characters, if we are using them, but require
// that they be followed by a digit. Otherwise we backup and
// reprocess them.
backup = position;
}
else if (!text.compare(position, decimalLen, decimal) && !isParseIntegerOnly() && !sawDecimal)
else if (!text.compare(position, decimalLen, *decimal) && !isParseIntegerOnly() && !sawDecimal)
{
// If we're only parsing integers, or if we ALREADY saw the
// decimal, then don't parse this one.
@ -1277,57 +1284,59 @@ UBool DecimalFormat::subparse(const UnicodeString& text, ParsePosition& parsePos
digits.fDecimalAt = digitCount; // Not digits.fCount!
sawDecimal = TRUE;
}
else if (!text.caseCompare(position,
fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol).length(),
fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol),
U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit
{
// Parse sign, if present
int32_t pos = position + 1; // position + exponentSep.length();
DigitList exponentDigits;
if (pos < textLength)
else {
const UnicodeString *tmp;
tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit
{
if (!text.compare(pos,
fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol).length(),
fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol)))
// Parse sign, if present
int32_t pos = position + 1; // position + exponentSep.length();
DigitList exponentDigits;
if (pos < textLength)
{
++pos;
tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
if (!text.compare(pos, tmp->length(), *tmp))
{
++pos;
}
else {
tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
if (!text.compare(pos, tmp->length(), *tmp))
{
++pos;
exponentDigits.fIsPositive = FALSE;
}
}
}
else if (!text.compare(pos,
fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol).length(),
fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol)))
{
++pos;
exponentDigits.fIsPositive = FALSE;
while (pos < textLength) {
ch = text[(int32_t)pos];
digit = ch - zero;
if (digit < 0 || digit > 9) {
digit = u_charDigitValue(ch);
}
if (0 <= digit && digit <= 9) {
++pos;
exponentDigits.append((char)(digit + '0'));
} else {
break;
}
}
if (exponentDigits.fCount > 0) {
exponentDigits.fDecimalAt = exponentDigits.fCount;
digits.fDecimalAt += exponentDigits.getLong();
position = pos; // Advance past the exponent
}
break; // Whether we fail or succeed, we exit this loop
}
while (pos < textLength) {
ch = text[(int32_t)pos];
digit = ch - zero;
if (digit < 0 || digit > 9) {
digit = u_charDigitValue(ch);
}
if (0 <= digit && digit <= 9) {
++pos;
exponentDigits.append((char)(digit + '0'));
} else {
break;
}
else {
break;
}
if (exponentDigits.fCount > 0) {
exponentDigits.fDecimalAt = exponentDigits.fCount;
digits.fDecimalAt += exponentDigits.getLong();
position = pos; // Advance past the exponent
}
break; // Whether we fail or succeed, we exit this loop
}
else
break;
}
if (backup != -1)
@ -1458,10 +1467,11 @@ DecimalFormat::setCurrencyForSymbols() {
UErrorCode ec = U_ZERO_ERROR;
DecimalFormatSymbols def(fSymbols->getLocale(), ec);
if (fSymbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol) ==
def.getSymbol(DecimalFormatSymbols::kCurrencySymbol) &&
fSymbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) ==
def.getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)) {
if (getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) ==
def.getConstSymbol(DecimalFormatSymbols::kCurrencySymbol) &&
getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol) ==
def.getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)
) {
setCurrencyForLocale(fSymbols->getLocale().getName(), ec);
} else {
currency[0] = 0; // Use DFS currency info
@ -1960,29 +1970,34 @@ void DecimalFormat::expandAffix(const UnicodeString& pattern,
if (intl) {
++i;
}
UnicodeString s;
if (currency[0] != 0) {
UErrorCode ec = U_ZERO_ERROR;
int32_t len;
s = UnicodeString(intl ? currency
: ucurr_getSymbol(currency, fSymbols->getLocale().getName(), &len, &ec));
if(intl) {
affix += currency;
} else {
int32_t len;
affix += ucurr_getSymbol(currency, fSymbols->getLocale().getName(), &len, &ec);
}
} else {
s = intl ? fSymbols->getSymbol(DecimalFormatSymbols::kIntlCurrencySymbol)
: fSymbols->getSymbol(DecimalFormatSymbols::kCurrencySymbol);
if(intl) {
affix += getConstSymbol(DecimalFormatSymbols::kIntlCurrencySymbol);
} else {
affix += getConstSymbol(DecimalFormatSymbols::kCurrencySymbol);
}
}
affix += s; }
break;
}
case kPatternPercent:
affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol));
affix += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
break;
case kPatternPerMill:
affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol));
affix += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
break;
case kPatternPlus:
affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol));
affix += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
break;
case kPatternMinus:
affix.append(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol));
affix += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
break;
default:
affix.append(c);
@ -2044,16 +2059,16 @@ void DecimalFormat::appendAffix(UnicodeString& buffer,
} else if (localized) {
switch (c) {
case kPatternPercent:
buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol));
buffer += getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
break;
case kPatternPerMill:
buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol));
buffer += getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
break;
case kPatternPlus:
buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol));
buffer += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
break;
case kPatternMinus:
buffer.append(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol));
buffer += getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
break;
default:
buffer.append(c);
@ -2076,15 +2091,15 @@ DecimalFormat::appendAffix( UnicodeString& buffer,
UBool localized) const {
UBool needQuote;
if(localized) {
needQuote = affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kDigitSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol)) >= 0
|| affix.indexOf(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol)) >= 0
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 {
@ -2131,8 +2146,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
{
result.remove();
UChar32 zero;
UnicodeString digit;
UnicodeString group;
UnicodeString digit, group;
int32_t i;
int32_t roundingDecimalPos = 0; // Pos of decimal in roundingDigits
UnicodeString roundingDigits;
@ -2140,9 +2154,9 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
UnicodeString padSpec;
if (localized) {
digit = fSymbols->getSymbol(DecimalFormatSymbols::kDigitSymbol);
group = fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
zero = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
digit.append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
group.append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
zero = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
}
else {
digit.append((UChar)kPatternDigit);
@ -2151,7 +2165,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
}
if (fFormatWidth > 0) {
if (localized) {
padSpec.append(fSymbols->getSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
padSpec.append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
}
else {
padSpec.append((UChar)kPatternPadEscape);
@ -2204,7 +2218,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
}
if (getMaximumFractionDigits() > 0 || fDecimalSeparatorAlwaysShown) {
if (localized) {
result.append(fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
result += getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
}
else {
result.append((UChar)kPatternDecimalSeparator);
@ -2231,14 +2245,14 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
}
if (fUseExponentialNotation) {
if (localized) {
result.append(fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol));
result += getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
}
else {
result.append((UChar)kPatternExponent);
}
if (fExponentSignAlwaysShown) {
if (localized) {
result.append(fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol));
result += getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
}
else {
result.append((UChar)kPatternPlus);
@ -2293,7 +2307,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
{
int32_t length = fPositivePrefix.length();
isDefault = fNegativePrefix.length() == (length+1) &&
fNegativePrefix.compare(fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
fNegativePrefix.compare(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol)) == 0 &&
fNegativePrefix.compare(1, length, fPositivePrefix, 0, length) == 0;
}
}
@ -2301,7 +2315,7 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
break; // Don't output default negative subpattern
} else {
if (localized) {
result.append(fSymbols->getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
result += getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
}
else {
result.append((UChar)kPatternSeparator);
@ -2385,17 +2399,17 @@ DecimalFormat::applyPattern(const UnicodeString& pattern,
UnicodeString padEscape ((UChar)kPatternPadEscape);
// Substitute with the localized symbols if necessary
if (localized) {
zeroDigit = fSymbols->getSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
groupingSeparator = fSymbols->getSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
decimalSeparator = fSymbols->getSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
percent = fSymbols->getSymbol(DecimalFormatSymbols::kPercentSymbol);
perMill = fSymbols->getSymbol(DecimalFormatSymbols::kPerMillSymbol);
digit = fSymbols->getSymbol(DecimalFormatSymbols::kDigitSymbol);
separator = fSymbols->getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
exponent = fSymbols->getSymbol(DecimalFormatSymbols::kExponentialSymbol);
plus = fSymbols->getSymbol(DecimalFormatSymbols::kPlusSignSymbol);
minus = fSymbols->getSymbol(DecimalFormatSymbols::kMinusSignSymbol);
padEscape = fSymbols->getSymbol(DecimalFormatSymbols::kPadEscapeSymbol);
zeroDigit = getConstSymbol(DecimalFormatSymbols::kZeroDigitSymbol).char32At(0);
groupingSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol));
decimalSeparator. remove().append(getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol));
percent. remove().append(getConstSymbol(DecimalFormatSymbols::kPercentSymbol));
perMill. remove().append(getConstSymbol(DecimalFormatSymbols::kPerMillSymbol));
digit. remove().append(getConstSymbol(DecimalFormatSymbols::kDigitSymbol));
separator. remove().append(getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol));
exponent. remove().append(getConstSymbol(DecimalFormatSymbols::kExponentialSymbol));
plus. remove().append(getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol));
minus. remove().append(getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol));
padEscape. remove().append(getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol));
}
UChar nineDigit = (UChar)(zeroDigit + 9);
int32_t digitLen = digit.length();

View File

@ -495,7 +495,7 @@ DateFormatSymbols::initField(UnicodeString **field, int32_t& length, const Resou
*field = new UnicodeString[length];
if (*field) {
for(int32_t i = 0; i<length; i++) {
*(*(field)+i) = data.getStringEx(i, status);
(*(field)+i)->fastCopyFrom(data.getStringEx(i, status));
}
}
else {
@ -586,7 +586,7 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo
initField(&fMonths, fMonthsCount, resource.get(fgMonthNamesTag, status), status);
initField(&fShortMonths, fShortMonthsCount, resource.get(fgMonthAbbreviationsTag, status), status);
initField(&fAmPms, fAmPmsCount, resource.get(fgAmPmMarkersTag, status), status);
fLocalPatternChars = resource.getStringEx(fgLocalPatternCharsTag, status);
fLocalPatternChars.fastCopyFrom(resource.getStringEx(fgLocalPatternCharsTag, status));
ResourceBundle zoneArray = resource.get(fgZoneStringsTag, status);
fZoneStringsRowCount = zoneArray.getSize();
@ -608,7 +608,7 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo
}
zoneRow = zoneArray.get(i, status);
for(int32_t j = 0; j<fZoneStringsColCount; j++) {
fZoneStrings[i][j] = zoneRow.getStringEx(j, status);
fZoneStrings[i][j].fastCopyFrom(zoneRow.getStringEx(j, status));
}
}
@ -623,7 +623,7 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo
}
fWeekdays[0] = UnicodeString();
for(i = 0; i<fWeekdaysCount; i++) {
fWeekdays[i+1] = weekdaysData.getStringEx(i, status);
fWeekdays[i+1].fastCopyFrom(weekdaysData.getStringEx(i, status));
}
ResourceBundle lsweekdaysData = resource.get(fgDayAbbreviationsTag, status);
@ -636,7 +636,7 @@ DateFormatSymbols::initializeData(const Locale& locale, UErrorCode& status, UBoo
}
fShortWeekdays[0] = UnicodeString();
for(i = 0; i<fShortWeekdaysCount; i++) {
fShortWeekdays[i+1] = lsweekdaysData.getStringEx(i, status);
fShortWeekdays[i+1].fastCopyFrom(lsweekdaysData.getStringEx(i, status));
}
fWeekdaysCount = fShortWeekdaysCount = 8;
@ -687,14 +687,8 @@ int32_t DateFormatSymbols::getZoneIndex(const UnicodeString& ID) const
*/
int32_t DateFormatSymbols::_getZoneIndex(const UnicodeString& ID) const
{
// {sfb} kludge to support case-insensitive comparison
UnicodeString lcaseID(ID);
lcaseID.toLower();
for(int32_t index = 0; index < fZoneStringsRowCount; index++) {
UnicodeString lcase(fZoneStrings[index][0]);
lcase.toLower();
if (lcaseID == lcase) {
if (0 == ID.caseCompare(fZoneStrings[index][0], 0)) {
return index;
}
}

View File

@ -839,15 +839,10 @@ MessageFormat::format(const Formattable* arguments,
return result;
}
UnicodeString buffer;
int32_t lastOffset = 0;
for (int32_t i = 0; i <= fMaxOffset;++i) {
// Cleans up the temp buffer for each formattable arguments.
buffer.remove();
// Append the prefix of current format element.
fPattern.extract(lastOffset, fOffsets[i] - lastOffset, buffer);
result += buffer;
result.append(fPattern, lastOffset, fOffsets[i] - lastOffset);
lastOffset = fOffsets[i];
int32_t argumentNumber = fArgumentNumbers[i];
// Checks the scope of the argument number.
@ -861,73 +856,70 @@ MessageFormat::format(const Formattable* arguments,
continue;
}
Formattable obj = arguments[argumentNumber];
UnicodeString arg;
UBool tryRecursion = FALSE;
const Formattable *obj = arguments + argumentNumber;
Formattable::Type type = obj->getType();
// Recursively calling the format process only if the current format argument
// refers to a ChoiceFormat object.
if (fFormats[i] != NULL) {
fFormats[i]->format(obj, arg, success);
tryRecursion = (fFormats[i]->getDynamicClassID() == ChoiceFormat::getStaticClassID());
UnicodeString arg;
fFormats[i]->format(*obj, arg, success);
// Needs to reprocess the ChoiceFormat option by using the MessageFormat
// pattern application.
if (fFormats[i]->getDynamicClassID() == ChoiceFormat::getStaticClassID() &&
arg.indexOf(LEFT_CURLY_BRACE) >= 0
) {
MessageFormat temp(arg, fLocale, success);
temp.format(arguments, cnt, result, status, recursionProtection, success);
if (U_FAILURE(success)) {
return result;
}
}
else {
result += arg;
}
}
// If the obj data type if a number, use a NumberFormat instance.
else if ((obj.getType() == Formattable::kDouble) ||
(obj.getType() == Formattable::kLong)) {
// If the obj data type is a number, use a NumberFormat instance.
else if ((type == Formattable::kDouble) || (type == Formattable::kLong)) {
NumberFormat *numTemplate = NULL;
numTemplate = NumberFormat::createInstance(fLocale, success);
if (U_FAILURE(success)) {
if (numTemplate == NULL || U_FAILURE(success)) {
delete numTemplate;
return result;
}
numTemplate->format((obj.getType() == Formattable::kDouble) ? obj.getDouble() : obj.getLong(), arg);
if (type == Formattable::kDouble) {
numTemplate->format(obj->getDouble(), result);
} else {
numTemplate->format(obj->getLong(), result);
}
delete numTemplate;
if (U_FAILURE(success))
return result;
}
// If the obj data type is a Date instance, use a DateFormat instance.
else if (obj.getType() == Formattable::kDate) {
else if (type == Formattable::kDate) {
DateFormat *dateTemplate = NULL;
dateTemplate = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale);
dateTemplate->format(obj.getDate(), arg);
if (dateTemplate == NULL) {
return result;
}
dateTemplate->format(obj->getDate(), result);
delete dateTemplate;
}
else if (obj.getType() == Formattable::kString) {
obj.getString(arg);
else if (type == Formattable::kString) {
result += obj->getString();
}
else {
#ifdef LIUDEBUG
cerr << "Unknown object of type:" << obj.getType() << endl;
cerr << "Unknown object of type:" << type << endl;
#endif
success = U_ILLEGAL_ARGUMENT_ERROR;
return result;
}
// Needs to reprocess the ChoiceFormat option by using the MessageFormat
// pattern application.
if (tryRecursion && arg.indexOf(LEFT_CURLY_BRACE) >= 0) {
MessageFormat *temp = NULL;
temp = new MessageFormat(arg, fLocale, success);
/* test for NULL */
if (temp == 0) {
status = U_MEMORY_ALLOCATION_ERROR;
return result;
}
if (U_FAILURE(success))
return result;
temp->format(arguments, cnt, result, status, recursionProtection, success);
if (U_FAILURE(success)) {
delete temp;
return result;
}
delete temp;
}
else {
result += arg;
}
}
buffer.remove();
// Appends the rest of the pattern characters after the real last offset.
fPattern.extract(lastOffset, fPattern.length(), buffer);
result += buffer;
result.append(fPattern, lastOffset, 0x7fffffff);
return result;
}

View File

@ -307,8 +307,11 @@ void SimpleDateFormat::construct(EStyle timeStyle,
}
//timeDateArray[0].setString(UnicodeString(dateTimePatterns[timeStyle]));
//timeDateArray[1].setString(UnicodeString(dateTimePatterns[dateStyle]));
timeDateArray[0].setString(dateTimePatterns.getStringEx(timeStyle, status));
timeDateArray[1].setString(dateTimePatterns.getStringEx(dateStyle, status));
// use Formattable::adoptString() so that we can use fastCopyFrom()
// instead of Formattable::setString()'s unaware, safe, deep string clone
// see Jitterbug 2296
timeDateArray[0].adoptString(&(new UnicodeString)->fastCopyFrom(dateTimePatterns.getStringEx(timeStyle, status)));
timeDateArray[1].adoptString(&(new UnicodeString)->fastCopyFrom(dateTimePatterns.getStringEx(dateStyle, status)));
//MessageFormat::format(UnicodeString(dateTimePatterns[kDateTime]), timeDateArray, 2, fPattern, status);
MessageFormat::format(dateTimePatterns.getStringEx(kDateTime, status), timeDateArray, 2, fPattern, status);
@ -408,7 +411,6 @@ SimpleDateFormat::format(Calendar& cal, UnicodeString& toAppendTo, FieldPosition
UBool inQuote = FALSE;
UChar prevCh = 0;
int32_t count = 0;
UnicodeString str;
// loop through the pattern string character by character
for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) {
@ -417,7 +419,7 @@ SimpleDateFormat::format(Calendar& cal, UnicodeString& toAppendTo, FieldPosition
// Use subFormat() to format a repeated pattern character
// when a different pattern or non-pattern character is seen
if (ch != prevCh && count > 0) {
toAppendTo += subFormat(str, prevCh, count, toAppendTo.length(), pos, cal, status);
subFormat(toAppendTo, prevCh, count, pos, cal, status);
count = 0;
}
if (ch == 0x0027 /*'\''*/) {
@ -445,7 +447,7 @@ SimpleDateFormat::format(Calendar& cal, UnicodeString& toAppendTo, FieldPosition
// Format the last item in the pattern, if any
if (count > 0) {
toAppendTo += subFormat(str, prevCh, count, toAppendTo.length(), pos, cal, status);
subFormat(toAppendTo, prevCh, count, pos, cal, status);
}
// and if something failed (e.g., an invalid format character), reset our FieldPosition
@ -505,11 +507,10 @@ SimpleDateFormat::fgPatternIndexToDateFormatField[] = {
//----------------------------------------------------------------------
UnicodeString&
SimpleDateFormat::subFormat(UnicodeString& result,
void
SimpleDateFormat::subFormat(UnicodeString &toAppendTo,
UChar ch,
int32_t count,
int32_t beginOffset,
FieldPosition& pos,
Calendar& cal,
UErrorCode& status) const
@ -519,37 +520,36 @@ SimpleDateFormat::subFormat(UnicodeString& result,
UChar *patternCharPtr = u_strchr(DateFormatSymbols::getPatternUChars(), ch);
EField patternCharIndex;
int32_t maxIntCount = 10;
UnicodeString str; // Scratch
result.remove();
const int32_t maxIntCount = 10;
int32_t beginOffset = toAppendTo.length();
// if the pattern character is unrecognized, signal an error and dump out
if (patternCharPtr == NULL)
{
status = U_INVALID_FORMAT_ERROR;
return result;
}
patternCharIndex = (EField)(patternCharPtr - DateFormatSymbols::getPatternUChars());
Calendar::EDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
int32_t value = cal.get(field, status);
if (U_FAILURE(status)) return result;
if (U_FAILURE(status)) {
return;
}
switch (patternCharIndex) {
// for any "G" symbol, write out the appropriate era string
case kEraField:
result = fSymbols->fEras[value];
toAppendTo += fSymbols->fEras[value];
break;
// for "yyyy", write out the whole year; for "yy", write out the last 2 digits
case kYearField:
case kYearWOYField:
if (count >= 4)
zeroPaddingNumber(result, value, 4, maxIntCount);
zeroPaddingNumber(toAppendTo, value, 4, maxIntCount);
else
zeroPaddingNumber(result, value, 2, 2);
zeroPaddingNumber(toAppendTo, value, 2, 2);
break;
// for "MMMM", write out the whole month name, for "MMM", write out the month
@ -557,19 +557,19 @@ SimpleDateFormat::subFormat(UnicodeString& result,
// appropriate number of digits
case kMonthField:
if (count >= 4)
result = fSymbols->fMonths[value];
toAppendTo += fSymbols->fMonths[value];
else if (count == 3)
result = fSymbols->fShortMonths[value];
toAppendTo += fSymbols->fShortMonths[value];
else
zeroPaddingNumber(result, value + 1, count, maxIntCount);
zeroPaddingNumber(toAppendTo, value + 1, count, maxIntCount);
break;
// for "k" and "kk", write out the hour, adjusting midnight to appear as "24"
case kHourOfDay1Field:
if (value == 0)
zeroPaddingNumber(result, cal.getMaximum(Calendar::HOUR_OF_DAY) + 1, count, maxIntCount);
zeroPaddingNumber(toAppendTo, cal.getMaximum(Calendar::HOUR_OF_DAY) + 1, count, maxIntCount);
else
zeroPaddingNumber(result, value, count, maxIntCount);
zeroPaddingNumber(toAppendTo, value, count, maxIntCount);
break;
// for "SS" and "S", we want to truncate digits so that you still see the MOST
@ -581,29 +581,29 @@ SimpleDateFormat::subFormat(UnicodeString& result,
value = value / 10;
else if (count == 1)
value = value / 100;
zeroPaddingNumber(result, value, count, maxIntCount);
zeroPaddingNumber(toAppendTo, value, count, maxIntCount);
break;
// for "EEEE", write out the day-of-the-week name; otherwise, use the abbreviation
case kDayOfWeekField:
if (count >= 4)
result = fSymbols->fWeekdays[value];
toAppendTo += fSymbols->fWeekdays[value];
else
result = fSymbols->fShortWeekdays[value];
toAppendTo += fSymbols->fShortWeekdays[value];
break;
// for and "a" symbol, write out the whole AM/PM string
case kAmPmField:
result = fSymbols->fAmPms[value];
toAppendTo += fSymbols->fAmPms[value];
break;
// for "h" and "hh", write out the hour, adjusting noon and midnight to show up
// as "12"
case kHour1Field:
if (value == 0)
zeroPaddingNumber(result, cal.getLeastMaximum(Calendar::HOUR) + 1, count, maxIntCount);
zeroPaddingNumber(toAppendTo, cal.getLeastMaximum(Calendar::HOUR) + 1, count, maxIntCount);
else
zeroPaddingNumber(result, value, count, maxIntCount);
zeroPaddingNumber(toAppendTo, value, count, maxIntCount);
break;
// for the "z" symbols, we have to check our time zone data first. If we have a
@ -613,37 +613,34 @@ SimpleDateFormat::subFormat(UnicodeString& result,
// then the time zone shows up as "GMT+hh:mm" or "GMT-hh:mm" (where "hh:mm" is the
// offset from GMT) regardless of how many z's were in the pattern symbol
case kTimezoneField: {
UnicodeString str;
int32_t zoneIndex = fSymbols->getZoneIndex(cal.getTimeZone().getID(str));
if (zoneIndex == -1) {
UnicodeString zoneString;
value = cal.get(Calendar::ZONE_OFFSET, status) +
cal.get(Calendar::DST_OFFSET, status);
if (value < 0) {
zoneString += fgGmtMinus;
toAppendTo += fgGmtMinus;
value = -value; // suppress the '-' sign for text display.
}
else
zoneString += fgGmtPlus;
toAppendTo += fgGmtPlus;
zoneString += zeroPaddingNumber(str, (int32_t)(value/U_MILLIS_PER_HOUR), 2, 2);
zoneString += (UChar)0x003A /*':'*/;
zoneString += zeroPaddingNumber(str, (int32_t)((value%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE), 2, 2);
result = zoneString;
zeroPaddingNumber(toAppendTo, (int32_t)(value/U_MILLIS_PER_HOUR), 2, 2);
toAppendTo += (UChar)0x003A /*':'*/;
zeroPaddingNumber(toAppendTo, (int32_t)((value%U_MILLIS_PER_HOUR)/U_MILLIS_PER_MINUTE), 2, 2);
}
else if (cal.get(Calendar::DST_OFFSET, status) != 0) {
if (count >= 4)
result = fSymbols->fZoneStrings[zoneIndex][3];
toAppendTo += fSymbols->fZoneStrings[zoneIndex][3];
else
result = fSymbols->fZoneStrings[zoneIndex][4];
toAppendTo += fSymbols->fZoneStrings[zoneIndex][4];
}
else {
if (count >= 4)
result = fSymbols->fZoneStrings[zoneIndex][1];
toAppendTo += fSymbols->fZoneStrings[zoneIndex][1];
else
result = fSymbols->fZoneStrings[zoneIndex][2];
toAppendTo += fSymbols->fZoneStrings[zoneIndex][2];
}
}
break;
@ -661,7 +658,7 @@ SimpleDateFormat::subFormat(UnicodeString& result,
// case kWeekOfMonthField:
// case kHour0Field:
// case kDOWLocalField:
zeroPaddingNumber(result, value, count, maxIntCount);
zeroPaddingNumber(toAppendTo, value, count, maxIntCount);
break;
}
@ -670,24 +667,21 @@ SimpleDateFormat::subFormat(UnicodeString& result,
if (pos.getField() == fgPatternIndexToDateFormatField[patternCharIndex]) {
if (pos.getBeginIndex() == 0 && pos.getEndIndex() == 0) {
pos.setBeginIndex(beginOffset);
pos.setEndIndex(beginOffset + result.length());
pos.setEndIndex(toAppendTo.length());
}
}
return result;
}
//----------------------------------------------------------------------
UnicodeString&
SimpleDateFormat::zeroPaddingNumber(UnicodeString& result, int32_t value, int32_t minDigits, int32_t maxDigits) const
void
SimpleDateFormat::zeroPaddingNumber(UnicodeString &toAppendTo, int32_t value, int32_t minDigits, int32_t maxDigits) const
{
FieldPosition pos(0);
result.remove();
fNumberFormat->setMinimumIntegerDigits(minDigits);
fNumberFormat->setMaximumIntegerDigits(maxDigits);
return fNumberFormat->format(value, result, pos); // 3rd arg is there to speed up processing
fNumberFormat->format(value, toAppendTo, pos); // 3rd arg is there to speed up processing
}
//----------------------------------------------------------------------
@ -1001,8 +995,10 @@ int32_t SimpleDateFormat::matchString(const UnicodeString& text,
int32_t bestMatchLength = 0, bestMatch = -1;
// {sfb} kludge to support case-insensitive comparison
UnicodeString lcaseText(text);
lcaseText.toLower();
// {markus 2002oct11} do not just use caseCompareBetween because we do not know
// the length of the match after case folding
UnicodeString lcaseText;
lcaseText.fastCopyFrom(text).foldCase();
for (; i < count; ++i)
{
@ -1010,8 +1006,8 @@ int32_t SimpleDateFormat::matchString(const UnicodeString& text,
// Always compare if we have no match yet; otherwise only compare
// against potentially better matches (longer strings).
UnicodeString lcase(data[i]);
lcase.toLower();
UnicodeString lcase;
lcase.fastCopyFrom(data[i]).foldCase();
if (length > bestMatchLength && (lcaseText.compareBetween(start, start + length, lcase, 0, length)) == 0)
{

View File

@ -244,8 +244,46 @@ private:
void setCurrencyForSymbols();
/**
* More efficient version of getSymbol, returning a const reference to one of the symbol strings.
* The returned reference becomes invalid when the symbol is changed
* or when the DecimalFormatSymbols are destroyed.
*
* @param symbol Constant to indicate a number format symbol.
* @return the format symbol by the param 'symbol'
* @internal
*/
inline const UnicodeString &getConstSymbol(ENumberFormatSymbol symbol) const;
/**
* Just for getConstSymbol().
* ### TODO markus 2002oct11: Consider proposing getConstSymbol() to be public instead.
*/
friend class DecimalFormat;
/**
* Private symbol strings.
* They are either loaded from a resource bundle or otherwise owned.
* setSymbol() clones the symbol string.
* Readonly aliases can only come from a resource bundle, so that we can always
* use fastCopyFrom() with them.
*
* If DecimalFormatSymbols becomes subclassable and the status of fSymbols changes
* from private to protected,
* or when fSymbols can be set any other way that allows them to be readonly aliases
* to non-resource bundle strings,
* then regular UnicodeString copies must be used instead of fastCopyFrom().
*
* @internal
*/
UnicodeString fSymbols[kFormatSymbolCount];
/**
* Non-symbol variable for getConstSymbol(). Always empty.
* @internal
*/
UnicodeString fNoSymbol;
Locale locale;
static const char fgNumberElements[];
@ -270,6 +308,15 @@ DecimalFormatSymbols::getSymbol(ENumberFormatSymbol symbol) const {
}
}
inline const UnicodeString &
DecimalFormatSymbols::getConstSymbol(ENumberFormatSymbol symbol) const {
if(symbol<kFormatSymbolCount) {
return fSymbols[symbol];
} else {
return fNoSymbol;
}
}
// -------------------------------------
/* TODO: This should use "const UnicodeString &value" */

View File

@ -28,12 +28,12 @@
#if !UCONFIG_NO_FORMATTING
#include "unicode/dcfmtsym.h"
#include "unicode/numfmt.h"
#include "unicode/locid.h"
U_NAMESPACE_BEGIN
class DecimalFormatSymbols;
class DigitList;
/**
@ -1173,6 +1173,13 @@ private:
UBool subparse(const UnicodeString& text, ParsePosition& parsePosition,
DigitList& digits, UBool* status) const;
/**
* Get a decimal format symbol.
* Returns a const reference to the symbol string.
* @internal
*/
inline const UnicodeString &getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const;
/**
* Append an affix to the given StringBuffer, using quotes if
* there are special characters. Single quotes themselves must be
@ -1295,6 +1302,10 @@ DecimalFormat::format(int32_t number,
return format(number, output, pos);
}
inline const UnicodeString &
DecimalFormat::getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
return fSymbols->getConstSymbol(symbol);
}
U_NAMESPACE_END

View File

@ -605,41 +605,37 @@ private:
/**
* Called by format() to format a single field.
*
* @param result Filled in with the result.
* @param toAppendTo A string which gets the result appended to it.
* @param ch The format character we encountered in the pattern.
* @param count Number of characters in the current pattern symbol (e.g.,
* "yyyy" in the pattern would result in a call to this function
* with ch equal to 'y' and count equal to 4)
* @param beginOffset Tells where the text returned by this function will go in
* the finished string. Used when this function needs to fill
* in a FieldPosition
* @param pos The FieldPosition being filled in by the format() call. If
* this function is formatting the field specfied by pos, it
* will fill in pos will the beginning and ending offsets of the
* will fill in pos with the beginning and ending offsets of the
* field.
* @param status Receives a status code, which will be U_ZERO_ERROR if the operation
* succeeds.
* @return A reference to "result".
*/
UnicodeString& subFormat( UnicodeString& result,
void subFormat( UnicodeString &toAppendTo,
UChar ch,
int32_t count,
int32_t beginOffset,
FieldPosition& pos,
Calendar& cal,
UErrorCode& status) const; // in case of illegal argument
/**
* Used by subFormat() to format a numeric value. Fills in "result" with a string
* representation of "value" having a number of digits between "minDigits" and
* Used by subFormat() to format a numeric value.
* Appends to toAppendTo a string representation of "value"
* having a number of digits between "minDigits" and
* "maxDigits". Uses the DateFormat's NumberFormat.
* @param result Filled in with the formatted number.
*
* @param toAppendTo A string which gets the formatted number appended to it.
* @param value Value to format.
* @param minDigits Minimum number of digits the result should have
* @param maxDigits Maximum number of digits the result should have
* @return A reference to "result".
*/
UnicodeString& zeroPaddingNumber(UnicodeString& result,
void zeroPaddingNumber( UnicodeString &toAppendTo,
int32_t value,
int32_t minDigits,
int32_t maxDigits) const;