1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.ibm.icu4jni.text;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughesimport com.ibm.icu4jni.util.LocaleData;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.math.BigDecimal;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.math.BigInteger;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.AttributedCharacterIterator;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.AttributedString;
25eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughesimport java.text.DecimalFormatSymbols;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.FieldPosition;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.Format;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.NumberFormat;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.ParsePosition;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Currency;
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Locale;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
33536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughespublic class NativeDecimalFormat {
3417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    /**
35b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes     * Constants corresponding to the native type UNumberFormatSymbol, for setSymbol.
3617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     */
37eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_DECIMAL_SEPARATOR_SYMBOL = 0;
38eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_GROUPING_SEPARATOR_SYMBOL = 1;
39eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_PATTERN_SEPARATOR_SYMBOL = 2;
40eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_PERCENT_SYMBOL = 3;
41eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_ZERO_DIGIT_SYMBOL = 4;
42eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_DIGIT_SYMBOL = 5;
43eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_MINUS_SIGN_SYMBOL = 6;
44eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_PLUS_SIGN_SYMBOL = 7;
45eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_CURRENCY_SYMBOL = 8;
46eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_INTL_CURRENCY_SYMBOL = 9;
47eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_MONETARY_SEPARATOR_SYMBOL = 10;
48eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_EXPONENTIAL_SYMBOL = 11;
49eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_PERMILL_SYMBOL = 12;
50eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_PAD_ESCAPE_SYMBOL = 13;
51eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_INFINITY_SYMBOL = 14;
52eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_NAN_SYMBOL = 15;
53eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_SIGNIFICANT_DIGIT_SYMBOL = 16;
54eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL = 17;
55eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private static final int UNUM_FORMAT_SYMBOL_COUNT = 18;
56536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes
5717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    /**
5817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * Constants corresponding to the native type UNumberFormatAttribute, for
5917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * getAttribute/setAttribute.
6017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     */
6117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_PARSE_INT_ONLY = 0;
6217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_GROUPING_USED = 1;
6317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_DECIMAL_ALWAYS_SHOWN = 2;
6417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MAX_INTEGER_DIGITS = 3;
6517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MIN_INTEGER_DIGITS = 4;
6617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_INTEGER_DIGITS = 5;
6717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MAX_FRACTION_DIGITS = 6;
6817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MIN_FRACTION_DIGITS = 7;
6917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_FRACTION_DIGITS = 8;
7017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MULTIPLIER = 9;
7117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_GROUPING_SIZE = 10;
7217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_ROUNDING_MODE = 11;
7317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_ROUNDING_INCREMENT = 12;
7417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_FORMAT_WIDTH = 13;
7517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_PADDING_POSITION = 14;
7617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_SECONDARY_GROUPING_SIZE = 15;
7717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_SIGNIFICANT_DIGITS_USED = 16;
7817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MIN_SIGNIFICANT_DIGITS = 17;
7917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_MAX_SIGNIFICANT_DIGITS = 18;
8017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_LENIENT_PARSE = 19;
81536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes
8217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    /**
8317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * Constants corresponding to the native type UNumberFormatTextAttribute, for
8417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * getTextAttribute/setTextAttribute.
8517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     */
8617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_POSITIVE_PREFIX = 0;
8717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_POSITIVE_SUFFIX = 1;
8817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_NEGATIVE_PREFIX = 2;
8917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_NEGATIVE_SUFFIX = 3;
9017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_PADDING_CHARACTER = 4;
9117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_CURRENCY_CODE = 5;
9217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_DEFAULT_RULESET = 6;
9317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static final int UNUM_PUBLIC_RULESETS = 7;
94eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes
9517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    /**
9617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * The address of the ICU DecimalFormat* on the native heap.
9717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     */
98eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    private final int addr;
99eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes
10017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    /**
10117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * The last pattern we gave to ICU, so we can make repeated applications cheap.
10217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * This helps in cases like String.format("%.2f,%.2f\n", x, y) where the DecimalFormat is
10317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes     * reused.
104536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes     */
10517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private String lastPattern;
10617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes
107536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes    // TODO: store all these in DecimalFormat instead!
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean negPrefNull;
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean negSuffNull;
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean posPrefNull;
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean posSuffNull;
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1138330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson    /**
1148330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson     * Cache the BigDecimal form of the multiplier. This is null until we've
115eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     * formatted a BigDecimal (with a multiplier that is not 1), or the user has
1168330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson     * explicitly called {@link #setMultiplier(int)} with any multiplier.
1178330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson     */
11817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private BigDecimal multiplierBigDecimal = null;
1198330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson
120b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes    public NativeDecimalFormat(String pattern, DecimalFormatSymbols dfs) {
121b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes        try {
122b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            this.addr = openDecimalFormatImpl(pattern, dfs.getCurrencySymbol(),
123b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes                    dfs.getDecimalSeparator(), dfs.getDigit(), dfs.getGroupingSeparator(),
124b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes                    dfs.getInfinity(), dfs.getInternationalCurrencySymbol(), dfs.getMinusSign(),
125b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes                    dfs.getMonetaryDecimalSeparator(), dfs.getNaN(), dfs.getPatternSeparator(),
126b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes                    dfs.getPercent(), dfs.getPerMill(), dfs.getZeroDigit());
127b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            this.lastPattern = pattern;
128b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes        } catch (NullPointerException npe) {
129b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            throw npe;
130b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes        } catch (RuntimeException re) {
131b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            throw new IllegalArgumentException("syntax error: " + re.getMessage() + ": " + pattern);
132b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes        }
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
135eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    // Used to implement clone.
136536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes    private NativeDecimalFormat(NativeDecimalFormat other) {
13717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        this.addr = cloneDecimalFormatImpl(other.addr);
13817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        this.lastPattern = other.lastPattern;
139eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        this.negPrefNull = other.negPrefNull;
140eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        this.negSuffNull = other.negSuffNull;
141eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        this.posPrefNull = other.posPrefNull;
142eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        this.posSuffNull = other.posSuffNull;
143eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    }
144eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes
145536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes    // TODO: remove this and just have DecimalFormat.hashCode do the right thing itself.
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int hashCode() {
148eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        return this.getPositivePrefix().hashCode();
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Object clone() {
153536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes        return new NativeDecimalFormat(this);
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
157eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    protected void finalize() {
15817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        closeDecimalFormatImpl(this.addr);
159eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    }
160eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes
161eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    /**
162eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     * Note: this doesn't check that the underlying native DecimalFormat objects' configured
163eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     * native DecimalFormatSymbols objects are equal. It is assumed that the
164536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes     * caller (DecimalFormat) will check the DecimalFormatSymbols objects
165eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     * instead, for performance.
166eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     *
167eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     * This is also unreasonably expensive, calling down to JNI multiple times.
168eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     *
169536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes     * TODO: remove this and just have DecimalFormat.equals do the right thing itself.
170eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     */
171eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    @Override
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean equals(Object object) {
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (object == this) {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
176536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes        if (!(object instanceof NativeDecimalFormat)) {
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
179536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes        NativeDecimalFormat obj = (NativeDecimalFormat) object;
180eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        if (obj.addr == this.addr) {
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
183eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes        return obj.toPattern().equals(this.toPattern()) &&
184eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.isDecimalSeparatorAlwaysShown() == this.isDecimalSeparatorAlwaysShown() &&
185eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getGroupingSize() == this.getGroupingSize() &&
186eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getMultiplier() == this.getMultiplier() &&
187eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getNegativePrefix().equals(this.getNegativePrefix()) &&
188eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getNegativeSuffix().equals(this.getNegativeSuffix()) &&
189eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getPositivePrefix().equals(this.getPositivePrefix()) &&
190eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getPositiveSuffix().equals(this.getPositiveSuffix()) &&
191eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getMaximumIntegerDigits() == this.getMaximumIntegerDigits() &&
192eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getMaximumFractionDigits() == this.getMaximumFractionDigits() &&
193eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getMinimumIntegerDigits() == this.getMinimumIntegerDigits() &&
194eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes                obj.getMinimumFractionDigits() == this.getMinimumFractionDigits() &&
195b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes                obj.isGroupingUsed() == this.isGroupingUsed();
196eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    }
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
198eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes    /**
19961da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes     * Copies the DecimalFormatSymbols settings into our native peer in bulk.
200eb5822b70b3e578dbe692a60b8a93b90a9d4df93Elliott Hughes     */
201536a964538d43749cfb88b3023bc4f8c31588b9aElliott Hughes    public void setDecimalFormatSymbols(final DecimalFormatSymbols dfs) {
20261da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes        setDecimalFormatSymbols(this.addr, dfs.getCurrencySymbol(), dfs.getDecimalSeparator(),
20361da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes                dfs.getDigit(), dfs.getGroupingSeparator(), dfs.getInfinity(),
20461da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes                dfs.getInternationalCurrencySymbol(), dfs.getMinusSign(),
20561da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes                dfs.getMonetaryDecimalSeparator(), dfs.getNaN(), dfs.getPatternSeparator(),
20661da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes                dfs.getPercent(), dfs.getPerMill(), dfs.getZeroDigit());
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2098330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson    private BigDecimal applyMultiplier(BigDecimal valBigDecimal) {
2108330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson       if (multiplierBigDecimal == null) {
2118330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson           multiplierBigDecimal = BigDecimal.valueOf(getMultiplier());
2128330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson       }
2138330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson       // Get new value by multiplying multiplier.
2148330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson       return valBigDecimal.multiply(multiplierBigDecimal);
2158330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson    }
216fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes
217fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes    public StringBuffer formatBigDecimal(BigDecimal value, StringBuffer buffer, FieldPosition field) {
218fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        if (buffer == null || field == null) {
219fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes            throw new NullPointerException();
220fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        }
221fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        if (getMultiplier() != 1) {
222fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes            value = applyMultiplier(value);
223fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        }
224fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        StringBuilder val = new StringBuilder();
225fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        val.append(value.unscaledValue().toString(10));
226fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        int scale = value.scale();
227fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        scale = makeScalePositive(scale, val);
228fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        String fieldType = getFieldType(field.getFieldAttribute());
229fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        String result = format(this.addr, val.toString(), field, fieldType, null, scale);
230fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        return buffer.append(result);
231fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes    }
232fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes
233fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes    public StringBuffer formatBigInteger(BigInteger value, StringBuffer buffer, FieldPosition field) {
234fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        if (buffer == null || field == null) {
235fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes            throw new NullPointerException();
236fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        }
237fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        String fieldType = getFieldType(field.getFieldAttribute());
238fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        String result = format(this.addr, value.toString(10), field, fieldType, null, 0);
239fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes        return buffer.append(result);
240fc7f3e4e4e169f08577a37fbe02cc2a80fba77d2Elliott Hughes    }
241ef05746e0c699a79ff2084861c346c09f1208b75Elliott Hughes
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public StringBuffer format(long value, StringBuffer buffer, FieldPosition field) {
243c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes        if (buffer == null || field == null) {
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String fieldType = getFieldType(field.getFieldAttribute());
24717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        buffer.append(format(this.addr, value, field, fieldType, null));
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return buffer;
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public StringBuffer format(double value, StringBuffer buffer, FieldPosition field) {
252c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes        if (buffer == null || field == null) {
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String fieldType = getFieldType(field.getFieldAttribute());
25617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        buffer.append(format(this.addr, value, field, fieldType, null));
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return buffer;
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void applyLocalizedPattern(String pattern) {
26117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        applyPattern(this.addr, true, pattern);
26217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        lastPattern = null;
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void applyPattern(String pattern) {
26617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        if (lastPattern != null && pattern.equals(lastPattern)) {
26717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            return;
26817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        }
26917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        applyPattern(this.addr, false, pattern);
27017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        lastPattern = pattern;
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public AttributedCharacterIterator formatToCharacterIterator(Object object) {
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!(object instanceof Number)) {
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException();
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Number number = (Number) object;
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String text = null;
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuffer attributes = new StringBuffer();
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(number instanceof BigInteger) {
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BigInteger valBigInteger = (BigInteger) number;
28317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            text = format(this.addr, valBigInteger.toString(10), null, null, attributes, 0);
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if(number instanceof BigDecimal) {
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BigDecimal valBigDecimal = (BigDecimal) number;
2868330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson            if (getMultiplier() != 1) {
2878330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson                valBigDecimal = applyMultiplier(valBigDecimal);
2888330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson            }
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            StringBuilder val = new StringBuilder();
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            val.append(valBigDecimal.unscaledValue().toString(10));
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int scale = valBigDecimal.scale();
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            scale = makeScalePositive(scale, val);
29317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            text = format(this.addr, val.toString(), null, null, attributes, scale);
2947393a171801ac6247a50c7610012d77ef84ed433Elliott Hughes        } else if (number instanceof Double || number instanceof Float) {
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            double dv = number.doubleValue();
29617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            text = format(this.addr, dv, null, null, attributes);
2977393a171801ac6247a50c7610012d77ef84ed433Elliott Hughes        } else {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            long lv = number.longValue();
29917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            text = format(this.addr, lv, null, null, attributes);
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3027393a171801ac6247a50c7610012d77ef84ed433Elliott Hughes        AttributedString as = new AttributedString(text);
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] attrs = attributes.toString().split(";");
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // add NumberFormat field attributes to the AttributedString
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int size = attrs.length / 3;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(size * 3 != attrs.length) {
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return as.getIterator();
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < size; i++) {
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Format.Field attribute = getField(attrs[3*i]);
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            as.addAttribute(attribute, attribute, Integer.parseInt(attrs[3*i+1]),
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Integer.parseInt(attrs[3*i+2]));
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // return the CharacterIterator from AttributedString
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return as.getIterator();
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int makeScalePositive(int scale, StringBuilder val) {
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (scale < 0) {
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            scale = -scale;
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = scale; i > 0; i--) {
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                val.append('0');
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            scale = 0;
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return scale;
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toLocalizedPattern() {
33217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return toPatternImpl(this.addr, true);
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toPattern() {
33617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return toPatternImpl(this.addr, false);
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Number parse(String string, ParsePosition position) {
34017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return parse(addr, string, position);
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // start getter and setter
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMaximumFractionDigits() {
34617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_MAX_FRACTION_DIGITS);
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMaximumIntegerDigits() {
35017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_MAX_INTEGER_DIGITS);
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMinimumFractionDigits() {
35417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_MIN_FRACTION_DIGITS);
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMinimumIntegerDigits() {
35817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_MIN_INTEGER_DIGITS);
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getGroupingSize() {
36217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_GROUPING_SIZE);
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int getMultiplier() {
36617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_MULTIPLIER);
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getNegativePrefix() {
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (negPrefNull) {
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
37317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getTextAttribute(this.addr, UNUM_NEGATIVE_PREFIX);
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getNegativeSuffix() {
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (negSuffNull) {
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
38017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getTextAttribute(this.addr, UNUM_NEGATIVE_SUFFIX);
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getPositivePrefix() {
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (posPrefNull) {
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
38717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getTextAttribute(this.addr, UNUM_POSITIVE_PREFIX);
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getPositiveSuffix() {
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (posSuffNull) {
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
39417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getTextAttribute(this.addr, UNUM_POSITIVE_SUFFIX);
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isDecimalSeparatorAlwaysShown() {
39817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_DECIMAL_ALWAYS_SHOWN) != 0;
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isParseIntegerOnly() {
40217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_PARSE_INT_ONLY) != 0;
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isGroupingUsed() {
40617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        return getAttribute(this.addr, UNUM_GROUPING_USED) != 0;
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setDecimalSeparatorAlwaysShown(boolean value) {
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = value ? -1 : 0;
41117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_DECIMAL_ALWAYS_SHOWN, i);
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setCurrency(Currency currency) {
41517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setSymbol(this.addr, UNUM_CURRENCY_SYMBOL, currency.getSymbol());
41617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setSymbol(this.addr, UNUM_INTL_CURRENCY_SYMBOL, currency.getCurrencyCode());
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setGroupingSize(int value) {
42017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_GROUPING_SIZE, value);
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setGroupingUsed(boolean value) {
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = value ? -1 : 0;
42517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_GROUPING_USED, i);
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setMaximumFractionDigits(int value) {
42917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_MAX_FRACTION_DIGITS, value);
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setMaximumIntegerDigits(int value) {
43317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_MAX_INTEGER_DIGITS, value);
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setMinimumFractionDigits(int value) {
43717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_MIN_FRACTION_DIGITS, value);
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setMinimumIntegerDigits(int value) {
44117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_MIN_INTEGER_DIGITS, value);
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setMultiplier(int value) {
44517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_MULTIPLIER, value);
4468330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson        // Update the cached BigDecimal for multiplier.
4478330d9de4ab714e0f1b50298757e2c691c8ece8bJesse Wilson        multiplierBigDecimal = BigDecimal.valueOf(value);
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setNegativePrefix(String value) {
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        negPrefNull = value == null;
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!negPrefNull) {
45317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            setTextAttribute(this.addr, UNUM_NEGATIVE_PREFIX, value);
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setNegativeSuffix(String value) {
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        negSuffNull = value == null;
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!negSuffNull) {
46017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            setTextAttribute(this.addr, UNUM_NEGATIVE_SUFFIX, value);
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setPositivePrefix(String value) {
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        posPrefNull = value == null;
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!posPrefNull) {
46717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            setTextAttribute(this.addr, UNUM_POSITIVE_PREFIX, value);
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setPositiveSuffix(String value) {
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        posSuffNull = value == null;
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!posSuffNull) {
47417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            setTextAttribute(this.addr, UNUM_POSITIVE_SUFFIX, value);
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setParseIntegerOnly(boolean value) {
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int i = value ? -1 : 0;
48017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        setAttribute(this.addr, UNUM_PARSE_INT_ONLY, i);
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static protected String getFieldType(Format.Field field) {
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field == null) {
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.SIGN)) {
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "sign";
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.INTEGER)) {
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "integer";
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.FRACTION)) {
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "fraction";
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.EXPONENT)) {
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "exponent";
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.EXPONENT_SIGN)) {
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "exponent_sign";
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.EXPONENT_SYMBOL)) {
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "exponent_symbol";
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.CURRENCY)) {
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "currency";
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.GROUPING_SEPARATOR)) {
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "grouping_separator";
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.DECIMAL_SEPARATOR)) {
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "decimal_separator";
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.PERCENT)) {
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "percent";
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(field.equals(NumberFormat.Field.PERMILLE)) {
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return "permille";
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected Format.Field getField(String type) {
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("")) {
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("sign")) {
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.SIGN;
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("integer")) {
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.INTEGER;
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("fraction")) {
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.FRACTION;
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("exponent")) {
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.EXPONENT;
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("exponent_sign")) {
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.EXPONENT_SIGN;
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("exponent_symbol")) {
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.EXPONENT_SYMBOL;
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("currency")) {
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.CURRENCY;
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("grouping_separator")) {
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.GROUPING_SEPARATOR;
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("decimal_separator")) {
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.DECIMAL_SEPARATOR;
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("percent")) {
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.PERCENT;
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(type.equals("permille")) {
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return NumberFormat.Field.PERMILLE;
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
56217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes
56317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static void applyPattern(int addr, boolean localized, String pattern) {
56417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        try {
56517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            applyPatternImpl(addr, localized, pattern);
56617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        } catch (NullPointerException npe) {
56717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            throw npe;
56817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        } catch (RuntimeException re) {
56917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes            throw new IllegalArgumentException("syntax error: " + re.getMessage() + ": " + pattern);
57017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes        }
57117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    }
57217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes
57317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native void applyPatternImpl(int addr, boolean localized, String pattern);
57417c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native int cloneDecimalFormatImpl(int addr);
57517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native void closeDecimalFormatImpl(int addr);
57617c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native String format(int addr, long value, FieldPosition position, String fieldType, StringBuffer attributes);
57717c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native String format(int addr, double value, FieldPosition position, String fieldType, StringBuffer attributes);
57817c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native String format(int addr, String value, FieldPosition position, String fieldType, StringBuffer attributes, int scale);
57917c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native int getAttribute(int addr, int symbol);
58017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native String getTextAttribute(int addr, int symbol);
581b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes    private static native int openDecimalFormatImpl(String pattern, String currencySymbol,
582b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            char decimalSeparator, char digit, char groupingSeparator, String infinity,
583b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            String internationalCurrencySymbol, char minusSign, char monetaryDecimalSeparator,
584b7df12f1bb73889f354806213b218a3a7d986448Elliott Hughes            String nan, char patternSeparator, char percent, char perMill, char zeroDigit);
58517c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native Number parse(int addr, String string, ParsePosition position);
58661da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes    private static native void setDecimalFormatSymbols(int addr, String currencySymbol,
58761da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes            char decimalSeparator, char digit, char groupingSeparator, String infinity,
58861da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes            String internationalCurrencySymbol, char minusSign, char monetaryDecimalSeparator,
58961da38c3b2bd80b1863a3788b1a7ffdd730fd70fElliott Hughes            String nan, char patternSeparator, char percent, char perMill, char zeroDigit);
59017c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native void setSymbol(int addr, int symbol, String str);
59117c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native void setAttribute(int addr, int symbol, int i);
59217c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native void setTextAttribute(int addr, int symbol, String str);
59317c4196ef6904c7770455ff68f3b54e3dfbc6ad7Elliott Hughes    private static native String toPatternImpl(int addr, boolean localized);
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
595