From: Travis Keep Date: Mon, 17 Sep 2012 18:06:12 +0000 (+0000) Subject: ICU-9566 Fix CompactDecimalFormat.formatToCharacterIterator in JAVA to work correctly. X-Git-Tag: milestone-59-0-1~3556 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f985dceb397f89de984a131218d45fda18f4962a;p=icu ICU-9566 Fix CompactDecimalFormat.formatToCharacterIterator in JAVA to work correctly. X-SVN-Rev: 32395 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/CompactDecimalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/CompactDecimalFormat.java index 64f2bcc4d77..9ae08cdb781 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/CompactDecimalFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/CompactDecimalFormat.java @@ -13,6 +13,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigDecimal; import java.math.BigInteger; +import java.text.AttributedCharacterIterator; import java.text.FieldPosition; import java.text.ParsePosition; import java.util.Collection; @@ -171,25 +172,25 @@ public class CompactDecimalFormat extends DecimalFormat { */ @Override public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) { - if (number < 0.0d) { - throw new UnsupportedOperationException("CompactDecimalFormat doesn't handle negative numbers yet."); - } - // We do this here so that the prefix or suffix we choose is always consistent - // with the rounding we do. This way, 999999 -> 1M instead of 1000K. - number = adjustNumberAsInFormatting(number); - int base = number <= 1.0d ? 0 : (int) Math.log10(number); - if (base >= CompactDecimalDataCache.MAX_DIGITS) { - base = CompactDecimalDataCache.MAX_DIGITS - 1; - } - number = number / divisor[base]; - String pluralVariant = getPluralForm(number); - setPositivePrefix(CompactDecimalDataCache.getPrefixOrSuffix(prefix, pluralVariant, base)); - setPositiveSuffix(CompactDecimalDataCache.getPrefixOrSuffix(suffix, pluralVariant, base)); - setCurrency(null); - + number = configure(number); return super.format(number, toAppendTo, pos); } + /** + * {@inheritDoc} + * @draft ICU 50 + * @provisional This API might change or be removed in a future release. + */ + @Override + public AttributedCharacterIterator formatToCharacterIterator(Object obj) { + if (!(obj instanceof Number)) { + throw new IllegalArgumentException(); + } + Number number = (Number) obj; + double newNumber = configure(number.doubleValue()); + return super.formatToCharacterIterator(newNumber); + } + /** * {@inheritDoc} * @draft ICU 49 @@ -252,7 +253,24 @@ public class CompactDecimalFormat extends DecimalFormat { /* INTERNALS */ - + private double configure(double number) { + if (number < 0.0d) { + throw new UnsupportedOperationException("CompactDecimalFormat doesn't handle negative numbers yet."); + } + // We do this here so that the prefix or suffix we choose is always consistent + // with the rounding we do. This way, 999999 -> 1M instead of 1000K. + number = adjustNumberAsInFormatting(number); + int base = number <= 1.0d ? 0 : (int) Math.log10(number); + if (base >= CompactDecimalDataCache.MAX_DIGITS) { + base = CompactDecimalDataCache.MAX_DIGITS - 1; + } + number /= divisor[base]; + String pluralVariant = getPluralForm(number); + setPositivePrefix(CompactDecimalDataCache.getPrefixOrSuffix(prefix, pluralVariant, base)); + setPositiveSuffix(CompactDecimalDataCache.getPrefixOrSuffix(suffix, pluralVariant, base)); + setCurrency(null); + return number; + } private void recordError(Collection creationErrors, String errorMessage) { if (creationErrors == null) { diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/CompactDecimalFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/CompactDecimalFormatTest.java index 6c9c7c2a207..50852efed04 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/CompactDecimalFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/CompactDecimalFormatTest.java @@ -6,6 +6,9 @@ */ package com.ibm.icu.dev.test.format; +import java.text.AttributedCharacterIterator; +import java.text.CharacterIterator; + import com.ibm.icu.dev.test.TestFmwk; import com.ibm.icu.text.CompactDecimalFormat; import com.ibm.icu.text.NumberFormat; @@ -105,10 +108,21 @@ public class CompactDecimalFormatTest extends TestFmwk { {12345678901234567890f, "T12000000"}, }; + public void TestCharacterIterator() { + CompactDecimalFormat cdf = + NumberFormat.getCompactDecimalInstance(ULocale.ENGLISH, CompactStyle.SHORT); + AttributedCharacterIterator iter = cdf.formatToCharacterIterator(12346); + assertEquals("CharacterIterator", "12K", iterToString(iter)); + iter = cdf.formatToCharacterIterator(12346); + assertEquals("Attributes", iter.getAttribute(NumberFormat.Field.INTEGER), NumberFormat.Field.INTEGER); + assertEquals("Attributes", 0, iter.getRunStart()); + assertEquals("Attributes", 2, iter.getRunLimit()); + } + public void TestEnglishShort() { checkLocale(ULocale.ENGLISH, CompactStyle.SHORT, EnglishTestData); } - + public void TestNoLongStyleInCLDR() { NumberFormat cdf = NumberFormat.getCompactDecimalInstance( @@ -138,4 +152,12 @@ public class CompactDecimalFormatTest extends TestFmwk { assertEquals(locale + " (" + locale.getDisplayName(locale) + ")", row[1], cdf.format(row[0])); } } + + private static String iterToString(CharacterIterator iter) { + StringBuilder builder = new StringBuilder(); + for (char c = iter.current(); c != CharacterIterator.DONE; c = iter.next()) { + builder.append(c); + } + return builder.toString(); + } }