ICU-13177 Improving consistency of Unicode string literals in number formatting code.

X-SVN-Rev: 40583
This commit is contained in:
Shane Carr 2017-10-06 01:37:59 +00:00
parent dbc623d0d8
commit dbf0bfe4a7
7 changed files with 151 additions and 155 deletions

View File

@ -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).
*/

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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));
}
}