package com.ibm.icu.impl;
import java.lang.ref.SoftReference;
-import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.MissingResourceException;
public ICUCurrencyDisplayInfoProvider() {
}
+ /**
+ * Single-item cache for ICUCurrencyDisplayInfo keyed by locale.
+ */
+ private volatile ICUCurrencyDisplayInfo currencyDisplayInfoCache = null;
+
@Override
public CurrencyDisplayInfo getInstance(ULocale locale, boolean withFallback) {
- ICUResourceBundle rb;
- if (withFallback) {
- rb = ICUResourceBundle.getBundleInstance(
- ICUData.ICU_CURR_BASE_NAME, locale, OpenType.LOCALE_DEFAULT_ROOT);
- } else {
- try {
+ ICUCurrencyDisplayInfo instance = currencyDisplayInfoCache;
+ if (instance == null || !instance.locale.equals(locale) || instance.fallback != withFallback) {
+ ICUResourceBundle rb;
+ if (withFallback) {
rb = ICUResourceBundle.getBundleInstance(
- ICUData.ICU_CURR_BASE_NAME, locale, OpenType.LOCALE_ONLY);
- } catch (MissingResourceException e) {
- return null;
+ ICUData.ICU_CURR_BASE_NAME, locale, OpenType.LOCALE_DEFAULT_ROOT);
+ } else {
+ try {
+ rb = ICUResourceBundle.getBundleInstance(
+ ICUData.ICU_CURR_BASE_NAME, locale, OpenType.LOCALE_ONLY);
+ } catch (MissingResourceException e) {
+ return null;
+ }
}
+ instance = new ICUCurrencyDisplayInfo(locale, rb, withFallback);
+ currencyDisplayInfoCache = instance;
}
- return new ICUCurrencyDisplayInfo(rb, withFallback);
+ return instance;
}
@Override
return true;
}
+ /**
+ * This class performs data loading for currencies and keeps data in lightweight cache.
+ */
static class ICUCurrencyDisplayInfo extends CurrencyDisplayInfo {
- private final boolean fallback;
+ final ULocale locale;
+ final boolean fallback;
private final ICUResourceBundle rb;
- private volatile SoftReference<RawCurrencyData> rawDataCache;
/**
- * The primary data structure is isoCodeToCurrencyStrings. In that structure,
- * the String arrays contain the following elements:
+ * Single-item cache for getName(), getSymbol(), and getFormatInfo().
+ * Holds data for only one currency. If another currency is requested, the old cache item is overwritten.
+ */
+ private volatile FormattingData formattingDataCache = null;
+
+ /**
+ * Single-item cache for getNarrowSymbol().
+ * Holds data for only one currency. If another currency is requested, the old cache item is overwritten.
+ */
+ private volatile NarrowSymbol narrowSymbolCache = null;
+
+ /**
+ * Single-item cache for getPluralName().
+ *
+ * <p>
+ * array[0] is the ISO code.<br>
+ * array[1+p] is the plural name where p=standardPlural.ordinal().
*
- * [DISPLAY_NAME] => display name
- * [SYMBOL] => symbol
- * [NARROW_SYMBOL] => narrow symbol
- * [FORMAT_PATTERN] => currency format pattern
- * [DECIMAL_SEPARATOR] => currency decimal separator
- * [GROUPING_SEPARATOR] => currency grouping separator
- * [PLURALS_OFFSET+p] => plural name where p=standardPlural.ordinal()
+ * <p>
+ * Holds data for only one currency. If another currency is requested, the old cache item is overwritten.
*/
- private static class RawCurrencyData {
- static final int DISPLAY_NAME = 0;
- static final int SYMBOL = 1;
- static final int NARROW_SYMBOL = 2;
- static final int FORMAT_PATTERN = 3;
- static final int DECIMAL_SEPARATOR = 4;
- static final int GROUPING_SEPARATOR = 5;
- static final int PLURALS_OFFSET = 6;
- static final int CURRENCY_STRINGS_LENGTH = 6 + StandardPlural.COUNT;
-
- Map<String, String[]> isoCodeToCurrencyStrings = new HashMap<String, String[]>();
-
- // The following maps are redundant data with the above map, but the API for CurrencyDisplayNames
- // restricts us to using these data structures.
- Map<String, String> symbolToIsoCode = new HashMap<String, String>();
- Map<String, String> nameToIsoCode = new HashMap<String, String>();
+ private volatile String[] pluralsDataCache = null;
- // Other currency-related data
- CurrencySpacingInfo spacingInfo = new CurrencySpacingInfo();
- Map<String, String> currencyUnitPatterns = new HashMap<String, String>();
+ /**
+ * Cache for symbolMap() and nameMap().
+ */
+ private volatile SoftReference<ParsingData> parsingDataCache = new SoftReference<ParsingData>(null);
- /**
- * Gets an entry out of isoCodeToCurrencyStrings or creates it if it does not exist yet.
- */
- String[] getOrCreateCurrencyStrings(String isoCode) {
- String[] currencyStrings = isoCodeToCurrencyStrings.get(isoCode);
- if (currencyStrings == null) {
- currencyStrings = new String[CURRENCY_STRINGS_LENGTH];
- isoCodeToCurrencyStrings.put(isoCode, currencyStrings);
- }
- return currencyStrings;
- }
+ /**
+ * Cache for getUnitPatterns().
+ */
+ private volatile Map<String, String> unitPatternsCache = null;
- /**
- * Called after all data is loaded to convert the externally visible Maps to Unmodifiable.
- */
- void freezeMaps() {
- symbolToIsoCode = Collections.unmodifiableMap(symbolToIsoCode);
- nameToIsoCode = Collections.unmodifiableMap(nameToIsoCode);
- currencyUnitPatterns = Collections.unmodifiableMap(currencyUnitPatterns);
- }
+ /**
+ * Cache for getSpacingInfo().
+ */
+ private volatile CurrencySpacingInfo spacingInfoCache = null;
+
+ static class FormattingData {
+ final String isoCode;
+ String displayName = null;
+ String symbol = null;
+ CurrencyFormatInfo formatInfo = null;
+
+ FormattingData(String isoCode) { this.isoCode = isoCode; }
}
- public ICUCurrencyDisplayInfo(ICUResourceBundle rb, boolean fallback) {
+ static class NarrowSymbol {
+ final String isoCode;
+ String narrowSymbol = null;
+
+ NarrowSymbol(String isoCode) { this.isoCode = isoCode; }
+ }
+
+ static class ParsingData {
+ Map<String, String> symbolToIsoCode = new HashMap<String, String>();
+ Map<String, String> nameToIsoCode = new HashMap<String, String>();
+ }
+
+ ////////////////////////
+ /// START PUBLIC API ///
+ ////////////////////////
+
+ public ICUCurrencyDisplayInfo(ULocale locale, ICUResourceBundle rb, boolean fallback) {
+ this.locale = locale;
this.fallback = fallback;
this.rb = rb;
- rawDataCache = new SoftReference<RawCurrencyData>(null);
}
@Override
@Override
public String getName(String isoCode) {
- return getName(isoCode, RawCurrencyData.DISPLAY_NAME);
+ FormattingData formattingData = fetchFormattingData(isoCode);
+
+ // Fall back to ISO Code
+ if (formattingData.displayName == null && fallback) {
+ return isoCode;
+ }
+ return formattingData.displayName;
}
@Override
public String getSymbol(String isoCode) {
- return getName(isoCode, RawCurrencyData.SYMBOL);
+ FormattingData formattingData = fetchFormattingData(isoCode);
+
+ // Fall back to ISO Code
+ if (formattingData.symbol == null && fallback) {
+ return isoCode;
+ }
+ return formattingData.symbol;
}
@Override
public String getNarrowSymbol(String isoCode) {
- // TODO: Should this fall back to the regular symbol instead of the ISO code?
- return getName(isoCode, RawCurrencyData.NARROW_SYMBOL);
- }
+ NarrowSymbol narrowSymbol = fetchNarrowSymbol(isoCode);
- private String getName(String isoCode, int index) {
- String[] currencyStrings = getRawCurrencyData().isoCodeToCurrencyStrings.get(isoCode);
- String result = null;
- if (currencyStrings != null) {
- result = currencyStrings[index];
- }
- // If fallback is true, don't return null; return the ISO code
- if (result == null && fallback) {
- result = isoCode;
+ // Fall back to ISO Code
+ // TODO: Should this fall back to the regular symbol instead of the ISO code?
+ if (narrowSymbol.narrowSymbol == null && fallback) {
+ return isoCode;
}
- return result;
+ return narrowSymbol.narrowSymbol;
}
@Override
public String getPluralName(String isoCode, String pluralKey ) {
StandardPlural plural = StandardPlural.orNullFromString(pluralKey);
- String[] currencyStrings = getRawCurrencyData().isoCodeToCurrencyStrings.get(isoCode);
+ String[] pluralsData = fetchPluralsData(isoCode);
+
+ // See http://unicode.org/reports/tr35/#Currencies, especially the fallback rule.
String result = null;
- if (currencyStrings != null && plural != null) {
- result = currencyStrings[RawCurrencyData.PLURALS_OFFSET + plural.ordinal()];
+ if (plural != null) {
+ result = pluralsData[1 + plural.ordinal()];
}
- // See http://unicode.org/reports/tr35/#Currencies, especially the fallback rule.
- if (result == null && currencyStrings != null && fallback) {
+ if (result == null && fallback) {
// First fall back to the "other" plural variant
// Note: If plural is already "other", this fallback is benign
- result = currencyStrings[RawCurrencyData.PLURALS_OFFSET + StandardPlural.OTHER.ordinal()];
+ result = pluralsData[1 + StandardPlural.OTHER.ordinal()];
}
- if (result == null && currencyStrings != null && fallback) {
+ if (result == null && fallback) {
// If that fails, fall back to the display name
- result = currencyStrings[0];
+ FormattingData formattingData = fetchFormattingData(isoCode);
+ result = formattingData.displayName;
}
if (result == null && fallback) {
// If all else fails, return the ISO code
@Override
public Map<String, String> symbolMap() {
- return getRawCurrencyData().symbolToIsoCode;
+ ParsingData parsingData = fetchParsingData();
+ return parsingData.symbolToIsoCode;
}
@Override
public Map<String, String> nameMap() {
- return getRawCurrencyData().nameToIsoCode;
+ ParsingData parsingData = fetchParsingData();
+ return parsingData.nameToIsoCode;
}
@Override
public Map<String, String> getUnitPatterns() {
// Default result is the empty map. Callers who require a pattern will have to
// supply a default.
- return getRawCurrencyData().currencyUnitPatterns;
+ Map<String,String> unitPatterns = fetchUnitPatterns();
+ return unitPatterns;
}
@Override
public CurrencyFormatInfo getFormatInfo(String isoCode) {
- String[] currencyStrings = getRawCurrencyData().isoCodeToCurrencyStrings.get(isoCode);
- if (currencyStrings == null || currencyStrings[RawCurrencyData.FORMAT_PATTERN] == null) {
- return null;
- }
- String pattern = currencyStrings[RawCurrencyData.FORMAT_PATTERN];
- String decimalSeparator = currencyStrings[RawCurrencyData.DECIMAL_SEPARATOR];
- String groupingSeparator = currencyStrings[RawCurrencyData.GROUPING_SEPARATOR];
- return new CurrencyFormatInfo(pattern, decimalSeparator, groupingSeparator);
+ FormattingData formattingData = fetchFormattingData(isoCode);
+ return formattingData.formatInfo;
}
@Override
public CurrencySpacingInfo getSpacingInfo() {
- CurrencySpacingInfo result = getRawCurrencyData().spacingInfo;
- if (result != null && (!result.hasBeforeCurrency || !result.hasAfterCurrency) && fallback) {
- result = CurrencySpacingInfo.DEFAULT;
+ CurrencySpacingInfo spacingInfo = fetchSpacingInfo();
+
+ // Fall back to DEFAULT
+ if ((!spacingInfo.hasBeforeCurrency || !spacingInfo.hasAfterCurrency) && fallback) {
+ return CurrencySpacingInfo.DEFAULT;
}
- if (result == null && fallback) {
- result = CurrencySpacingInfo.DEFAULT;
+ return spacingInfo;
+ }
+
+ /////////////////////////////////////////////
+ /// END PUBLIC API -- START DATA FRONTEND ///
+ /////////////////////////////////////////////
+
+ FormattingData fetchFormattingData(String isoCode) {
+ FormattingData result = formattingDataCache;
+ if (result == null || !result.isoCode.equals(isoCode)) {
+ result = new FormattingData(isoCode);
+ CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCIES);
+ sink.formattingData = result;
+ rb.getAllItemsWithFallbackNoFail("Currencies/" + isoCode, sink);
+ formattingDataCache = result;
}
return result;
}
- /**
- * If the soft cache is populated, returns the data stored there.
- * Otherwise, computes the data, stores it in the cache, and returns it.
- * Never returns null.
- */
- private RawCurrencyData getRawCurrencyData() {
- RawCurrencyData data = rawDataCache.get();
- if (data == null) {
- data = new RawCurrencyData();
- RawCurrencyDataSink sink = new RawCurrencyDataSink(data, !fallback);
+ NarrowSymbol fetchNarrowSymbol(String isoCode) {
+ NarrowSymbol result = narrowSymbolCache;
+ if (result == null || !result.isoCode.equals(isoCode)) {
+ result = new NarrowSymbol(isoCode);
+ CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCY_NARROW);
+ sink.narrowSymbol = result;
+ rb.getAllItemsWithFallbackNoFail("Currencies%narrow/" + isoCode, sink);
+ narrowSymbolCache = result;
+ }
+ return result;
+ }
+
+ String[] fetchPluralsData(String isoCode) {
+ String[] result = pluralsDataCache;
+ if (result == null || !result[0].equals(isoCode)) {
+ result = new String[1 + StandardPlural.COUNT];
+ result[0] = isoCode;
+ CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCY_PLURALS);
+ sink.pluralsData = result;
+ rb.getAllItemsWithFallbackNoFail("CurrencyPlurals/" + isoCode, sink);
+ pluralsDataCache = result;
+ }
+ return result;
+ }
+
+ ParsingData fetchParsingData() {
+ ParsingData result = parsingDataCache.get();
+ if (result == null) {
+ result = new ParsingData();
+ CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.TOP);
+ sink.parsingData = result;
rb.getAllItemsWithFallback("", sink);
- data.freezeMaps();
- rawDataCache = new SoftReference<RawCurrencyData>(data);
+ parsingDataCache = new SoftReference<ParsingData>(result);
}
- return data;
+ return result;
}
- private static final class RawCurrencyDataSink extends UResource.Sink {
- private final RawCurrencyData data;
- private final boolean noRoot;
+ Map<String, String> fetchUnitPatterns() {
+ Map<String, String> result = unitPatternsCache;
+ if (result == null) {
+ result = new HashMap<String, String>();
+ CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCY_UNIT_PATTERNS);
+ sink.unitPatterns = result;
+ rb.getAllItemsWithFallback("CurrencyUnitPatterns", sink);
+ unitPatternsCache = result;
+ }
+ return result;
+ }
+
+ CurrencySpacingInfo fetchSpacingInfo() {
+ CurrencySpacingInfo result = spacingInfoCache;
+ if (result == null) {
+ result = new CurrencySpacingInfo();
+ CurrencySink sink = new CurrencySink(!fallback, CurrencySink.EntrypointTable.CURRENCY_SPACING);
+ sink.spacingInfo = result;
+ rb.getAllItemsWithFallback("currencySpacing", sink);
+ spacingInfoCache = result;
+ }
+ return result;
+ }
- RawCurrencyDataSink(RawCurrencyData data, boolean noRoot) {
- this.data = data;
+ ////////////////////////////////////////////
+ /// END DATA FRONTEND -- START DATA SINK ///
+ ////////////////////////////////////////////
+
+ private static final class CurrencySink extends UResource.Sink {
+ final boolean noRoot;
+ final EntrypointTable entrypointTable;
+
+ // The fields to be populated on this run of the data sink will be non-null.
+ FormattingData formattingData = null;
+ String[] pluralsData = null;
+ ParsingData parsingData = null;
+ Map<String, String> unitPatterns = null;
+ CurrencySpacingInfo spacingInfo = null;
+ NarrowSymbol narrowSymbol = null;
+
+ enum EntrypointTable {
+ // For Parsing:
+ TOP,
+
+ // For Formatting:
+ CURRENCIES,
+ CURRENCY_PLURALS,
+ CURRENCY_NARROW,
+ CURRENCY_SPACING,
+ CURRENCY_UNIT_PATTERNS
+ }
+
+ CurrencySink(boolean noRoot, EntrypointTable entrypointTable) {
this.noRoot = noRoot;
+ this.entrypointTable = entrypointTable;
}
/**
* found in the currency data.
*/
@Override
- public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
- if (noRoot && noFallback) {
+ public void put(UResource.Key key, UResource.Value value, boolean isRoot) {
+ if (noRoot && isRoot) {
// Don't consume the root bundle
return;
}
+ switch (entrypointTable) {
+ case TOP:
+ consumeTopTable(key, value);
+ break;
+ case CURRENCIES:
+ consumeCurrenciesEntry(key, value);
+ break;
+ case CURRENCY_PLURALS:
+ consumeCurrencyPluralsEntry(key, value);
+ break;
+ case CURRENCY_NARROW:
+ consumeCurrenciesNarrowEntry(key, value);
+ break;
+ case CURRENCY_SPACING:
+ consumeCurrencySpacingTable(key, value);
+ break;
+ case CURRENCY_UNIT_PATTERNS:
+ consumeCurrencyUnitPatternsTable(key, value);
+ break;
+ }
+ }
+
+ private void consumeTopTable(UResource.Key key, UResource.Value value) {
UResource.Table table = value.getTable();
for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
if (key.contentEquals("Currencies")) {
- consumeCurrencies(key, value, noFallback);
- } else if (key.contentEquals("Currencies%narrow")) {
- consumeCurrenciesNarrow(key, value, noFallback);
+ consumeCurrenciesTable(key, value);
} else if (key.contentEquals("Currencies%variant")) {
- consumeCurrenciesVariant(key, value, noFallback);
+ consumeCurrenciesVariantTable(key, value);
} else if (key.contentEquals("CurrencyPlurals")) {
- consumeCurrencyPlurals(key, value, noFallback);
- } else if (key.contentEquals("currencySpacing")) {
- consumeCurrencySpacing(key, value, noFallback);
- } else if (key.contentEquals("CurrencyUnitPatterns")) {
- consumeCurrencyUnitPatterns(key, value, noFallback);
+ consumeCurrencyPluralsTable(key, value);
}
}
}
* "US Dollar", => display name
* }
* ...
- * ESP{
- * "₧", => symbol
- * "pesseta espanyola", => display name
- * {
- * "¤ #,##0.00", => currency-specific pattern
- * ",", => currency-specific grouping separator
- * ".", => currency-specific decimal separator
+ * ESP{
+ * "₧", => symbol
+ * "pesseta espanyola", => display name
+ * {
+ * "¤ #,##0.00", => currency-specific pattern
+ * ",", => currency-specific grouping separator
+ * ".", => currency-specific decimal separator
+ * }
* }
- * }
* ...
* }
*/
- private void consumeCurrencies(UResource.Key key, UResource.Value value, boolean noFallback) {
-
+ void consumeCurrenciesTable(UResource.Key key, UResource.Value value) {
+ // The full Currencies table is consumed for parsing only.
+ assert parsingData != null;
UResource.Table table = value.getTable();
for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
String isoCode = key.toString();
- String[] currencyStrings = data.getOrCreateCurrencyStrings(isoCode);
if (value.getType() != UResourceBundle.ARRAY) {
throw new ICUException("Unexpected data type in Currencies table for " + isoCode);
}
UResource.Array array = value.getArray();
- // First element is the symbol.
+ parsingData.symbolToIsoCode.put(isoCode, isoCode); // Add the ISO code itself as a symbol
array.getValue(0, value);
- String symbol = value.getString();
- if (currencyStrings[RawCurrencyData.SYMBOL] == null) {
- currencyStrings[RawCurrencyData.SYMBOL] = symbol;
- }
-
- // Second element is the display name.
+ parsingData.symbolToIsoCode.put(value.getString(), isoCode);
array.getValue(1, value);
- String name = value.getString();
- if (currencyStrings[RawCurrencyData.DISPLAY_NAME] == null) {
- currencyStrings[RawCurrencyData.DISPLAY_NAME] = name;
- }
+ parsingData.nameToIsoCode.put(value.getString(), isoCode);
+ }
+ }
- // If present, the third element is the currency format info.
- // TODO: Write unit test to ensure that this data is being used by number formatting.
- if (array.getSize() > 2 && currencyStrings[RawCurrencyData.FORMAT_PATTERN] == null) {
- array.getValue(2, value);
- UResource.Array formatArray = value.getArray();
- formatArray.getValue(0, value);
- currencyStrings[RawCurrencyData.FORMAT_PATTERN] = value.getString();
- assert currencyStrings[RawCurrencyData.DECIMAL_SEPARATOR] == null;
- formatArray.getValue(1, value);
- currencyStrings[RawCurrencyData.DECIMAL_SEPARATOR] = value.getString();
- assert currencyStrings[RawCurrencyData.GROUPING_SEPARATOR] == null;
- formatArray.getValue(2, value);
- currencyStrings[RawCurrencyData.GROUPING_SEPARATOR] = value.getString();
- }
+ void consumeCurrenciesEntry(UResource.Key key, UResource.Value value) {
+ assert formattingData != null;
+ String isoCode = key.toString();
+ if (value.getType() != UResourceBundle.ARRAY) {
+ throw new ICUException("Unexpected data type in Currencies table for " + isoCode);
+ }
+ UResource.Array array = value.getArray();
+
+ if (formattingData.symbol == null) {
+ array.getValue(0, value);
+ formattingData.symbol = value.getString();
+ }
+ if (formattingData.displayName == null) {
+ array.getValue(1, value);
+ formattingData.displayName = value.getString();
+ }
- // Add the name and symbols to the other two maps (used for parsing).
- data.nameToIsoCode.put(name, isoCode);
- data.symbolToIsoCode.put(isoCode, isoCode); // Add the ISO code itself as a symbol
- data.symbolToIsoCode.put(symbol, isoCode);
+ // If present, the third element is the currency format info.
+ // TODO: Write unit test to ensure that this data is being used by number formatting.
+ if (array.getSize() > 2 && formattingData.formatInfo == null) {
+ array.getValue(2, value);
+ UResource.Array formatArray = value.getArray();
+ formatArray.getValue(0, value);
+ String formatPattern = value.getString();
+ formatArray.getValue(1, value);
+ String decimalSeparator = value.getString();
+ formatArray.getValue(2, value);
+ String groupingSeparator = value.getString();
+ formattingData.formatInfo = new CurrencyFormatInfo(
+ isoCode, formatPattern, decimalSeparator, groupingSeparator);
}
}
* ...
* }
*/
- private void consumeCurrenciesNarrow(UResource.Key key, UResource.Value value, boolean noFallback) {
- UResource.Table table = value.getTable();
- for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
- String isoCode = key.toString();
- String[] currencyStrings = data.getOrCreateCurrencyStrings(isoCode);
- if (currencyStrings[RawCurrencyData.NARROW_SYMBOL] == null) {
- currencyStrings[RawCurrencyData.NARROW_SYMBOL] = value.getString();
- }
-
- // Note: This data is used for formatting but not parsing.
+ void consumeCurrenciesNarrowEntry(UResource.Key key, UResource.Value value) {
+ assert narrowSymbol != null;
+ // No extra structure to traverse.
+ if (narrowSymbol.narrowSymbol == null) {
+ narrowSymbol.narrowSymbol = value.getString();
}
}
* TRY{"TL"}
* }
*/
- private void consumeCurrenciesVariant(UResource.Key key, UResource.Value value, boolean noFallback) {
+ void consumeCurrenciesVariantTable(UResource.Key key, UResource.Value value) {
+ // Note: This data is used for parsing but not formatting.
+ assert parsingData != null;
UResource.Table table = value.getTable();
for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
String isoCode = key.toString();
-
- // Note: This data is used for parsing but not formatting.
- data.symbolToIsoCode.put(value.getString(), isoCode);
+ parsingData.symbolToIsoCode.put(value.getString(), isoCode);
}
}
* ...
* }
*/
- private void consumeCurrencyPlurals(UResource.Key key, UResource.Value value, boolean noFallback) {
+ void consumeCurrencyPluralsTable(UResource.Key key, UResource.Value value) {
+ // The full CurrencyPlurals table is consumed for parsing only.
+ assert parsingData != null;
UResource.Table table = value.getTable();
for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
String isoCode = key.toString();
- String[] currencyStrings = data.getOrCreateCurrencyStrings(isoCode);
UResource.Table pluralsTable = value.getTable();
for (int j=0; pluralsTable.getKeyAndValue(j, key, value); j++) {
StandardPlural plural = StandardPlural.orNullFromString(key.toString());
if (plural == null) {
throw new ICUException("Could not make StandardPlural from keyword " + key);
}
- String valueString = value.getString();
- if (currencyStrings[RawCurrencyData.PLURALS_OFFSET + plural.ordinal()] == null) {
- currencyStrings[RawCurrencyData.PLURALS_OFFSET + plural.ordinal()] = valueString;
- }
- // Add the name to the name-to-currency map (used for parsing)
- data.nameToIsoCode.put(valueString, isoCode);
+ parsingData.nameToIsoCode.put(value.getString(), isoCode);
+ }
+ }
+ }
+
+ void consumeCurrencyPluralsEntry(UResource.Key key, UResource.Value value) {
+ assert pluralsData != null;
+ UResource.Table pluralsTable = value.getTable();
+ for (int j=0; pluralsTable.getKeyAndValue(j, key, value); j++) {
+ StandardPlural plural = StandardPlural.orNullFromString(key.toString());
+ if (plural == null) {
+ throw new ICUException("Could not make StandardPlural from keyword " + key);
+ }
+
+ if (pluralsData[1 + plural.ordinal()] == null) {
+ pluralsData[1 + plural.ordinal()] = value.getString();
}
}
}
* }
* }
*/
- private void consumeCurrencySpacing(UResource.Key key, UResource.Value value, boolean noFallback) {
+ void consumeCurrencySpacingTable(UResource.Key key, UResource.Value value) {
+ assert spacingInfo != null;
UResource.Table spacingTypesTable = value.getTable();
for (int i = 0; spacingTypesTable.getKeyAndValue(i, key, value); ++i) {
CurrencySpacingInfo.SpacingType type;
if (key.contentEquals("beforeCurrency")) {
type = CurrencySpacingInfo.SpacingType.BEFORE;
- data.spacingInfo.hasBeforeCurrency = true;
+ spacingInfo.hasBeforeCurrency = true;
} else if (key.contentEquals("afterCurrency")) {
type = CurrencySpacingInfo.SpacingType.AFTER;
- data.spacingInfo.hasAfterCurrency = true;
+ spacingInfo.hasAfterCurrency = true;
} else {
continue;
}
continue;
}
- data.spacingInfo.setSymbolIfNull(type, pattern, value.getString());
+ spacingInfo.setSymbolIfNull(type, pattern, value.getString());
}
}
}
* ...
* }
*/
- private void consumeCurrencyUnitPatterns(UResource.Key key, UResource.Value value, boolean noFallback) {
+ void consumeCurrencyUnitPatternsTable(UResource.Key key, UResource.Value value) {
+ assert unitPatterns != null;
UResource.Table table = value.getTable();
for (int i = 0; table.getKeyAndValue(i, key, value); i++) {
String pluralKeyword = key.toString();
- if (data.currencyUnitPatterns.get(pluralKeyword) == null) {
- data.currencyUnitPatterns.put(pluralKeyword, value.getString());
+ if (unitPatterns.get(pluralKeyword) == null) {
+ unitPatterns.put(pluralKeyword, value.getString());
}
}
}