diff options
author | Elliott Hughes <enh@google.com> | 2010-01-25 23:13:46 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2010-01-26 16:05:42 -0800 |
commit | f2d5062b67e57ef00ee81fec67480f0d58d66b50 (patch) | |
tree | 2b549c42ac9ab9dab0e2c0a4bb165a40d9e956fb /icu/src/main/java | |
parent | ab3c1e059b3df3b81b7945ea160e1c6296811bc4 (diff) | |
download | libcore-f2d5062b67e57ef00ee81fec67480f0d58d66b50.zip libcore-f2d5062b67e57ef00ee81fec67480f0d58d66b50.tar.gz libcore-f2d5062b67e57ef00ee81fec67480f0d58d66b50.tar.bz2 |
Simplify our DecimalFormat.
Both the is-a and has-a hierarchies for our DecimalFormat implementation were
over-complicated. This patch starts to address that, and makes cloning twice
as fast (50us versus 100us), but not as fast as I'd like (<10us), and without
making much of a dent in the time it takes to create a new NumberFormat (550us
versus 600us).
The speed of cloning is important because Formatter has a hack that uses it,
and I want to change NumberFormat so that it always hands out clones... at
least until I have time to make "new NumberFormat" acceptably fast.
Also fixes DecimalFormat.applyLocalizedPattern (which used to behave as if
you'd called applyPattern).
Diffstat (limited to 'icu/src/main/java')
3 files changed, 132 insertions, 380 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java index 4b296d5..d995dc6 100644 --- a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java +++ b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormat.java @@ -18,11 +18,13 @@ package com.ibm.icu4jni.text; import com.ibm.icu4jni.text.NativeDecimalFormat.UNumberFormatAttribute; import com.ibm.icu4jni.text.NativeDecimalFormat.UNumberFormatTextAttribute; +import com.ibm.icu4jni.util.LocaleData; import java.math.BigDecimal; import java.math.BigInteger; import java.text.AttributedCharacterIterator; import java.text.AttributedString; +import java.text.DecimalFormatSymbols; import java.text.FieldPosition; import java.text.Format; import java.text.NumberFormat; @@ -30,19 +32,32 @@ import java.text.ParsePosition; import java.util.Currency; import java.util.Locale; -public class DecimalFormat extends NumberFormat { - - private int addr; - - private DecimalFormatSymbols symbols; - - // fix to be icu4j conform (harmony wants this field to exist) - // for serialization of java.text.DecimalFormat - @SuppressWarnings("unused") - private boolean useExponentialNotation = false; - @SuppressWarnings("unused") - private byte minExponentDigits = 0; - +public class DecimalFormat { + // Constants corresponding to the native type UNumberFormatSymbol, for use with getSymbol/setSymbol. + private static final int UNUM_DECIMAL_SEPARATOR_SYMBOL = 0; + private static final int UNUM_GROUPING_SEPARATOR_SYMBOL = 1; + private static final int UNUM_PATTERN_SEPARATOR_SYMBOL = 2; + private static final int UNUM_PERCENT_SYMBOL = 3; + private static final int UNUM_ZERO_DIGIT_SYMBOL = 4; + private static final int UNUM_DIGIT_SYMBOL = 5; + private static final int UNUM_MINUS_SIGN_SYMBOL = 6; + private static final int UNUM_PLUS_SIGN_SYMBOL = 7; + private static final int UNUM_CURRENCY_SYMBOL = 8; + private static final int UNUM_INTL_CURRENCY_SYMBOL = 9; + private static final int UNUM_MONETARY_SEPARATOR_SYMBOL = 10; + private static final int UNUM_EXPONENTIAL_SYMBOL = 11; + private static final int UNUM_PERMILL_SYMBOL = 12; + private static final int UNUM_PAD_ESCAPE_SYMBOL = 13; + private static final int UNUM_INFINITY_SYMBOL = 14; + private static final int UNUM_NAN_SYMBOL = 15; + private static final int UNUM_SIGNIFICANT_DIGIT_SYMBOL = 16; + private static final int UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL = 17; + private static final int UNUM_FORMAT_SYMBOL_COUNT = 18; + + // The address of the ICU DecimalFormat* on the native heap. + private final int addr; + + // TODO: store all these in java.text.DecimalFormat instead! private boolean negPrefNull; private boolean negSuffNull; private boolean posPrefNull; @@ -50,37 +65,52 @@ public class DecimalFormat extends NumberFormat { /** * Cache the BigDecimal form of the multiplier. This is null until we've - * formatted a BigDecimal (with a multipler that is not 1), or the user has + * formatted a BigDecimal (with a multiplier that is not 1), or the user has * explicitly called {@link #setMultiplier(int)} with any multiplier. */ private transient BigDecimal multiplierBigDecimal = null; - public DecimalFormat(String pattern, DecimalFormatSymbols icuSymbols) { - this.addr = icuSymbols.getAddr(); - this.symbols = icuSymbols; - applyPattern(pattern); + public DecimalFormat(String pattern, Locale locale, DecimalFormatSymbols symbols) { + this.addr = NativeDecimalFormat.openDecimalFormat(locale.toString(), pattern); + setDecimalFormatSymbols(symbols); } + // Used to implement clone. + private DecimalFormat(DecimalFormat other) { + this.addr = NativeDecimalFormat.cloneDecimalFormatImpl(other.addr); + this.negPrefNull = other.negPrefNull; + this.negSuffNull = other.negSuffNull; + this.posPrefNull = other.posPrefNull; + this.posSuffNull = other.posSuffNull; + } + + // TODO: remove this and just have java.text.DecimalFormat.hashCode do the right thing itself. @Override public int hashCode() { - return super.hashCode() * 37 + this.getPositivePrefix().hashCode(); + return this.getPositivePrefix().hashCode(); } @Override public Object clone() { - String pat = this.toPattern(); - DecimalFormatSymbols sym = (DecimalFormatSymbols) this.symbols.clone(); - DecimalFormat newdf = new DecimalFormat(pat, sym); - newdf.setMaximumIntegerDigits(this.getMaximumIntegerDigits()); - newdf.setMaximumFractionDigits(this.getMaximumFractionDigits()); - newdf.setMinimumIntegerDigits(this.getMinimumIntegerDigits()); - newdf.setMinimumFractionDigits(this.getMinimumFractionDigits()); - newdf.setGroupingUsed(this.isGroupingUsed()); - newdf.setGroupingSize(this.getGroupingSize()); - return newdf; + return new DecimalFormat(this); } @Override + protected void finalize() { + NativeDecimalFormat.closeDecimalFormatImpl(this.addr); + } + + /** + * Note: this doesn't check that the underlying native DecimalFormat objects' configured + * native DecimalFormatSymbols objects are equal. It is assumed that the + * caller (java.text.DecimalFormat) will check the java.text.DecimalFormatSymbols objects + * instead, for performance. + * + * This is also unreasonably expensive, calling down to JNI multiple times. + * + * TODO: remove this and just have java.text.DecimalFormat.equals do the right thing itself. + */ + @Override public boolean equals(Object object) { if (object == this) { return true; @@ -89,39 +119,47 @@ public class DecimalFormat extends NumberFormat { return false; } DecimalFormat obj = (DecimalFormat) object; - - if(obj.addr == this.addr) { + if (obj.addr == this.addr) { return true; } + return obj.toPattern().equals(this.toPattern()) && + obj.isDecimalSeparatorAlwaysShown() == this.isDecimalSeparatorAlwaysShown() && + obj.getGroupingSize() == this.getGroupingSize() && + obj.getMultiplier() == this.getMultiplier() && + obj.getNegativePrefix().equals(this.getNegativePrefix()) && + obj.getNegativeSuffix().equals(this.getNegativeSuffix()) && + obj.getPositivePrefix().equals(this.getPositivePrefix()) && + obj.getPositiveSuffix().equals(this.getPositiveSuffix()) && + obj.getMaximumIntegerDigits() == this.getMaximumIntegerDigits() && + obj.getMaximumFractionDigits() == this.getMaximumFractionDigits() && + obj.getMinimumIntegerDigits() == this.getMinimumIntegerDigits() && + obj.getMinimumFractionDigits() == this.getMinimumFractionDigits() && + obj.isGroupingUsed() == this.isGroupingUsed() && + obj.getCurrency() == this.getCurrency(); + } - boolean result = super.equals(object); - - - result &= obj.toPattern().equals(this.toPattern()); - result &= obj.isDecimalSeparatorAlwaysShown() == this.isDecimalSeparatorAlwaysShown(); - result &= obj.getGroupingSize() == this.getGroupingSize(); - result &= obj.getMultiplier() == this.getMultiplier(); - result &= obj.getNegativePrefix().equals(this.getNegativePrefix()); - result &= obj.getNegativeSuffix().equals(this.getNegativeSuffix()); - result &= obj.getPositivePrefix().equals(this.getPositivePrefix()); - result &= obj.getPositiveSuffix().equals(this.getPositiveSuffix()); - result &= obj.getMaximumIntegerDigits() == this.getMaximumIntegerDigits(); - result &= obj.getMaximumFractionDigits() == this.getMaximumFractionDigits(); - result &= obj.getMinimumIntegerDigits() == this.getMinimumIntegerDigits(); - result &= obj.getMinimumFractionDigits() == this.getMinimumFractionDigits(); - result &= obj.isGroupingUsed() == this.isGroupingUsed(); - Currency objCurr = obj.getCurrency(); - Currency thisCurr = this.getCurrency(); - if(objCurr != null) { - result &= objCurr.getCurrencyCode().equals(thisCurr.getCurrencyCode()); - result &= objCurr.getSymbol().equals(thisCurr.getSymbol()); - result &= objCurr.getDefaultFractionDigits() == thisCurr.getDefaultFractionDigits(); - } else { - result &= thisCurr == null; - } - result &= obj.getDecimalFormatSymbols().equals(this.getDecimalFormatSymbols()); + /** + * Copies the java.text.DecimalFormatSymbols' settings into our native peer. + */ + public void setDecimalFormatSymbols(final java.text.DecimalFormatSymbols dfs) { + NativeDecimalFormat.setSymbol(this.addr, UNUM_CURRENCY_SYMBOL, dfs.getCurrencySymbol()); - return result; + NativeDecimalFormat.setSymbol(this.addr, UNUM_DECIMAL_SEPARATOR_SYMBOL, dfs.getDecimalSeparator()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_DIGIT_SYMBOL, dfs.getDigit()); + + char groupingSeparator = dfs.getGroupingSeparator(); + NativeDecimalFormat.setSymbol(this.addr, UNUM_GROUPING_SEPARATOR_SYMBOL, groupingSeparator); + NativeDecimalFormat.setSymbol(this.addr, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, groupingSeparator); + + NativeDecimalFormat.setSymbol(this.addr, UNUM_INFINITY_SYMBOL, dfs.getInfinity()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL, dfs.getInternationalCurrencySymbol()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_MINUS_SIGN_SYMBOL, dfs.getMinusSign()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_MONETARY_SEPARATOR_SYMBOL, dfs.getMonetaryDecimalSeparator()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_NAN_SYMBOL, dfs.getNaN()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_PATTERN_SEPARATOR_SYMBOL, dfs.getPatternSeparator()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_PERCENT_SYMBOL, dfs.getPercent()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_PERMILL_SYMBOL, dfs.getPerMill()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_ZERO_DIGIT_SYMBOL, dfs.getZeroDigit()); } private BigDecimal applyMultiplier(BigDecimal valBigDecimal) { @@ -132,7 +170,6 @@ public class DecimalFormat extends NumberFormat { return valBigDecimal.multiply(multiplierBigDecimal); } - @Override public StringBuffer format(Object value, StringBuffer buffer, FieldPosition field) { if (!(value instanceof Number)) { throw new IllegalArgumentException(); @@ -170,7 +207,6 @@ public class DecimalFormat extends NumberFormat { } } - @Override public StringBuffer format(long value, StringBuffer buffer, FieldPosition field) { if (buffer == null || field == null) { throw new NullPointerException(); @@ -180,7 +216,6 @@ public class DecimalFormat extends NumberFormat { return buffer; } - @Override public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) { if (buffer == null || field == null) { throw new NullPointerException(); @@ -191,30 +226,13 @@ public class DecimalFormat extends NumberFormat { } public void applyLocalizedPattern(String pattern) { - if (pattern == null) { - throw new NullPointerException("pattern was null"); - } - try { - NativeDecimalFormat.applyPatternImpl(this.addr, false, pattern); - } catch(RuntimeException re) { - throw new IllegalArgumentException( - "applying localized pattern failed for pattern: " + pattern, re); - } + NativeDecimalFormat.applyPattern(this.addr, true, pattern); } public void applyPattern(String pattern) { - if (pattern == null) { - throw new NullPointerException("pattern was null"); - } - try { - NativeDecimalFormat.applyPatternImpl(this.addr, false, pattern); - } catch(RuntimeException re) { - throw new IllegalArgumentException( - "applying pattern failed for pattern: " + pattern, re); - } + NativeDecimalFormat.applyPattern(this.addr, false, pattern); } - @Override public AttributedCharacterIterator formatToCharacterIterator(Object object) { if (!(object instanceof Number)) { throw new IllegalArgumentException(); @@ -283,40 +301,38 @@ public class DecimalFormat extends NumberFormat { return NativeDecimalFormat.toPatternImpl(this.addr, false); } - @Override public Number parse(String string, ParsePosition position) { return NativeDecimalFormat.parse(addr, string, position); } // start getter and setter - @Override public int getMaximumFractionDigits() { - return NativeDecimalFormat.getAttribute(this .addr, + return NativeDecimalFormat.getAttribute(this.addr, UNumberFormatAttribute.UNUM_MAX_FRACTION_DIGITS.ordinal()); } - @Override public int getMaximumIntegerDigits() { - return NativeDecimalFormat.getAttribute(this .addr, + return NativeDecimalFormat.getAttribute(this.addr, UNumberFormatAttribute.UNUM_MAX_INTEGER_DIGITS.ordinal()); } - @Override public int getMinimumFractionDigits() { - return NativeDecimalFormat.getAttribute(this .addr, + return NativeDecimalFormat.getAttribute(this.addr, UNumberFormatAttribute.UNUM_MIN_FRACTION_DIGITS.ordinal()); } - @Override public int getMinimumIntegerDigits() { - return NativeDecimalFormat.getAttribute(this .addr, + return NativeDecimalFormat.getAttribute(this.addr, UNumberFormatAttribute.UNUM_MIN_INTEGER_DIGITS.ordinal()); } - @Override public Currency getCurrency() { - return this.symbols.getCurrency(); + String curr = NativeDecimalFormat.getSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL); + if (curr.equals("") || curr.equals("\u00a4\u00a4")) { + return null; + } + return Currency.getInstance(curr); } public int getGroupingSize() { @@ -366,35 +382,25 @@ public class DecimalFormat extends NumberFormat { UNumberFormatAttribute.UNUM_DECIMAL_ALWAYS_SHOWN.ordinal()) != 0; } - @Override public boolean isParseIntegerOnly() { return NativeDecimalFormat.getAttribute(this.addr, UNumberFormatAttribute.UNUM_PARSE_INT_ONLY.ordinal()) != 0; } - @Override public boolean isGroupingUsed() { return NativeDecimalFormat.getAttribute(this.addr, UNumberFormatAttribute.UNUM_GROUPING_USED.ordinal()) != 0; } - public DecimalFormatSymbols getDecimalFormatSymbols() { - return this.symbols; - } - - public void setDecimalFormatSymbols(DecimalFormatSymbols icuSymbols) { - this.symbols = icuSymbols; - } - public void setDecimalSeparatorAlwaysShown(boolean value) { int i = value ? -1 : 0; NativeDecimalFormat.setAttribute(this.addr, UNumberFormatAttribute.UNUM_DECIMAL_ALWAYS_SHOWN.ordinal(), i); } - @Override public void setCurrency(Currency currency) { - this.symbols.setCurrency(currency); + NativeDecimalFormat.setSymbol(this.addr, UNUM_CURRENCY_SYMBOL, currency.getSymbol()); + NativeDecimalFormat.setSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL, currency.getCurrencyCode()); } public void setGroupingSize(int value) { @@ -402,32 +408,27 @@ public class DecimalFormat extends NumberFormat { UNumberFormatAttribute.UNUM_GROUPING_SIZE.ordinal(), value); } - @Override public void setGroupingUsed(boolean value) { int i = value ? -1 : 0; NativeDecimalFormat.setAttribute(this.addr, UNumberFormatAttribute.UNUM_GROUPING_USED.ordinal(), i); } - @Override public void setMaximumFractionDigits(int value) { NativeDecimalFormat.setAttribute(this.addr, UNumberFormatAttribute.UNUM_MAX_FRACTION_DIGITS.ordinal(), value); } - @Override public void setMaximumIntegerDigits(int value) { NativeDecimalFormat.setAttribute(this.addr, UNumberFormatAttribute.UNUM_MAX_INTEGER_DIGITS.ordinal(), value); } - @Override public void setMinimumFractionDigits(int value) { NativeDecimalFormat.setAttribute(this.addr, UNumberFormatAttribute.UNUM_MIN_FRACTION_DIGITS.ordinal(), value); } - @Override public void setMinimumIntegerDigits(int value) { NativeDecimalFormat.setAttribute(this.addr, UNumberFormatAttribute.UNUM_MIN_INTEGER_DIGITS.ordinal(), value); @@ -476,7 +477,6 @@ public class DecimalFormat extends NumberFormat { } } - @Override public void setParseIntegerOnly(boolean value) { int i = value ? -1 : 0; NativeDecimalFormat.setAttribute(this.addr, diff --git a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java b/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java deleted file mode 100644 index 2d5ae02..0000000 --- a/icu/src/main/java/com/ibm/icu4jni/text/DecimalFormatSymbols.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ibm.icu4jni.text; - -import com.ibm.icu4jni.util.LocaleData; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Currency; -import java.util.Locale; -import java.util.ResourceBundle; - -public class DecimalFormatSymbols implements Cloneable { - - // Constants corresponding to the native type UNumberFormatSymbol, for use with getSymbol/setSymbol. - private static final int UNUM_DECIMAL_SEPARATOR_SYMBOL = 0; - private static final int UNUM_GROUPING_SEPARATOR_SYMBOL = 1; - private static final int UNUM_PATTERN_SEPARATOR_SYMBOL = 2; - private static final int UNUM_PERCENT_SYMBOL = 3; - private static final int UNUM_ZERO_DIGIT_SYMBOL = 4; - private static final int UNUM_DIGIT_SYMBOL = 5; - private static final int UNUM_MINUS_SIGN_SYMBOL = 6; - private static final int UNUM_PLUS_SIGN_SYMBOL = 7; - private static final int UNUM_CURRENCY_SYMBOL = 8; - private static final int UNUM_INTL_CURRENCY_SYMBOL = 9; - private static final int UNUM_MONETARY_SEPARATOR_SYMBOL = 10; - private static final int UNUM_EXPONENTIAL_SYMBOL = 11; - private static final int UNUM_PERMILL_SYMBOL = 12; - private static final int UNUM_PAD_ESCAPE_SYMBOL = 13; - private static final int UNUM_INFINITY_SYMBOL = 14; - private static final int UNUM_NAN_SYMBOL = 15; - private static final int UNUM_SIGNIFICANT_DIGIT_SYMBOL = 16; - private static final int UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL = 17; - private static final int UNUM_FORMAT_SYMBOL_COUNT = 18; - - private final int addr; - - // Used to implement clone. - private DecimalFormatSymbols(DecimalFormatSymbols other) { - this.addr = NativeDecimalFormat.cloneImpl(other.addr); - } - - public DecimalFormatSymbols(Locale locale) { - LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale); - this.addr = NativeDecimalFormat.openDecimalFormatImpl(locale.toString(), - localeData.numberPattern); - NativeDecimalFormat.setSymbol(this.addr, UNUM_CURRENCY_SYMBOL, localeData.currencySymbol); - NativeDecimalFormat.setSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL, - localeData.internationalCurrencySymbol); - } - - public DecimalFormatSymbols(Locale locale, java.text.DecimalFormatSymbols symbols) { - LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale); - this.addr = NativeDecimalFormat.openDecimalFormatImpl(locale.toString(), - localeData.numberPattern); - copySymbols(symbols); - } - - /** - * Copies the java.text.DecimalFormatSymbols' settings into this object. - */ - public void copySymbols(final java.text.DecimalFormatSymbols dfs) { - setCurrencySymbol(dfs.getCurrencySymbol()); - setDecimalSeparator(dfs.getDecimalSeparator()); - setDigit(dfs.getDigit()); - setGroupingSeparator(dfs.getGroupingSeparator()); - setInfinity(dfs.getInfinity()); - setInternationalCurrencySymbol(dfs.getInternationalCurrencySymbol()); - setMinusSign(dfs.getMinusSign()); - setMonetaryDecimalSeparator(dfs.getMonetaryDecimalSeparator()); - setNaN(dfs.getNaN()); - setPatternSeparator(dfs.getPatternSeparator()); - setPercent(dfs.getPercent()); - setPerMill(dfs.getPerMill()); - setZeroDigit(dfs.getZeroDigit()); - } - - @Override - public boolean equals(Object object) { - if(object == null) { - return false; - } - if(!(object instanceof DecimalFormatSymbols)) { - return false; - } - - DecimalFormatSymbols sym = (DecimalFormatSymbols) object; - - if(sym.addr == this.addr) { - return true; - } - - boolean result = true; - - Currency objCurr = sym.getCurrency(); - Currency thisCurr = this.getCurrency(); - if(objCurr != null) { - result &= objCurr.getCurrencyCode().equals(thisCurr.getCurrencyCode()); - result &= objCurr.getSymbol().equals(thisCurr.getSymbol()); - result &= objCurr.getDefaultFractionDigits() == thisCurr.getDefaultFractionDigits(); - } else { - result &= thisCurr == null; - } - result &= sym.getCurrencySymbol().equals(this.getCurrencySymbol()); - result &= sym.getDecimalSeparator() == this.getDecimalSeparator(); - result &= sym.getDigit() == this.getDigit(); - result &= sym.getGroupingSeparator() == this.getGroupingSeparator(); - result &= sym.getInfinity().equals(this.getInfinity()); - result &= sym.getInternationalCurrencySymbol().equals( - this.getInternationalCurrencySymbol()); - result &= sym.getMinusSign() == this.getMinusSign(); - result &= sym.getMonetaryDecimalSeparator() == - this.getMonetaryDecimalSeparator(); - result &= sym.getNaN().equals(this.getNaN()); - result &= sym.getPatternSeparator() == this.getPatternSeparator(); - result &= sym.getPercent() == this.getPercent(); - result &= sym.getPerMill() == this.getPerMill(); - result &= sym.getZeroDigit() == this.getZeroDigit(); - - return result; - } - - @Override - public Object clone() { - return new DecimalFormatSymbols(this); - } - - public void setCurrency(Currency currency) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_CURRENCY_SYMBOL, currency.getSymbol()); - NativeDecimalFormat.setSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL, - currency.getCurrencyCode()); - } - - public void setCurrencySymbol(String symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_CURRENCY_SYMBOL, symbol); - } - - public void setDecimalSeparator(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_DECIMAL_SEPARATOR_SYMBOL, symbol); - } - - public void setDigit(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_DIGIT_SYMBOL, symbol); - } - - public void setGroupingSeparator(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_GROUPING_SEPARATOR_SYMBOL, symbol); - NativeDecimalFormat.setSymbol(this.addr, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, symbol); - } - - public void setInfinity(String symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_INFINITY_SYMBOL, symbol); - } - - public void setInternationalCurrencySymbol(String symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL, symbol); - } - - public void setMinusSign(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_MINUS_SIGN_SYMBOL, symbol); - } - - public void setMonetaryDecimalSeparator(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_MONETARY_SEPARATOR_SYMBOL, symbol); - } - - public void setNaN(String symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_NAN_SYMBOL, symbol); - } - - public void setPatternSeparator(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_PATTERN_SEPARATOR_SYMBOL, symbol); - } - - public void setPercent(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_PERCENT_SYMBOL, symbol); - } - - public void setPerMill(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_PERMILL_SYMBOL, symbol); - } - - public void setZeroDigit(char symbol) { - NativeDecimalFormat.setSymbol(this.addr, UNUM_ZERO_DIGIT_SYMBOL, symbol); - } - - public Currency getCurrency() { - String curr = NativeDecimalFormat.getSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL); - if (curr.equals("") || curr.equals("\u00a4\u00a4")) { - return null; - } - return Currency.getInstance(curr); - } - - public String getCurrencySymbol() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_CURRENCY_SYMBOL); - } - - public char getDecimalSeparator() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_DECIMAL_SEPARATOR_SYMBOL).charAt(0); - } - - public char getDigit() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_DIGIT_SYMBOL).charAt(0); - } - - public char getGroupingSeparator() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_GROUPING_SEPARATOR_SYMBOL).charAt(0); - } - - public String getInfinity() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_INFINITY_SYMBOL); - } - - public String getInternationalCurrencySymbol() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL); - } - - public char getMinusSign() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_MINUS_SIGN_SYMBOL).charAt(0); - } - - public char getMonetaryDecimalSeparator() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_MONETARY_SEPARATOR_SYMBOL).charAt(0); - } - - public String getNaN() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_NAN_SYMBOL); - } - - public char getPatternSeparator() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_PATTERN_SEPARATOR_SYMBOL).charAt(0); - } - - public char getPercent() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_PERCENT_SYMBOL).charAt(0); - } - - public char getPerMill() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_PERMILL_SYMBOL).charAt(0); - } - - public char getZeroDigit() { - return NativeDecimalFormat.getSymbol(this.addr, UNUM_ZERO_DIGIT_SYMBOL).charAt(0); - } - - int getAddr() { - return this.addr; - } - - protected void finalize() { - NativeDecimalFormat.closeDecimalFormatImpl(this.addr); - } -} diff --git a/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java b/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java index 88e0d5f..ec07fbd 100644 --- a/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java +++ b/icu/src/main/java/com/ibm/icu4jni/text/NativeDecimalFormat.java @@ -55,15 +55,26 @@ final class NativeDecimalFormat { UNUM_PUBLIC_RULESETS } - static native int openDecimalFormatImpl(String locale, String pattern); + static int openDecimalFormat(String locale, String pattern) { + try { + // FIXME: if we're about to override everything, should we just ask for the cheapest locale (presumably the root locale)? + return NativeDecimalFormat.openDecimalFormatImpl(locale, pattern); + } catch (NullPointerException npe) { + throw npe; + } catch (RuntimeException re) { + throw new IllegalArgumentException("syntax error: " + re.getMessage() + ": " + pattern); + } + } + private static native int openDecimalFormatImpl(String locale, String pattern); static native void closeDecimalFormatImpl(int addr); - static native int cloneImpl(int addr); + static native int cloneDecimalFormatImpl(int addr); static native void setSymbol(int addr, int symbol, String str); static native void setSymbol(int addr, int symbol, char ch); + // FIXME: do we need this any more? the Java-side object should be the canonical source. static native String getSymbol(int addr, int symbol); static native void setAttribute(int addr, int symbol, int i); @@ -74,7 +85,16 @@ final class NativeDecimalFormat { static native String getTextAttribute(int addr, int symbol); - static native void applyPatternImpl(int addr, boolean localized, String pattern); + static void applyPattern(int addr, boolean localized, String pattern) { + try { + NativeDecimalFormat.applyPatternImpl(addr, localized, pattern); + } catch (NullPointerException npe) { + throw npe; + } catch (RuntimeException re) { + throw new IllegalArgumentException("syntax error: " + re.getMessage() + ": " + pattern); + } + } + private static native void applyPatternImpl(int addr, boolean localized, String pattern); static native String toPatternImpl(int addr, boolean localized); |