From a9e8f6d13546f2c59ba9d6ae73f6d70092aa7788 Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Wed, 11 Apr 2018 23:14:06 +0000 Subject: [PATCH] ICU-13634 Fixing affix overrides when using CurrencyPluralInfo. X-SVN-Rev: 41217 --- icu4c/source/i18n/number_decimfmtprops.h | 4 ---- icu4c/source/i18n/number_mapper.cpp | 20 ++++++++++++------- icu4c/source/i18n/number_mapper.h | 5 +++-- icu4c/source/i18n/numparse_impl.cpp | 2 +- .../CurrencyPluralInfoAffixProvider.java | 16 +++++++++------ .../impl/number/parse/NumberParserImpl.java | 2 +- .../ibm/icu/number/NumberPropertyMapper.java | 2 +- .../icu/dev/test/format/NumberFormatTest.java | 10 ++++++++++ 8 files changed, 39 insertions(+), 22 deletions(-) diff --git a/icu4c/source/i18n/number_decimfmtprops.h b/icu4c/source/i18n/number_decimfmtprops.h index 6632dfc5a2a..d66a621250c 100644 --- a/icu4c/source/i18n/number_decimfmtprops.h +++ b/icu4c/source/i18n/number_decimfmtprops.h @@ -132,10 +132,6 @@ struct U_I18N_API DecimalFormatProperties { DecimalFormatProperties(); - //DecimalFormatProperties(const DecimalFormatProperties &other) = default; - - DecimalFormatProperties& operator=(const DecimalFormatProperties& other) = default; - bool operator==(const DecimalFormatProperties& other) const; void clear(); diff --git a/icu4c/source/i18n/number_mapper.cpp b/icu4c/source/i18n/number_mapper.cpp index 24a09e6f4b2..51ebb3c0870 100644 --- a/icu4c/source/i18n/number_mapper.cpp +++ b/icu4c/source/i18n/number_mapper.cpp @@ -67,7 +67,7 @@ MacroProps NumberPropertyMapper::oldToNew(const DecimalFormatProperties& propert warehouse.propertiesAPP.setTo(properties, status); affixProvider = &warehouse.propertiesAPP; } else { - warehouse.currencyPluralInfoAPP.setTo(*properties.currencyPluralInfo.fPtr, status); + warehouse.currencyPluralInfoAPP.setTo(*properties.currencyPluralInfo.fPtr, properties, status); warehouse.propertiesAPP.setToBogus(); affixProvider = &warehouse.currencyPluralInfoAPP; } @@ -434,17 +434,23 @@ bool PropertiesAffixPatternProvider::hasBody() const { } -void CurrencyPluralInfoAffixProvider::setTo(const CurrencyPluralInfo& cpi, UErrorCode& status) { +void CurrencyPluralInfoAffixProvider::setTo(const CurrencyPluralInfo& cpi, + const DecimalFormatProperties& properties, + UErrorCode& status) { + // We need to use a PropertiesAffixPatternProvider, not the simpler version ParsedPatternInfo, + // because user-specified affix overrides still need to work. fBogus = false; + DecimalFormatProperties pluralProperties(properties); for (int32_t plural = 0; plural < StandardPlural::COUNT; plural++) { const char* keyword = StandardPlural::getKeyword(static_cast(plural)); UnicodeString patternString; patternString = cpi.getCurrencyPluralPattern(keyword, patternString); - // ParsedPatternInfo does not support being overwritten if it was written previously; - // instead, we need to write to a fresh instance and move it into place. - ParsedPatternInfo temp; - PatternParser::parseToPatternInfo(patternString, temp, status); - affixesByPlural[plural] = std::move(temp); + PatternParser::parseToExistingProperties( + patternString, + pluralProperties, + IGNORE_ROUNDING_NEVER, + status); + affixesByPlural[plural].setTo(pluralProperties, status); } } diff --git a/icu4c/source/i18n/number_mapper.h b/icu4c/source/i18n/number_mapper.h index 5183b1195f6..ef9de18f77e 100644 --- a/icu4c/source/i18n/number_mapper.h +++ b/icu4c/source/i18n/number_mapper.h @@ -77,7 +77,8 @@ class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMem fBogus = true; } - void setTo(const CurrencyPluralInfo& cpi, UErrorCode& status); + void setTo(const CurrencyPluralInfo& cpi, const DecimalFormatProperties& properties, + UErrorCode& status); // AffixPatternProvider Methods: @@ -100,7 +101,7 @@ class CurrencyPluralInfoAffixProvider : public AffixPatternProvider, public UMem bool hasBody() const U_OVERRIDE; private: - ParsedPatternInfo affixesByPlural[StandardPlural::COUNT]; + PropertiesAffixPatternProvider affixesByPlural[StandardPlural::COUNT]; bool fBogus{true}; }; diff --git a/icu4c/source/i18n/numparse_impl.cpp b/icu4c/source/i18n/numparse_impl.cpp index 54609151bcd..db1586bca48 100644 --- a/icu4c/source/i18n/numparse_impl.cpp +++ b/icu4c/source/i18n/numparse_impl.cpp @@ -88,7 +88,7 @@ NumberParserImpl::createParserFromProperties(const number::impl::DecimalFormatPr localPAPP.setTo(properties, status); affixProvider = &localPAPP; } else { - localCPIAP.setTo(*properties.currencyPluralInfo.fPtr, status); + localCPIAP.setTo(*properties.currencyPluralInfo.fPtr, properties, status); affixProvider = &localCPIAP; } if (affixProvider == nullptr || U_FAILURE(status)) { return nullptr; } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/CurrencyPluralInfoAffixProvider.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/CurrencyPluralInfoAffixProvider.java index 2540899cda7..a3aae565aff 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/CurrencyPluralInfoAffixProvider.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/CurrencyPluralInfoAffixProvider.java @@ -3,17 +3,21 @@ package com.ibm.icu.impl.number; import com.ibm.icu.impl.StandardPlural; -import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo; import com.ibm.icu.text.CurrencyPluralInfo; public class CurrencyPluralInfoAffixProvider implements AffixPatternProvider { - private final AffixPatternProvider[] affixesByPlural; + private final PropertiesAffixPatternProvider[] affixesByPlural; - public CurrencyPluralInfoAffixProvider(CurrencyPluralInfo cpi) { - affixesByPlural = new ParsedPatternInfo[StandardPlural.COUNT]; + public CurrencyPluralInfoAffixProvider(CurrencyPluralInfo cpi, DecimalFormatProperties properties) { + // We need to use a PropertiesAffixPatternProvider, not the simpler version ParsedPatternInfo, + // because user-specified affix overrides still need to work. + affixesByPlural = new PropertiesAffixPatternProvider[StandardPlural.COUNT]; + DecimalFormatProperties pluralProperties = new DecimalFormatProperties(); + pluralProperties.copyFrom(properties); for (StandardPlural plural : StandardPlural.VALUES) { - affixesByPlural[plural.ordinal()] = PatternStringParser - .parseToPatternInfo(cpi.getCurrencyPluralPattern(plural.getKeyword())); + String pattern = cpi.getCurrencyPluralPattern(plural.getKeyword()); + PatternStringParser.parseToExistingProperties(pattern, pluralProperties); + affixesByPlural[plural.ordinal()] = new PropertiesAffixPatternProvider(pluralProperties); } } diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java index 957a5933452..bff15dce37e 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/parse/NumberParserImpl.java @@ -139,7 +139,7 @@ public class NumberParserImpl { if (properties.getCurrencyPluralInfo() == null) { affixProvider = new PropertiesAffixPatternProvider(properties); } else { - affixProvider = new CurrencyPluralInfoAffixProvider(properties.getCurrencyPluralInfo()); + affixProvider = new CurrencyPluralInfoAffixProvider(properties.getCurrencyPluralInfo(), properties); } Currency currency = CustomSymbolCurrency.resolve(properties.getCurrency(), locale, symbols); boolean isStrict = properties.getParseMode() == ParseMode.STRICT; diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java index b3051bc4f68..0cbdf3c5ef7 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java @@ -102,7 +102,7 @@ final class NumberPropertyMapper { if (properties.getCurrencyPluralInfo() == null) { affixProvider = new PropertiesAffixPatternProvider(properties); } else { - affixProvider = new CurrencyPluralInfoAffixProvider(properties.getCurrencyPluralInfo()); + affixProvider = new CurrencyPluralInfoAffixProvider(properties.getCurrencyPluralInfo(), properties); } macros.affixProvider = affixProvider; diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java index 6a784fdf4c6..728c538197b 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java @@ -6027,4 +6027,14 @@ public class NumberFormatTest extends TestFmwk { assertEquals("Should fail to parse", 0, ppos.getIndex()); assertEquals("Should fail to parse", 0, ppos.getErrorIndex()); } + + @Test + public void testCurrencyPluralAffixOverrides() { + // The affix setters should override CurrencyPluralInfo, used in the plural currency constructor. + DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.PLURALCURRENCYSTYLE); + df.setCurrency(Currency.getInstance("USD")); + df.setPositiveSuffix("lala"); + assertEquals("Custom suffix should round-trip", "lala", df.getPositiveSuffix()); + assertEquals("Custom suffix should be used in formatting", "123.00lala", df.format(123)); + } } -- 2.40.0