ICU-2296 optimize use of UnicodeString, copy string objects less often
X-SVN-Rev: 10029
This commit is contained in:
parent
b6de7e771f
commit
d8cd28cf02
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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" */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user