ICU-13177 Improving consistency of Unicode string literals in number formatting code.
X-SVN-Rev: 40583
This commit is contained in:
parent
dbc623d0d8
commit
dbf0bfe4a7
@ -308,6 +308,14 @@ public:
|
||||
* Default constructor initializes with internal T[stackCapacity] buffer.
|
||||
*/
|
||||
MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {}
|
||||
/**
|
||||
* Automatically allocates the heap array if the argument is larger than the stack capacity.
|
||||
* Intended for use when an approximate capacity is known at compile time but the true
|
||||
* capacity is not known until runtime.
|
||||
*/
|
||||
MaybeStackArray(int32_t newCapacity) : MaybeStackArray() {
|
||||
if (capacity < newCapacity) { resize(newCapacity); }
|
||||
};
|
||||
/**
|
||||
* Destructor deletes the array (if owned).
|
||||
*/
|
||||
|
@ -20,7 +20,7 @@ int32_t AffixUtils::estimateLength(const CharSequence &patternString, UErrorCode
|
||||
|
||||
switch (state) {
|
||||
case STATE_BASE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
// First quote
|
||||
state = STATE_FIRST_QUOTE;
|
||||
} else {
|
||||
@ -29,7 +29,7 @@ int32_t AffixUtils::estimateLength(const CharSequence &patternString, UErrorCode
|
||||
}
|
||||
break;
|
||||
case STATE_FIRST_QUOTE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
// Repeated quote
|
||||
length++;
|
||||
state = STATE_BASE;
|
||||
@ -40,7 +40,7 @@ int32_t AffixUtils::estimateLength(const CharSequence &patternString, UErrorCode
|
||||
}
|
||||
break;
|
||||
case STATE_INSIDE_QUOTE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
// End of quoted sequence
|
||||
state = STATE_AFTER_QUOTE;
|
||||
} else {
|
||||
@ -49,7 +49,7 @@ int32_t AffixUtils::estimateLength(const CharSequence &patternString, UErrorCode
|
||||
}
|
||||
break;
|
||||
case STATE_AFTER_QUOTE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
// Double quote inside of quoted sequence
|
||||
length++;
|
||||
state = STATE_INSIDE_QUOTE;
|
||||
@ -81,20 +81,20 @@ UnicodeString AffixUtils::escape(const CharSequence &input) {
|
||||
int32_t offset = 0;
|
||||
UnicodeString output;
|
||||
for (; offset < input.length();) {
|
||||
int32_t cp = input.codePointAt(offset);
|
||||
UChar32 cp = input.codePointAt(offset);
|
||||
|
||||
switch (cp) {
|
||||
case '\'':
|
||||
case u'\'':
|
||||
output.append(u"''", -1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case '+':
|
||||
case '%':
|
||||
case u'-':
|
||||
case u'+':
|
||||
case u'%':
|
||||
case u'‰':
|
||||
case u'¤':
|
||||
if (state == STATE_BASE) {
|
||||
output.append('\'');
|
||||
output.append(u'\'');
|
||||
output.append(cp);
|
||||
state = STATE_INSIDE_QUOTE;
|
||||
} else {
|
||||
@ -104,7 +104,7 @@ UnicodeString AffixUtils::escape(const CharSequence &input) {
|
||||
|
||||
default:
|
||||
if (state == STATE_INSIDE_QUOTE) {
|
||||
output.append('\'');
|
||||
output.append(u'\'');
|
||||
output.append(cp);
|
||||
state = STATE_BASE;
|
||||
} else {
|
||||
@ -116,7 +116,7 @@ UnicodeString AffixUtils::escape(const CharSequence &input) {
|
||||
}
|
||||
|
||||
if (state == STATE_INSIDE_QUOTE) {
|
||||
output.append('\'');
|
||||
output.append(u'\'');
|
||||
}
|
||||
|
||||
return output;
|
||||
@ -247,14 +247,14 @@ AffixTag AffixUtils::nextToken(AffixTag tag, const CharSequence &patternString,
|
||||
switch (state) {
|
||||
case STATE_BASE:
|
||||
switch (cp) {
|
||||
case '\'':
|
||||
case u'\'':
|
||||
state = STATE_FIRST_QUOTE;
|
||||
offset += count;
|
||||
// continue to the next code point
|
||||
break;
|
||||
case '-':
|
||||
case u'-':
|
||||
return makeTag(offset + count, TYPE_MINUS_SIGN, STATE_BASE, 0);
|
||||
case '+':
|
||||
case u'+':
|
||||
return makeTag(offset + count, TYPE_PLUS_SIGN, STATE_BASE, 0);
|
||||
case u'%':
|
||||
return makeTag(offset + count, TYPE_PERCENT, STATE_BASE, 0);
|
||||
@ -270,13 +270,13 @@ AffixTag AffixUtils::nextToken(AffixTag tag, const CharSequence &patternString,
|
||||
}
|
||||
break;
|
||||
case STATE_FIRST_QUOTE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
return makeTag(offset + count, TYPE_CODEPOINT, STATE_BASE, cp);
|
||||
} else {
|
||||
return makeTag(offset + count, TYPE_CODEPOINT, STATE_INSIDE_QUOTE, cp);
|
||||
}
|
||||
case STATE_INSIDE_QUOTE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
state = STATE_AFTER_QUOTE;
|
||||
offset += count;
|
||||
// continue to the next code point
|
||||
@ -285,7 +285,7 @@ AffixTag AffixUtils::nextToken(AffixTag tag, const CharSequence &patternString,
|
||||
return makeTag(offset + count, TYPE_CODEPOINT, STATE_INSIDE_QUOTE, cp);
|
||||
}
|
||||
case STATE_AFTER_QUOTE:
|
||||
if (cp == '\'') {
|
||||
if (cp == u'\'') {
|
||||
return makeTag(offset + count, TYPE_CODEPOINT, STATE_INSIDE_QUOTE, cp);
|
||||
} else {
|
||||
state = STATE_BASE;
|
||||
@ -390,7 +390,7 @@ bool AffixUtils::hasNext(const AffixTag &tag, const CharSequence &string) {
|
||||
// The rest of the fields are safe to use now.
|
||||
// Special case: the last character in string is an end quote.
|
||||
if (tag.state == STATE_INSIDE_QUOTE && tag.offset == string.length() - 1 &&
|
||||
string.charAt(tag.offset) == '\'') {
|
||||
string.charAt(tag.offset) == u'\'') {
|
||||
return false;
|
||||
} else if (tag.state != STATE_BASE) {
|
||||
return true;
|
||||
|
@ -687,11 +687,11 @@ void DecimalQuantity::appendDigit(int8_t value, int32_t leadingZeros, bool appen
|
||||
UnicodeString DecimalQuantity::toPlainString() const {
|
||||
UnicodeString sb;
|
||||
if (isNegative()) {
|
||||
sb.append('-');
|
||||
sb.append(u'-');
|
||||
}
|
||||
for (int m = getUpperDisplayMagnitude(); m >= getLowerDisplayMagnitude(); m--) {
|
||||
sb.append(getDigit(m) + '0');
|
||||
if (m == 0) { sb.append('.'); }
|
||||
sb.append(getDigit(m) + u'0');
|
||||
if (m == 0) { sb.append(u'.'); }
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
@ -975,46 +975,34 @@ const char16_t* DecimalQuantity::checkHealth() const {
|
||||
}
|
||||
|
||||
UnicodeString DecimalQuantity::toString() const {
|
||||
auto digits = new char[precision + 1];
|
||||
MaybeStackArray<char, 30> digits(precision + 1);
|
||||
for (int32_t i = 0; i < precision; i++) {
|
||||
digits[i] = getDigitPos(precision - i - 1) + '0';
|
||||
}
|
||||
digits[precision] = 0;
|
||||
digits[precision] = 0; // terminate buffer
|
||||
char buffer8[100];
|
||||
snprintf(
|
||||
buffer8,
|
||||
100,
|
||||
sizeof(buffer8),
|
||||
"<DecimalQuantity %d:%d:%d:%d %s %s%s%d>",
|
||||
(lOptPos > 999 ? 999 : lOptPos),
|
||||
lReqPos,
|
||||
rReqPos,
|
||||
(rOptPos < -999 ? -999 : rOptPos),
|
||||
(usingBytes ? "bytes" : "long"),
|
||||
(precision == 0 ? "0" : digits),
|
||||
(precision == 0 ? "0" : digits.getAlias()),
|
||||
"E",
|
||||
scale);
|
||||
delete[] digits;
|
||||
|
||||
// Convert from char to char16_t to avoid codepage conversion
|
||||
char16_t buffer16[100];
|
||||
for (int32_t i = 0; i < 100; i++) {
|
||||
buffer16[i] = static_cast<char16_t>(buffer8[i]);
|
||||
}
|
||||
return UnicodeString(buffer16);
|
||||
return UnicodeString(buffer8, -1, US_INV);
|
||||
}
|
||||
|
||||
UnicodeString DecimalQuantity::toNumberString() const {
|
||||
auto digits = new char[precision + 11];
|
||||
MaybeStackArray<char, 30> digits(precision + 11);
|
||||
for (int32_t i = 0; i < precision; i++) {
|
||||
digits[i] = getDigitPos(precision - i - 1) + '0';
|
||||
}
|
||||
auto digits16 = new char16_t[precision + 11];
|
||||
snprintf(digits + precision, 11, "E%d", scale);
|
||||
u_charsToUChars(digits, digits16, precision + 11);
|
||||
UnicodeString ret(digits16);
|
||||
delete[] digits;
|
||||
delete[] digits16;
|
||||
return ret;
|
||||
snprintf(digits.getAlias() + precision, 11, "E%d", scale);
|
||||
return UnicodeString(digits.getAlias(), -1, US_INV);
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
@ -326,16 +326,16 @@ char16_t MutablePatternModifier::charAt(int32_t index) const {
|
||||
U_ASSERT(inCharSequenceMode);
|
||||
char16_t candidate;
|
||||
if (prependSign && index == 0) {
|
||||
candidate = '-';
|
||||
candidate = u'-';
|
||||
} else if (prependSign) {
|
||||
candidate = patternInfo->charAt(fFlags, index - 1);
|
||||
} else {
|
||||
candidate = patternInfo->charAt(fFlags, index);
|
||||
}
|
||||
if (plusReplacesMinusSign && candidate == '-') {
|
||||
return '+';
|
||||
if (plusReplacesMinusSign && candidate == u'-') {
|
||||
return u'+';
|
||||
}
|
||||
if (perMilleReplacesPercent && candidate == '%') {
|
||||
if (perMilleReplacesPercent && candidate == u'%') {
|
||||
return u'‰';
|
||||
}
|
||||
return candidate;
|
||||
|
@ -120,7 +120,7 @@ void ParsedPatternInfo::consumePattern(const UnicodeString& patternString, UErro
|
||||
currentSubpattern = &positive;
|
||||
consumeSubpattern(status);
|
||||
if (U_FAILURE(status)) { return; }
|
||||
if (state.peek() == ';') {
|
||||
if (state.peek() == u';') {
|
||||
state.next(); // consume the ';'
|
||||
// Don't consume the negative subpattern if it is empty (trailing ';')
|
||||
if (state.peek() != -1) {
|
||||
@ -157,7 +157,7 @@ void ParsedPatternInfo::consumeSubpattern(UErrorCode &status) {
|
||||
}
|
||||
|
||||
void ParsedPatternInfo::consumePadding(PadPosition paddingLocation, UErrorCode &status) {
|
||||
if (state.peek() != '*') {
|
||||
if (state.peek() != u'*') {
|
||||
return;
|
||||
}
|
||||
if (!currentSubpattern->paddingLocation.isNull()) {
|
||||
@ -177,28 +177,28 @@ void ParsedPatternInfo::consumeAffix(Endpoints &endpoints, UErrorCode &status) {
|
||||
endpoints.start = state.offset;
|
||||
while (true) {
|
||||
switch (state.peek()) {
|
||||
case '#':
|
||||
case '@':
|
||||
case ';':
|
||||
case '*':
|
||||
case '.':
|
||||
case ',':
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case u'#':
|
||||
case u'@':
|
||||
case u';':
|
||||
case u'*':
|
||||
case u'.':
|
||||
case u',':
|
||||
case u'0':
|
||||
case u'1':
|
||||
case u'2':
|
||||
case u'3':
|
||||
case u'4':
|
||||
case u'5':
|
||||
case u'6':
|
||||
case u'7':
|
||||
case u'8':
|
||||
case u'9':
|
||||
case -1:
|
||||
// Characters that cannot appear unquoted in a literal
|
||||
// break outer;
|
||||
goto after_outer;
|
||||
|
||||
case '%':
|
||||
case u'%':
|
||||
currentSubpattern->hasPercentSign = true;
|
||||
break;
|
||||
|
||||
@ -210,11 +210,11 @@ void ParsedPatternInfo::consumeAffix(Endpoints &endpoints, UErrorCode &status) {
|
||||
currentSubpattern->hasCurrencySign = true;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case u'-':
|
||||
currentSubpattern->hasMinusSign = true;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
case u'+':
|
||||
currentSubpattern->hasPlusSign = true;
|
||||
break;
|
||||
|
||||
@ -233,9 +233,9 @@ void ParsedPatternInfo::consumeLiteral(UErrorCode &status) {
|
||||
state.toParseException(u"Expected unquoted literal but found EOL");
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
return;
|
||||
} else if (state.peek() == '\'') {
|
||||
} else if (state.peek() == u'\'') {
|
||||
state.next(); // consume the starting quote
|
||||
while (state.peek() != '\'') {
|
||||
while (state.peek() != u'\'') {
|
||||
if (state.peek() == -1) {
|
||||
state.toParseException(u"Expected quoted literal but found EOL");
|
||||
status = U_PATTERN_SYNTAX_ERROR;
|
||||
@ -254,7 +254,7 @@ void ParsedPatternInfo::consumeLiteral(UErrorCode &status) {
|
||||
void ParsedPatternInfo::consumeFormat(UErrorCode &status) {
|
||||
consumeIntegerFormat(status);
|
||||
if (U_FAILURE(status)) { return; }
|
||||
if (state.peek() == '.') {
|
||||
if (state.peek() == u'.') {
|
||||
state.next(); // consume the decimal point
|
||||
currentSubpattern->hasDecimal = true;
|
||||
currentSubpattern->widthExceptAffixes += 1;
|
||||
@ -269,12 +269,12 @@ void ParsedPatternInfo::consumeIntegerFormat(UErrorCode &status) {
|
||||
|
||||
while (true) {
|
||||
switch (state.peek()) {
|
||||
case ',':
|
||||
case u',':
|
||||
result.widthExceptAffixes += 1;
|
||||
result.groupingSizes <<= 16;
|
||||
break;
|
||||
|
||||
case '#':
|
||||
case u'#':
|
||||
if (result.integerNumerals > 0) {
|
||||
state.toParseException(u"# cannot follow 0 before decimal point");
|
||||
status = U_UNEXPECTED_TOKEN;
|
||||
@ -290,7 +290,7 @@ void ParsedPatternInfo::consumeIntegerFormat(UErrorCode &status) {
|
||||
result.integerTotal += 1;
|
||||
break;
|
||||
|
||||
case '@':
|
||||
case u'@':
|
||||
if (result.integerNumerals > 0) {
|
||||
state.toParseException(u"Cannot mix 0 and @");
|
||||
status = U_UNEXPECTED_TOKEN;
|
||||
@ -307,16 +307,16 @@ void ParsedPatternInfo::consumeIntegerFormat(UErrorCode &status) {
|
||||
result.integerTotal += 1;
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case u'0':
|
||||
case u'1':
|
||||
case u'2':
|
||||
case u'3':
|
||||
case u'4':
|
||||
case u'5':
|
||||
case u'6':
|
||||
case u'7':
|
||||
case u'8':
|
||||
case u'9':
|
||||
if (result.integerAtSigns > 0) {
|
||||
state.toParseException(u"Cannot mix @ and 0");
|
||||
status = U_UNEXPECTED_TOKEN;
|
||||
@ -326,8 +326,8 @@ void ParsedPatternInfo::consumeIntegerFormat(UErrorCode &status) {
|
||||
result.groupingSizes += 1;
|
||||
result.integerNumerals += 1;
|
||||
result.integerTotal += 1;
|
||||
if (!result.rounding.isZero() || state.peek() != '0') {
|
||||
result.rounding.appendDigit(static_cast<int8_t>(state.peek() - '0'), 0, true);
|
||||
if (!result.rounding.isZero() || state.peek() != u'0') {
|
||||
result.rounding.appendDigit(static_cast<int8_t>(state.peek() - u'0'), 0, true);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -361,23 +361,23 @@ void ParsedPatternInfo::consumeFractionFormat(UErrorCode &status) {
|
||||
int32_t zeroCounter = 0;
|
||||
while (true) {
|
||||
switch (state.peek()) {
|
||||
case '#':
|
||||
case u'#':
|
||||
result.widthExceptAffixes += 1;
|
||||
result.fractionHashSigns += 1;
|
||||
result.fractionTotal += 1;
|
||||
zeroCounter++;
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case u'0':
|
||||
case u'1':
|
||||
case u'2':
|
||||
case u'3':
|
||||
case u'4':
|
||||
case u'5':
|
||||
case u'6':
|
||||
case u'7':
|
||||
case u'8':
|
||||
case u'9':
|
||||
if (result.fractionHashSigns > 0) {
|
||||
state.toParseException(u"0 cannot follow # after decimal point");
|
||||
status = U_UNEXPECTED_TOKEN;
|
||||
@ -386,11 +386,11 @@ void ParsedPatternInfo::consumeFractionFormat(UErrorCode &status) {
|
||||
result.widthExceptAffixes += 1;
|
||||
result.fractionNumerals += 1;
|
||||
result.fractionTotal += 1;
|
||||
if (state.peek() == '0') {
|
||||
if (state.peek() == u'0') {
|
||||
zeroCounter++;
|
||||
} else {
|
||||
result.rounding
|
||||
.appendDigit(static_cast<int8_t>(state.peek() - '0'), zeroCounter, false);
|
||||
.appendDigit(static_cast<int8_t>(state.peek() - u'0'), zeroCounter, false);
|
||||
zeroCounter = 0;
|
||||
}
|
||||
break;
|
||||
@ -406,7 +406,7 @@ void ParsedPatternInfo::consumeExponent(UErrorCode &status) {
|
||||
// Convenience reference:
|
||||
ParsedSubpatternInfo &result = *currentSubpattern;
|
||||
|
||||
if (state.peek() != 'E') {
|
||||
if (state.peek() != u'E') {
|
||||
return;
|
||||
}
|
||||
if ((result.groupingSizes & 0xffff0000L) != 0xffff0000L) {
|
||||
@ -416,12 +416,12 @@ void ParsedPatternInfo::consumeExponent(UErrorCode &status) {
|
||||
}
|
||||
state.next(); // consume the E
|
||||
result.widthExceptAffixes++;
|
||||
if (state.peek() == '+') {
|
||||
if (state.peek() == u'+') {
|
||||
state.next(); // consume the +
|
||||
result.exponentHasPlusSign = true;
|
||||
result.widthExceptAffixes++;
|
||||
}
|
||||
while (state.peek() == '0') {
|
||||
while (state.peek() == u'0') {
|
||||
state.next(); // consume the 0
|
||||
result.exponentZeros += 1;
|
||||
result.widthExceptAffixes++;
|
||||
@ -573,7 +573,7 @@ void PatternParser::patternInfoToProperties(DecimalFormatProperties &properties,
|
||||
if (rawPaddingString.length() == 1) {
|
||||
properties.padString = rawPaddingString;
|
||||
} else if (rawPaddingString.length() == 2) {
|
||||
if (rawPaddingString.charAt(0) == '\'') {
|
||||
if (rawPaddingString.charAt(0) == u'\'') {
|
||||
properties.padString.setTo(u"'", -1);
|
||||
} else {
|
||||
properties.padString = rawPaddingString;
|
||||
@ -683,10 +683,10 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
|
||||
if (maxSig != uprv_min(dosMax, -1)) {
|
||||
// Significant Digits.
|
||||
while (digitsString.length() < minSig) {
|
||||
digitsString.append('@');
|
||||
digitsString.append(u'@');
|
||||
}
|
||||
while (digitsString.length() < maxSig) {
|
||||
digitsString.append('#');
|
||||
digitsString.append(u'#');
|
||||
}
|
||||
} else if (roundingInterval != 0.0) {
|
||||
// Rounding Interval.
|
||||
@ -697,7 +697,7 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
|
||||
incrementQuantity.adjustMagnitude(minFrac);
|
||||
incrementQuantity.roundToMagnitude(0, kDefaultMode, status);
|
||||
UnicodeString str = incrementQuantity.toPlainString();
|
||||
if (str.charAt(0) == '-') {
|
||||
if (str.charAt(0) == u'-') {
|
||||
// TODO: Unsupported operation exception or fail silently?
|
||||
digitsString.append(str, 1, str.length() - 1);
|
||||
} else {
|
||||
@ -705,10 +705,10 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
|
||||
}
|
||||
}
|
||||
while (digitsString.length() + digitsStringScale < minInt) {
|
||||
digitsString.insert(0, '0');
|
||||
digitsString.insert(0, u'0');
|
||||
}
|
||||
while (-digitsStringScale < minFrac) {
|
||||
digitsString.append('0');
|
||||
digitsString.append(u'0');
|
||||
digitsStringScale--;
|
||||
}
|
||||
|
||||
@ -719,27 +719,27 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
|
||||
for (int magnitude = m0; magnitude >= mN; magnitude--) {
|
||||
int di = digitsString.length() + digitsStringScale - magnitude - 1;
|
||||
if (di < 0 || di >= digitsString.length()) {
|
||||
sb.append('#');
|
||||
sb.append(u'#');
|
||||
} else {
|
||||
sb.append(digitsString.charAt(di));
|
||||
}
|
||||
if (magnitude > grouping2 && grouping > 0 && (magnitude - grouping2) % grouping == 0) {
|
||||
sb.append(',');
|
||||
sb.append(u',');
|
||||
} else if (magnitude > 0 && magnitude == grouping2) {
|
||||
sb.append(',');
|
||||
sb.append(u',');
|
||||
} else if (magnitude == 0 && (alwaysShowDecimal || mN < 0)) {
|
||||
sb.append('.');
|
||||
sb.append(u'.');
|
||||
}
|
||||
}
|
||||
|
||||
// Exponential notation
|
||||
if (exponentDigits != uprv_min(dosMax, -1)) {
|
||||
sb.append('E');
|
||||
sb.append(u'E');
|
||||
if (exponentShowPlusSign) {
|
||||
sb.append('+');
|
||||
sb.append(u'+');
|
||||
}
|
||||
for (int i = 0; i < exponentDigits; i++) {
|
||||
sb.append('0');
|
||||
sb.append(u'0');
|
||||
}
|
||||
}
|
||||
|
||||
@ -753,29 +753,29 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
|
||||
// Resolve Padding
|
||||
if (paddingWidth != -1 && !paddingLocation.isNull()) {
|
||||
while (paddingWidth - sb.length() > 0) {
|
||||
sb.insert(afterPrefixPos, '#');
|
||||
sb.insert(afterPrefixPos, u'#');
|
||||
beforeSuffixPos++;
|
||||
}
|
||||
int addedLength;
|
||||
switch (paddingLocation.get(status)) {
|
||||
case PadPosition::UNUM_PAD_BEFORE_PREFIX:
|
||||
addedLength = escapePaddingString(paddingString, sb, 0, status);
|
||||
sb.insert(0, '*');
|
||||
sb.insert(0, u'*');
|
||||
afterPrefixPos += addedLength + 1;
|
||||
beforeSuffixPos += addedLength + 1;
|
||||
break;
|
||||
case PadPosition::UNUM_PAD_AFTER_PREFIX:
|
||||
addedLength = escapePaddingString(paddingString, sb, afterPrefixPos, status);
|
||||
sb.insert(afterPrefixPos, '*');
|
||||
sb.insert(afterPrefixPos, u'*');
|
||||
afterPrefixPos += addedLength + 1;
|
||||
beforeSuffixPos += addedLength + 1;
|
||||
break;
|
||||
case PadPosition::UNUM_PAD_BEFORE_SUFFIX:
|
||||
escapePaddingString(paddingString, sb, beforeSuffixPos, status);
|
||||
sb.insert(beforeSuffixPos, '*');
|
||||
sb.insert(beforeSuffixPos, u'*');
|
||||
break;
|
||||
case PadPosition::UNUM_PAD_AFTER_SUFFIX:
|
||||
sb.append('*');
|
||||
sb.append(u'*');
|
||||
escapePaddingString(paddingString, sb, sb.length(), status);
|
||||
break;
|
||||
}
|
||||
@ -785,8 +785,8 @@ UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatP
|
||||
// Negative affixes
|
||||
// Ignore if the negative prefix pattern is "-" and the negative suffix is empty
|
||||
if (!np.isBogus() || !ns.isBogus() || (npp.isBogus() && !nsp.isBogus()) ||
|
||||
(!npp.isBogus() && (npp.length() != 1 || npp.charAt(0) != '-' || nsp.length() != 0))) {
|
||||
sb.append(';');
|
||||
(!npp.isBogus() && (npp.length() != 1 || npp.charAt(0) != u'-' || nsp.length() != 0))) {
|
||||
sb.append(u';');
|
||||
if (!npp.isBogus()) {
|
||||
sb.append(npp);
|
||||
}
|
||||
@ -817,12 +817,12 @@ int PatternStringUtils::escapePaddingString(UnicodeString input, UnicodeString&
|
||||
output.insert(startIndex, input);
|
||||
}
|
||||
} else {
|
||||
output.insert(startIndex, '\'');
|
||||
output.insert(startIndex, u'\'');
|
||||
int offset = 1;
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
// it's okay to deal in chars here because the quote mark is the only interesting thing.
|
||||
char16_t ch = input.charAt(i);
|
||||
if (ch == '\'') {
|
||||
if (ch == u'\'') {
|
||||
output.insert(startIndex + offset, u"''", -1);
|
||||
offset += 2;
|
||||
} else {
|
||||
@ -830,7 +830,7 @@ int PatternStringUtils::escapePaddingString(UnicodeString input, UnicodeString&
|
||||
offset += 1;
|
||||
}
|
||||
}
|
||||
output.insert(startIndex + offset, '\'');
|
||||
output.insert(startIndex + offset, u'\'');
|
||||
}
|
||||
return output.length() - startLength;
|
||||
}
|
||||
|
@ -75,25 +75,25 @@ void DecimalQuantityTest::testDecimalQuantityBehaviorStandalone() {
|
||||
DecimalQuantity fq;
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 999:0:0:-999 long 0E0>");
|
||||
fq.setToInt(51423);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 51423E0>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 999:0:0:-999 long 51423E0>");
|
||||
fq.adjustMagnitude(-3);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 51423E-3>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 999:0:0:-999 long 51423E-3>");
|
||||
fq.setToLong(999999999999000L);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 999:0:0:-999 long 999999999999E3>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 999:0:0:-999 long 999999999999E3>");
|
||||
fq.setIntegerLength(2, 5);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 5:2:0:-999 long 999999999999E3>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 5:2:0:-999 long 999999999999E3>");
|
||||
fq.setFractionLength(3, 6);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 999999999999E3>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 5:2:-3:-6 long 999999999999E3>");
|
||||
fq.setToDouble(987.654321);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 987654321E-6>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 5:2:-3:-6 long 987654321E-6>");
|
||||
fq.roundToInfinity();
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 987654321E-6>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 5:2:-3:-6 long 987654321E-6>");
|
||||
fq.roundToIncrement(0.005, RoundingMode::UNUM_ROUND_HALFEVEN, 3, status);
|
||||
assertSuccess("Rounding to increment", status);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 987655E-3>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 5:2:-3:-6 long 987655E-3>");
|
||||
fq.roundToMagnitude(-2, RoundingMode::UNUM_ROUND_HALFEVEN, status);
|
||||
assertSuccess("Rounding to magnitude", status);
|
||||
assertToStringAndHealth(fq, "<DecimalQuantity 5:2:-3:-6 long 98766E-2>");
|
||||
assertToStringAndHealth(fq, u"<DecimalQuantity 5:2:-3:-6 long 98766E-2>");
|
||||
}
|
||||
|
||||
void DecimalQuantityTest::testSwitchStorage() {
|
||||
@ -102,67 +102,67 @@ void DecimalQuantityTest::testSwitchStorage() {
|
||||
|
||||
fq.setToLong(1234123412341234L);
|
||||
assertFalse("Should not be using byte array", fq.isUsingBytes());
|
||||
assertEquals("Failed on initialize", "1234123412341234E0", fq.toNumberString());
|
||||
assertEquals("Failed on initialize", u"1234123412341234E0", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
// Long -> Bytes
|
||||
fq.appendDigit(5, 0, true);
|
||||
assertTrue("Should be using byte array", fq.isUsingBytes());
|
||||
assertEquals("Failed on multiply", "12341234123412345E0", fq.toNumberString());
|
||||
assertEquals("Failed on multiply", u"12341234123412345E0", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
// Bytes -> Long
|
||||
fq.roundToMagnitude(5, RoundingMode::UNUM_ROUND_HALFEVEN, status);
|
||||
assertSuccess("Rounding to magnitude", status);
|
||||
assertFalse("Should not be using byte array", fq.isUsingBytes());
|
||||
assertEquals("Failed on round", "123412341234E5", fq.toNumberString());
|
||||
assertEquals("Failed on round", u"123412341234E5", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
}
|
||||
|
||||
void DecimalQuantityTest::testAppend() {
|
||||
DecimalQuantity fq;
|
||||
fq.appendDigit(1, 0, true);
|
||||
assertEquals("Failed on append", "1E0", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"1E0", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(2, 0, true);
|
||||
assertEquals("Failed on append", "12E0", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"12E0", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(3, 1, true);
|
||||
assertEquals("Failed on append", "1203E0", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"1203E0", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(0, 1, true);
|
||||
assertEquals("Failed on append", "1203E2", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"1203E2", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(4, 0, true);
|
||||
assertEquals("Failed on append", "1203004E0", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"1203004E0", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(0, 0, true);
|
||||
assertEquals("Failed on append", "1203004E1", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"1203004E1", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(5, 0, false);
|
||||
assertEquals("Failed on append", "120300405E-1", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"120300405E-1", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(6, 0, false);
|
||||
assertEquals("Failed on append", "1203004056E-2", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"1203004056E-2", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
fq.appendDigit(7, 3, false);
|
||||
assertEquals("Failed on append", "12030040560007E-6", fq.toNumberString());
|
||||
assertEquals("Failed on append", u"12030040560007E-6", fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
UnicodeString baseExpected("12030040560007");
|
||||
UnicodeString baseExpected(u"12030040560007");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
fq.appendDigit(8, 0, false);
|
||||
baseExpected.append('8');
|
||||
baseExpected.append(u'8');
|
||||
UnicodeString expected(baseExpected);
|
||||
expected.append("E-");
|
||||
expected.append(u"E-");
|
||||
if (i >= 3) {
|
||||
expected.append('1');
|
||||
expected.append(u'1');
|
||||
}
|
||||
expected.append(((7 + i) % 10) + '0');
|
||||
expected.append(((7 + i) % 10) + u'0');
|
||||
assertEquals("Failed on append", expected, fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
}
|
||||
fq.appendDigit(9, 2, false);
|
||||
baseExpected.append("009");
|
||||
baseExpected.append(u"009");
|
||||
UnicodeString expected(baseExpected);
|
||||
expected.append("E-19");
|
||||
expected.append(u"E-19");
|
||||
assertEquals("Failed on append", expected, fq.toNumberString());
|
||||
assertHealth(fq);
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ void NumberStringBuilderTest::testUnlimitedCapacity() {
|
||||
UnicodeString message("Iteration #");
|
||||
message += Int64ToUnicodeString(i);
|
||||
assertEquals(message, builder.length(), i);
|
||||
builder.appendCodePoint('x', UNUM_FIELD_COUNT, status);
|
||||
builder.appendCodePoint(u'x', UNUM_FIELD_COUNT, status);
|
||||
assertSuccess(message, status);
|
||||
assertEquals(message, builder.length(), i + 1);
|
||||
}
|
||||
@ -229,8 +229,8 @@ void NumberStringBuilderTest::assertEqualsImpl(const UnicodeString &a, const Num
|
||||
|
||||
for (int32_t i = 0; i < a.length(); i++) {
|
||||
IntlTest::assertEquals(
|
||||
UnicodeString("Char at position ") + Int64ToUnicodeString(i) +
|
||||
UnicodeString(" in string ") + a, a.charAt(i), b.charAt(i));
|
||||
UnicodeString(u"Char at position ") + Int64ToUnicodeString(i) +
|
||||
UnicodeString(u" in string ") + a, a.charAt(i), b.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user