ICU-13634 Fixing affix overrides when using CurrencyPluralInfo.

X-SVN-Rev: 41217
This commit is contained in:
Shane Carr 2018-04-11 23:14:06 +00:00
parent 2c6bf0d77e
commit a9e8f6d135
8 changed files with 39 additions and 22 deletions

View File

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

View File

@ -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<StandardPlural::Form>(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);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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