1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27/*
28 * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
29 * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
30 *
31 *   The original version of this source code and documentation is copyrighted
32 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
33 * materials are provided under terms of a License Agreement between Taligent
34 * and Sun. This technology is protected by multiple US and International
35 * patents. This notice and attribution to Taligent may not be removed.
36 *   Taligent is a registered trademark of Taligent, Inc.
37 *
38 */
39
40package java.text;
41
42import java.io.IOException;
43import java.io.ObjectInputStream;
44import java.io.ObjectOutputStream;
45import java.io.ObjectStreamField;
46import java.math.BigDecimal;
47import java.math.BigInteger;
48import java.math.RoundingMode;
49import java.util.Currency;
50import java.util.Locale;
51import java.util.Objects;
52import java.util.concurrent.ConcurrentHashMap;
53import java.util.concurrent.ConcurrentMap;
54import java.util.concurrent.atomic.AtomicInteger;
55import java.util.concurrent.atomic.AtomicLong;
56import libcore.icu.LocaleData;
57
58import android.icu.math.MathContext;
59
60/**
61 * <code>DecimalFormat</code> is a concrete subclass of
62 * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
63 * features designed to make it possible to parse and format numbers in any
64 * locale, including support for Western, Arabic, and Indic digits.  It also
65 * supports different kinds of numbers, including integers (123), fixed-point
66 * numbers (123.4), scientific notation (1.23E4), percentages (12%), and
67 * currency amounts ($123).  All of these can be localized.
68 *
69 * <p>To obtain a <code>NumberFormat</code> for a specific locale, including the
70 * default locale, call one of <code>NumberFormat</code>'s factory methods, such
71 * as <code>getInstance()</code>.  In general, do not call the
72 * <code>DecimalFormat</code> constructors directly, since the
73 * <code>NumberFormat</code> factory methods may return subclasses other than
74 * <code>DecimalFormat</code>. If you need to customize the format object, do
75 * something like this:
76 *
77 * <blockquote><pre>
78 * NumberFormat f = NumberFormat.getInstance(loc);
79 * if (f instanceof DecimalFormat) {
80 *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
81 * }
82 * </pre></blockquote>
83 *
84 * <p>A <code>DecimalFormat</code> comprises a <em>pattern</em> and a set of
85 * <em>symbols</em>.  The pattern may be set directly using
86 * <code>applyPattern()</code>, or indirectly using the API methods.  The
87 * symbols are stored in a <code>DecimalFormatSymbols</code> object.  When using
88 * the <code>NumberFormat</code> factory methods, the pattern and symbols are
89 * read from localized <code>ResourceBundle</code>s.
90 *
91 * <h3>Patterns</h3>
92 *
93 * <code>DecimalFormat</code> patterns have the following syntax:
94 * <blockquote><pre>
95 * <i>Pattern:</i>
96 *         <i>PositivePattern</i>
97 *         <i>PositivePattern</i> ; <i>NegativePattern</i>
98 * <i>PositivePattern:</i>
99 *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
100 * <i>NegativePattern:</i>
101 *         <i>Prefix<sub>opt</sub></i> <i>Number</i> <i>Suffix<sub>opt</sub></i>
102 * <i>Prefix:</i>
103 *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
104 * <i>Suffix:</i>
105 *         any Unicode characters except &#92;uFFFE, &#92;uFFFF, and special characters
106 * <i>Number:</i>
107 *         <i>Integer</i> <i>Exponent<sub>opt</sub></i>
108 *         <i>Integer</i> . <i>Fraction</i> <i>Exponent<sub>opt</sub></i>
109 * <i>Integer:</i>
110 *         <i>MinimumInteger</i>
111 *         #
112 *         # <i>Integer</i>
113 *         # , <i>Integer</i>
114 * <i>MinimumInteger:</i>
115 *         0
116 *         0 <i>MinimumInteger</i>
117 *         0 , <i>MinimumInteger</i>
118 * <i>Fraction:</i>
119 *         <i>MinimumFraction<sub>opt</sub></i> <i>OptionalFraction<sub>opt</sub></i>
120 * <i>MinimumFraction:</i>
121 *         0 <i>MinimumFraction<sub>opt</sub></i>
122 * <i>OptionalFraction:</i>
123 *         # <i>OptionalFraction<sub>opt</sub></i>
124 * <i>Exponent:</i>
125 *         E <i>MinimumExponent</i>
126 * <i>MinimumExponent:</i>
127 *         0 <i>MinimumExponent<sub>opt</sub></i>
128 * </pre></blockquote>
129 *
130 * <p>A <code>DecimalFormat</code> pattern contains a positive and negative
131 * subpattern, for example, <code>"#,##0.00;(#,##0.00)"</code>.  Each
132 * subpattern has a prefix, numeric part, and suffix. The negative subpattern
133 * is optional; if absent, then the positive subpattern prefixed with the
134 * localized minus sign (<code>'-'</code> in most locales) is used as the
135 * negative subpattern. That is, <code>"0.00"</code> alone is equivalent to
136 * <code>"0.00;-0.00"</code>.  If there is an explicit negative subpattern, it
137 * serves only to specify the negative prefix and suffix; the number of digits,
138 * minimal digits, and other characteristics are all the same as the positive
139 * pattern. That means that <code>"#,##0.0#;(#)"</code> produces precisely
140 * the same behavior as <code>"#,##0.0#;(#,##0.0#)"</code>.
141 *
142 * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
143 * thousands separators, decimal separators, etc. may be set to arbitrary
144 * values, and they will appear properly during formatting.  However, care must
145 * be taken that the symbols and strings do not conflict, or parsing will be
146 * unreliable.  For example, either the positive and negative prefixes or the
147 * suffixes must be distinct for <code>DecimalFormat.parse()</code> to be able
148 * to distinguish positive from negative values.  (If they are identical, then
149 * <code>DecimalFormat</code> will behave as if no negative subpattern was
150 * specified.)  Another example is that the decimal separator and thousands
151 * separator should be distinct characters, or parsing will be impossible.
152 *
153 * <p>The grouping separator is commonly used for thousands, but in some
154 * countries it separates ten-thousands. The grouping size is a constant number
155 * of digits between the grouping characters, such as 3 for 100,000,000 or 4 for
156 * 1,0000,0000.  If you supply a pattern with multiple grouping characters, the
157 * interval between the last one and the end of the integer is the one that is
158 * used. So <code>"#,##,###,####"</code> == <code>"######,####"</code> ==
159 * <code>"##,####,####"</code>.
160 *
161 * <h4>Special Pattern Characters</h4>
162 *
163 * <p>Many characters in a pattern are taken literally; they are matched during
164 * parsing and output unchanged during formatting.  Special characters, on the
165 * other hand, stand for other characters, strings, or classes of characters.
166 * They must be quoted, unless noted otherwise, if they are to appear in the
167 * prefix or suffix as literals.
168 *
169 * <p>The characters listed here are used in non-localized patterns.  Localized
170 * patterns use the corresponding characters taken from this formatter's
171 * <code>DecimalFormatSymbols</code> object instead, and these characters lose
172 * their special status.  Two exceptions are the currency sign and quote, which
173 * are not localized.
174 *
175 * <blockquote>
176 * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
177 *  location, localized, and meaning.">
178 *     <tr style="background-color: rgb(204, 204, 255);">
179 *          <th align=left>Symbol
180 *          <th align=left>Location
181 *          <th align=left>Localized?
182 *          <th align=left>Meaning
183 *     <tr valign=top>
184 *          <td><code>0</code>
185 *          <td>Number
186 *          <td>Yes
187 *          <td>Digit
188 *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
189 *          <td><code>#</code>
190 *          <td>Number
191 *          <td>Yes
192 *          <td>Digit, zero shows as absent
193 *     <tr valign=top>
194 *          <td><code>.</code>
195 *          <td>Number
196 *          <td>Yes
197 *          <td>Decimal separator or monetary decimal separator
198 *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
199 *          <td><code>-</code>
200 *          <td>Number
201 *          <td>Yes
202 *          <td>Minus sign
203 *     <tr valign=top>
204 *          <td><code>,</code>
205 *          <td>Number
206 *          <td>Yes
207 *          <td>Grouping separator
208 *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
209 *          <td><code>E</code>
210 *          <td>Number
211 *          <td>Yes
212 *          <td>Separates mantissa and exponent in scientific notation.
213 *              <em>Need not be quoted in prefix or suffix.</em>
214 *     <tr valign=top>
215 *          <td><code>;</code>
216 *          <td>Subpattern boundary
217 *          <td>Yes
218 *          <td>Separates positive and negative subpatterns
219 *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
220 *          <td><code>%</code>
221 *          <td>Prefix or suffix
222 *          <td>Yes
223 *          <td>Multiply by 100 and show as percentage
224 *     <tr valign=top>
225 *          <td><code>&#92;u2030</code>
226 *          <td>Prefix or suffix
227 *          <td>Yes
228 *          <td>Multiply by 1000 and show as per mille value
229 *     <tr style="vertical-align: top; background-color: rgb(238, 238, 255);">
230 *          <td><code>&#164;</code> (<code>&#92;u00A4</code>)
231 *          <td>Prefix or suffix
232 *          <td>No
233 *          <td>Currency sign, replaced by currency symbol.  If
234 *              doubled, replaced by international currency symbol.
235 *              If present in a pattern, the monetary decimal separator
236 *              is used instead of the decimal separator.
237 *     <tr valign=top>
238 *          <td><code>'</code>
239 *          <td>Prefix or suffix
240 *          <td>No
241 *          <td>Used to quote special characters in a prefix or suffix,
242 *              for example, <code>"'#'#"</code> formats 123 to
243 *              <code>"#123"</code>.  To create a single quote
244 *              itself, use two in a row: <code>"# o''clock"</code>.
245 * </table>
246 * </blockquote>
247 *
248 * <h4>Scientific Notation</h4>
249 *
250 * <p>Numbers in scientific notation are expressed as the product of a mantissa
251 * and a power of ten, for example, 1234 can be expressed as 1.234 x 10^3.  The
252 * mantissa is often in the range 1.0 &le; x {@literal <} 10.0, but it need not
253 * be.
254 * <code>DecimalFormat</code> can be instructed to format and parse scientific
255 * notation <em>only via a pattern</em>; there is currently no factory method
256 * that creates a scientific notation format.  In a pattern, the exponent
257 * character immediately followed by one or more digit characters indicates
258 * scientific notation.  Example: <code>"0.###E0"</code> formats the number
259 * 1234 as <code>"1.234E3"</code>.
260 *
261 * <ul>
262 * <li>The number of digit characters after the exponent character gives the
263 * minimum exponent digit count.  There is no maximum.  Negative exponents are
264 * formatted using the localized minus sign, <em>not</em> the prefix and suffix
265 * from the pattern.  This allows patterns such as <code>"0.###E0 m/s"</code>.
266 *
267 * <li>The minimum and maximum number of integer digits are interpreted
268 * together:
269 *
270 * <ul>
271 * <li>If the maximum number of integer digits is greater than their minimum number
272 * and greater than 1, it forces the exponent to be a multiple of the maximum
273 * number of integer digits, and the minimum number of integer digits to be
274 * interpreted as 1.  The most common use of this is to generate
275 * <em>engineering notation</em>, in which the exponent is a multiple of three,
276 * e.g., <code>"##0.#####E0"</code>. Using this pattern, the number 12345
277 * formats to <code>"12.345E3"</code>, and 123456 formats to
278 * <code>"123.456E3"</code>.
279 *
280 * <li>Otherwise, the minimum number of integer digits is achieved by adjusting the
281 * exponent.  Example: 0.00123 formatted with <code>"00.###E0"</code> yields
282 * <code>"12.3E-4"</code>.
283 * </ul>
284 *
285 * <li>The number of significant digits in the mantissa is the sum of the
286 * <em>minimum integer</em> and <em>maximum fraction</em> digits, and is
287 * unaffected by the maximum integer digits.  For example, 12345 formatted with
288 * <code>"##0.##E0"</code> is <code>"12.3E3"</code>. To show all digits, set
289 * the significant digits count to zero.  The number of significant digits
290 * does not affect parsing.
291 *
292 * <li>Exponential patterns may not contain grouping separators.
293 * </ul>
294 *
295 * <h4>Rounding</h4>
296 *
297 * <code>DecimalFormat</code> provides rounding modes defined in
298 * {@link java.math.RoundingMode} for formatting.  By default, it uses
299 * {@link java.math.RoundingMode#HALF_EVEN RoundingMode.HALF_EVEN}.
300 *
301 * <h4>Digits</h4>
302 *
303 * For formatting, <code>DecimalFormat</code> uses the ten consecutive
304 * characters starting with the localized zero digit defined in the
305 * <code>DecimalFormatSymbols</code> object as digits. For parsing, these
306 * digits as well as all Unicode decimal digits, as defined by
307 * {@link Character#digit Character.digit}, are recognized.
308 *
309 * <h4>Special Values</h4>
310 *
311 * <p><code>NaN</code> is formatted as a string, which typically has a single character
312 * <code>&#92;uFFFD</code>.  This string is determined by the
313 * <code>DecimalFormatSymbols</code> object.  This is the only value for which
314 * the prefixes and suffixes are not used.
315 *
316 * <p>Infinity is formatted as a string, which typically has a single character
317 * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
318 * applied.  The infinity string is determined by the
319 * <code>DecimalFormatSymbols</code> object.
320 *
321 * <p>Negative zero (<code>"-0"</code>) parses to
322 * <ul>
323 * <li><code>BigDecimal(0)</code> if <code>isParseBigDecimal()</code> is
324 * true,
325 * <li><code>Long(0)</code> if <code>isParseBigDecimal()</code> is false
326 *     and <code>isParseIntegerOnly()</code> is true,
327 * <li><code>Double(-0.0)</code> if both <code>isParseBigDecimal()</code>
328 * and <code>isParseIntegerOnly()</code> are false.
329 * </ul>
330 *
331 * <h4><a name="synchronization">Synchronization</a></h4>
332 *
333 * <p>
334 * Decimal formats are generally not synchronized.
335 * It is recommended to create separate format instances for each thread.
336 * If multiple threads access a format concurrently, it must be synchronized
337 * externally.
338 *
339 * <h4>Example</h4>
340 *
341 * <blockquote><pre>{@code
342 * <strong>// Print out a number using the localized number, integer, currency,
343 * // and percent format for each locale</strong>
344 * Locale[] locales = NumberFormat.getAvailableLocales();
345 * double myNumber = -1234.56;
346 * NumberFormat form;
347 * for (int j = 0; j < 4; ++j) {
348 *     System.out.println("FORMAT");
349 *     for (int i = 0; i < locales.length; ++i) {
350 *         if (locales[i].getCountry().length() == 0) {
351 *            continue; // Skip language-only locales
352 *         }
353 *         System.out.print(locales[i].getDisplayName());
354 *         switch (j) {
355 *         case 0:
356 *             form = NumberFormat.getInstance(locales[i]); break;
357 *         case 1:
358 *             form = NumberFormat.getIntegerInstance(locales[i]); break;
359 *         case 2:
360 *             form = NumberFormat.getCurrencyInstance(locales[i]); break;
361 *         default:
362 *             form = NumberFormat.getPercentInstance(locales[i]); break;
363 *         }
364 *         if (form instanceof DecimalFormat) {
365 *             System.out.print(": " + ((DecimalFormat) form).toPattern());
366 *         }
367 *         System.out.print(" -> " + form.format(myNumber));
368 *         try {
369 *             System.out.println(" -> " + form.parse(form.format(myNumber)));
370 *         } catch (ParseException e) {}
371 *     }
372 * }
373 * }</pre></blockquote>
374 *
375 * @see          <a href="https://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html">Java Tutorial</a>
376 * @see          NumberFormat
377 * @see          DecimalFormatSymbols
378 * @see          ParsePosition
379 * @author       Mark Davis
380 * @author       Alan Liu
381 */
382public class DecimalFormat extends NumberFormat {
383
384    // Android-note: This class is heavily modified from upstream OpenJDK.
385    // Android's version delegates most of its work to android.icu.text.DecimalFormat. This is done
386    // to avoid code duplication and to stay compatible with earlier releases that used ICU4C/ICU4J
387    // to implement DecimalFormat.
388
389    // Android-added: ICU DecimalFormat to delegate to.
390    // TODO(b/68143370): switch back to ICU DecimalFormat once it can reproduce ICU 58 behavior.
391    private transient android.icu.text.DecimalFormat_ICU58_Android icuDecimalFormat;
392
393    /**
394     * Creates a DecimalFormat using the default pattern and symbols
395     * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
396     * This is a convenient way to obtain a
397     * DecimalFormat when internationalization is not the main concern.
398     * <p>
399     * To obtain standard formats for a given locale, use the factory methods
400     * on NumberFormat such as getNumberInstance. These factories will
401     * return the most appropriate sub-class of NumberFormat for a given
402     * locale.
403     *
404     * @see java.text.NumberFormat#getInstance
405     * @see java.text.NumberFormat#getNumberInstance
406     * @see java.text.NumberFormat#getCurrencyInstance
407     * @see java.text.NumberFormat#getPercentInstance
408     */
409    public DecimalFormat() {
410        // Get the pattern for the default locale.
411        Locale def = Locale.getDefault(Locale.Category.FORMAT);
412        // BEGIN Android-changed: Use ICU LocaleData. Remove SPI LocaleProviderAdapter.
413        /*
414        LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(NumberFormatProvider.class, def);
415        if (!(adapter instanceof ResourceBundleBasedAdapter)) {
416            adapter = LocaleProviderAdapter.getResourceBundleBased();
417        }
418        String[] all = adapter.getLocaleResources(def).getNumberPatterns();
419        */
420        String pattern = LocaleData.get(def).numberPattern;
421        // END Android-changed: Use ICU LocaleData. Remove SPI LocaleProviderAdapter.
422
423        // Always applyPattern after the symbols are set
424        this.symbols = DecimalFormatSymbols.getInstance(def);
425        // Android-changed: use initPattern() instead of removed applyPattern(String, boolean).
426        // applyPattern(all[0], false);
427        initPattern(pattern);
428    }
429
430
431    /**
432     * Creates a DecimalFormat using the given pattern and the symbols
433     * for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
434     * This is a convenient way to obtain a
435     * DecimalFormat when internationalization is not the main concern.
436     * <p>
437     * To obtain standard formats for a given locale, use the factory methods
438     * on NumberFormat such as getNumberInstance. These factories will
439     * return the most appropriate sub-class of NumberFormat for a given
440     * locale.
441     *
442     * @param pattern a non-localized pattern string.
443     * @exception NullPointerException if <code>pattern</code> is null
444     * @exception IllegalArgumentException if the given pattern is invalid.
445     * @see java.text.NumberFormat#getInstance
446     * @see java.text.NumberFormat#getNumberInstance
447     * @see java.text.NumberFormat#getCurrencyInstance
448     * @see java.text.NumberFormat#getPercentInstance
449     */
450    public DecimalFormat(String pattern) {
451        // Always applyPattern after the symbols are set
452        this.symbols = DecimalFormatSymbols.getInstance(Locale.getDefault(Locale.Category.FORMAT));
453        // Android-changed: use initPattern() instead of removed applyPattern(String, boolean).
454        initPattern(pattern);
455    }
456
457
458    /**
459     * Creates a DecimalFormat using the given pattern and symbols.
460     * Use this constructor when you need to completely customize the
461     * behavior of the format.
462     * <p>
463     * To obtain standard formats for a given
464     * locale, use the factory methods on NumberFormat such as
465     * getInstance or getCurrencyInstance. If you need only minor adjustments
466     * to a standard format, you can modify the format returned by
467     * a NumberFormat factory method.
468     *
469     * @param pattern a non-localized pattern string
470     * @param symbols the set of symbols to be used
471     * @exception NullPointerException if any of the given arguments is null
472     * @exception IllegalArgumentException if the given pattern is invalid
473     * @see java.text.NumberFormat#getInstance
474     * @see java.text.NumberFormat#getNumberInstance
475     * @see java.text.NumberFormat#getCurrencyInstance
476     * @see java.text.NumberFormat#getPercentInstance
477     * @see java.text.DecimalFormatSymbols
478     */
479    public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
480        // Always applyPattern after the symbols are set
481        this.symbols = (DecimalFormatSymbols)symbols.clone();
482        // Android-changed: use initPattern() instead of removed applyPattern(String, boolean).
483        initPattern(pattern);
484    }
485
486    // BEGIN Android-added: initPattern() and conversion methods between ICU and Java values.
487    /**
488     * Applies the pattern similarly to {@link #applyPattern(String)}, except it initializes
489     * {@link #icuDecimalFormat} in the process. This should only be called from constructors.
490     */
491    private void initPattern(String pattern) {
492        this.icuDecimalFormat =  new android.icu.text.DecimalFormat_ICU58_Android(pattern,
493                symbols.getIcuDecimalFormatSymbols());
494        updateFieldsFromIcu();
495    }
496
497    /**
498     * Update local fields indicating maximum/minimum integer/fraction digit count from the ICU
499     * DecimalFormat. This needs to be called whenever a new pattern is applied.
500     */
501    private void updateFieldsFromIcu() {
502        // Imitate behaviour of ICU4C NumberFormat that Android used up to M.
503        // If the pattern doesn't enforce a different value (some exponential
504        // patterns do), then set the maximum integer digits to 2 billion.
505        if (icuDecimalFormat.getMaximumIntegerDigits() == DOUBLE_INTEGER_DIGITS) {
506            icuDecimalFormat.setMaximumIntegerDigits(2000000000);
507        }
508        maximumIntegerDigits = icuDecimalFormat.getMaximumIntegerDigits();
509        minimumIntegerDigits = icuDecimalFormat.getMinimumIntegerDigits();
510        maximumFractionDigits = icuDecimalFormat.getMaximumFractionDigits();
511        minimumFractionDigits = icuDecimalFormat.getMinimumFractionDigits();
512    }
513
514    /**
515     * Converts between field positions used by Java/ICU.
516     * @param fp The java.text.NumberFormat.Field field position
517     * @return The android.icu.text.NumberFormat.Field field position
518     */
519    private static FieldPosition getIcuFieldPosition(FieldPosition fp) {
520        Format.Field fieldAttribute = fp.getFieldAttribute();
521        if (fieldAttribute == null) return fp;
522
523        android.icu.text.NumberFormat.Field attribute;
524        if (fieldAttribute == Field.INTEGER) {
525            attribute = android.icu.text.NumberFormat.Field.INTEGER;
526        } else if (fieldAttribute == Field.FRACTION) {
527            attribute = android.icu.text.NumberFormat.Field.FRACTION;
528        } else if (fieldAttribute == Field.DECIMAL_SEPARATOR) {
529            attribute = android.icu.text.NumberFormat.Field.DECIMAL_SEPARATOR;
530        } else if (fieldAttribute == Field.EXPONENT_SYMBOL) {
531            attribute = android.icu.text.NumberFormat.Field.EXPONENT_SYMBOL;
532        } else if (fieldAttribute == Field.EXPONENT_SIGN) {
533            attribute = android.icu.text.NumberFormat.Field.EXPONENT_SIGN;
534        } else if (fieldAttribute == Field.EXPONENT) {
535            attribute = android.icu.text.NumberFormat.Field.EXPONENT;
536        } else if (fieldAttribute == Field.GROUPING_SEPARATOR) {
537            attribute = android.icu.text.NumberFormat.Field.GROUPING_SEPARATOR;
538        } else if (fieldAttribute == Field.CURRENCY) {
539            attribute = android.icu.text.NumberFormat.Field.CURRENCY;
540        } else if (fieldAttribute == Field.PERCENT) {
541            attribute = android.icu.text.NumberFormat.Field.PERCENT;
542        } else if (fieldAttribute == Field.PERMILLE) {
543            attribute = android.icu.text.NumberFormat.Field.PERMILLE;
544        } else if (fieldAttribute == Field.SIGN) {
545            attribute = android.icu.text.NumberFormat.Field.SIGN;
546        } else {
547            throw new IllegalArgumentException("Unexpected field position attribute type.");
548        }
549
550        FieldPosition icuFieldPosition = new FieldPosition(attribute);
551        icuFieldPosition.setBeginIndex(fp.getBeginIndex());
552        icuFieldPosition.setEndIndex(fp.getEndIndex());
553        return icuFieldPosition;
554    }
555
556    /**
557     * Converts the Attribute that ICU returns in its AttributedCharacterIterator
558     * responses to the type that java uses.
559     * @param icuAttribute The AttributedCharacterIterator.Attribute field.
560     * @return Field converted to a java.text.NumberFormat.Field field.
561     */
562    private static Field toJavaFieldAttribute(AttributedCharacterIterator.Attribute icuAttribute) {
563        String name = icuAttribute.getName();
564        if (name.equals(Field.INTEGER.getName())) {
565            return Field.INTEGER;
566        }
567        if (name.equals(Field.CURRENCY.getName())) {
568            return Field.CURRENCY;
569        }
570        if (name.equals(Field.DECIMAL_SEPARATOR.getName())) {
571            return Field.DECIMAL_SEPARATOR;
572        }
573        if (name.equals(Field.EXPONENT.getName())) {
574            return Field.EXPONENT;
575        }
576        if (name.equals(Field.EXPONENT_SIGN.getName())) {
577            return Field.EXPONENT_SIGN;
578        }
579        if (name.equals(Field.EXPONENT_SYMBOL.getName())) {
580            return Field.EXPONENT_SYMBOL;
581        }
582        if (name.equals(Field.FRACTION.getName())) {
583            return Field.FRACTION;
584        }
585        if (name.equals(Field.GROUPING_SEPARATOR.getName())) {
586            return Field.GROUPING_SEPARATOR;
587        }
588        if (name.equals(Field.SIGN.getName())) {
589            return Field.SIGN;
590        }
591        if (name.equals(Field.PERCENT.getName())) {
592            return Field.PERCENT;
593        }
594        if (name.equals(Field.PERMILLE.getName())) {
595            return Field.PERMILLE;
596        }
597        throw new IllegalArgumentException("Unrecognized attribute: " + name);
598    }
599    // END Android-added: initPattern() and conversion methods between ICU and Java values.
600
601    // Overrides
602    /**
603     * Formats a number and appends the resulting text to the given string
604     * buffer.
605     * The number can be of any subclass of {@link java.lang.Number}.
606     * <p>
607     * This implementation uses the maximum precision permitted.
608     * @param number     the number to format
609     * @param toAppendTo the <code>StringBuffer</code> to which the formatted
610     *                   text is to be appended
611     * @param pos        On input: an alignment field, if desired.
612     *                   On output: the offsets of the alignment field.
613     * @return           the value passed in as <code>toAppendTo</code>
614     * @exception        IllegalArgumentException if <code>number</code> is
615     *                   null or not an instance of <code>Number</code>.
616     * @exception        NullPointerException if <code>toAppendTo</code> or
617     *                   <code>pos</code> is null
618     * @exception        ArithmeticException if rounding is needed with rounding
619     *                   mode being set to RoundingMode.UNNECESSARY
620     * @see              java.text.FieldPosition
621     */
622    @Override
623    public final StringBuffer format(Object number,
624                                     StringBuffer toAppendTo,
625                                     FieldPosition pos) {
626        if (number instanceof Long || number instanceof Integer ||
627                   number instanceof Short || number instanceof Byte ||
628                   number instanceof AtomicInteger ||
629                   number instanceof AtomicLong ||
630                   (number instanceof BigInteger &&
631                    ((BigInteger)number).bitLength () < 64)) {
632            return format(((Number)number).longValue(), toAppendTo, pos);
633        } else if (number instanceof BigDecimal) {
634            return format((BigDecimal)number, toAppendTo, pos);
635        } else if (number instanceof BigInteger) {
636            return format((BigInteger)number, toAppendTo, pos);
637        } else if (number instanceof Number) {
638            return format(((Number)number).doubleValue(), toAppendTo, pos);
639        } else {
640            throw new IllegalArgumentException("Cannot format given Object as a Number");
641        }
642    }
643
644    /**
645     * Formats a double to produce a string.
646     * @param number    The double to format
647     * @param result    where the text is to be appended
648     * @param fieldPosition    On input: an alignment field, if desired.
649     * On output: the offsets of the alignment field.
650     * @exception ArithmeticException if rounding is needed with rounding
651     *            mode being set to RoundingMode.UNNECESSARY
652     * @return The formatted number string
653     * @see java.text.FieldPosition
654     */
655    @Override
656    public StringBuffer format(double number, StringBuffer result,
657                               FieldPosition fieldPosition) {
658        // BEGIN Android-changed: Use ICU.
659        FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
660        icuDecimalFormat.format(number, result, icuFieldPosition);
661        fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
662        fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
663        return result;
664        // END Android-changed: Use ICU.
665    }
666
667    // Android-removed: private StringBuffer format(double, StringBuffer, FieldDelegate).
668
669    /**
670     * Format a long to produce a string.
671     * @param number    The long to format
672     * @param result    where the text is to be appended
673     * @param fieldPosition    On input: an alignment field, if desired.
674     * On output: the offsets of the alignment field.
675     * @exception       ArithmeticException if rounding is needed with rounding
676     *                  mode being set to RoundingMode.UNNECESSARY
677     * @return The formatted number string
678     * @see java.text.FieldPosition
679     */
680    @Override
681    public StringBuffer format(long number, StringBuffer result,
682                               FieldPosition fieldPosition) {
683        // BEGIN Android-changed: Use ICU.
684        FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
685        icuDecimalFormat.format(number, result, icuFieldPosition);
686        fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
687        fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
688        return result;
689        // END Android-changed: Use ICU.
690    }
691
692    // Android-removed: private StringBuffer format(long, StringBuffer, FieldDelegate).
693
694    /**
695     * Formats a BigDecimal to produce a string.
696     * @param number    The BigDecimal to format
697     * @param result    where the text is to be appended
698     * @param fieldPosition    On input: an alignment field, if desired.
699     * On output: the offsets of the alignment field.
700     * @return The formatted number string
701     * @exception        ArithmeticException if rounding is needed with rounding
702     *                   mode being set to RoundingMode.UNNECESSARY
703     * @see java.text.FieldPosition
704     */
705    private StringBuffer format(BigDecimal number, StringBuffer result,
706                                FieldPosition fieldPosition) {
707        // BEGIN Android-changed: Use ICU.
708        FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
709        icuDecimalFormat.format(number, result, fieldPosition);
710        fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
711        fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
712        return result;
713        // END Android-changed: Use ICU.
714    }
715
716    // Android-removed: private StringBuffer format(BigDecimal, StringBuffer, FieldDelegate).
717
718    /**
719     * Format a BigInteger to produce a string.
720     * @param number    The BigInteger to format
721     * @param result    where the text is to be appended
722     * @param fieldPosition    On input: an alignment field, if desired.
723     * On output: the offsets of the alignment field.
724     * @return The formatted number string
725     * @exception        ArithmeticException if rounding is needed with rounding
726     *                   mode being set to RoundingMode.UNNECESSARY
727     * @see java.text.FieldPosition
728     */
729    private StringBuffer format(BigInteger number, StringBuffer result,
730                               FieldPosition fieldPosition) {
731        // BEGIN Android-changed: Use ICU.
732        FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
733        icuDecimalFormat.format(number, result, fieldPosition);
734        fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
735        fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
736        return result;
737        // END Android-changed: Use ICU.
738    }
739
740    // Android-removed: private StringBuffer format(BigInteger, StringBuffer, FieldDelegate).
741
742    /**
743     * Formats an Object producing an <code>AttributedCharacterIterator</code>.
744     * You can use the returned <code>AttributedCharacterIterator</code>
745     * to build the resulting String, as well as to determine information
746     * about the resulting String.
747     * <p>
748     * Each attribute key of the AttributedCharacterIterator will be of type
749     * <code>NumberFormat.Field</code>, with the attribute value being the
750     * same as the attribute key.
751     *
752     * @exception NullPointerException if obj is null.
753     * @exception IllegalArgumentException when the Format cannot format the
754     *            given object.
755     * @exception        ArithmeticException if rounding is needed with rounding
756     *                   mode being set to RoundingMode.UNNECESSARY
757     * @param obj The object to format
758     * @return AttributedCharacterIterator describing the formatted value.
759     * @since 1.4
760     */
761    @Override
762    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
763        // BEGIN Android-changed: Use ICU.
764        if (obj == null) {
765            throw new NullPointerException("object == null");
766        }
767        // Note: formatToCharacterIterator cannot be used directly because it returns attributes
768        // in terms of its own class: icu.text.NumberFormat instead of java.text.NumberFormat.
769        // http://bugs.icu-project.org/trac/ticket/11931 Proposes to use the NumberFormat constants.
770
771        AttributedCharacterIterator original = icuDecimalFormat.formatToCharacterIterator(obj);
772
773        // Extract the text out of the ICU iterator.
774        StringBuilder textBuilder = new StringBuilder(
775                original.getEndIndex() - original.getBeginIndex());
776
777        for (int i = original.getBeginIndex(); i < original.getEndIndex(); i++) {
778            textBuilder.append(original.current());
779            original.next();
780        }
781
782        AttributedString result = new AttributedString(textBuilder.toString());
783
784        for (int i = original.getBeginIndex(); i < original.getEndIndex(); i++) {
785            original.setIndex(i);
786
787            for (AttributedCharacterIterator.Attribute attribute
788                    : original.getAttributes().keySet()) {
789                    int start = original.getRunStart();
790                    int end = original.getRunLimit();
791                    Field javaAttr = toJavaFieldAttribute(attribute);
792                    result.addAttribute(javaAttr, javaAttr, start, end);
793            }
794        }
795
796        return result.getIterator();
797        // END Android-changed: Use ICU.
798    }
799
800    // Android-removed: "fast-path formating logic for double" (sic).
801
802    // Android-removed: subformat(), append().
803
804    /**
805     * Parses text from a string to produce a <code>Number</code>.
806     * <p>
807     * The method attempts to parse text starting at the index given by
808     * <code>pos</code>.
809     * If parsing succeeds, then the index of <code>pos</code> is updated
810     * to the index after the last character used (parsing does not necessarily
811     * use all characters up to the end of the string), and the parsed
812     * number is returned. The updated <code>pos</code> can be used to
813     * indicate the starting point for the next call to this method.
814     * If an error occurs, then the index of <code>pos</code> is not
815     * changed, the error index of <code>pos</code> is set to the index of
816     * the character where the error occurred, and null is returned.
817     * <p>
818     * The subclass returned depends on the value of {@link #isParseBigDecimal}
819     * as well as on the string being parsed.
820     * <ul>
821     *   <li>If <code>isParseBigDecimal()</code> is false (the default),
822     *       most integer values are returned as <code>Long</code>
823     *       objects, no matter how they are written: <code>"17"</code> and
824     *       <code>"17.000"</code> both parse to <code>Long(17)</code>.
825     *       Values that cannot fit into a <code>Long</code> are returned as
826     *       <code>Double</code>s. This includes values with a fractional part,
827     *       infinite values, <code>NaN</code>, and the value -0.0.
828     *       <code>DecimalFormat</code> does <em>not</em> decide whether to
829     *       return a <code>Double</code> or a <code>Long</code> based on the
830     *       presence of a decimal separator in the source string. Doing so
831     *       would prevent integers that overflow the mantissa of a double,
832     *       such as <code>"-9,223,372,036,854,775,808.00"</code>, from being
833     *       parsed accurately.
834     *       <p>
835     *       Callers may use the <code>Number</code> methods
836     *       <code>doubleValue</code>, <code>longValue</code>, etc., to obtain
837     *       the type they want.
838     *   <li>If <code>isParseBigDecimal()</code> is true, values are returned
839     *       as <code>BigDecimal</code> objects. The values are the ones
840     *       constructed by {@link java.math.BigDecimal#BigDecimal(String)}
841     *       for corresponding strings in locale-independent format. The
842     *       special cases negative and positive infinity and NaN are returned
843     *       as <code>Double</code> instances holding the values of the
844     *       corresponding <code>Double</code> constants.
845     * </ul>
846     * <p>
847     * <code>DecimalFormat</code> parses all Unicode characters that represent
848     * decimal digits, as defined by <code>Character.digit()</code>. In
849     * addition, <code>DecimalFormat</code> also recognizes as digits the ten
850     * consecutive characters starting with the localized zero digit defined in
851     * the <code>DecimalFormatSymbols</code> object.
852     *
853     * @param text the string to be parsed
854     * @param pos  A <code>ParsePosition</code> object with index and error
855     *             index information as described above.
856     * @return     the parsed value, or <code>null</code> if the parse fails
857     * @exception  NullPointerException if <code>text</code> or
858     *             <code>pos</code> is null.
859     */
860    @Override
861    public Number parse(String text, ParsePosition pos) {
862        // BEGIN Android-changed: Use ICU.
863        // Return early if the parse position is bogus.
864        if (pos.index < 0 || pos.index >= text.length()) {
865            return null;
866        }
867
868        // This might return android.icu.math.BigDecimal, java.math.BigInteger or a primitive type.
869        Number number = icuDecimalFormat.parse(text, pos);
870        if (number == null) {
871            return null;
872        }
873        if (isParseBigDecimal()) {
874            if (number instanceof Long) {
875                return new BigDecimal(number.longValue());
876            }
877            if ((number instanceof Double) && !((Double) number).isInfinite()
878                    && !((Double) number).isNaN()) {
879                return new BigDecimal(number.toString());
880            }
881            if ((number instanceof Double) &&
882                    (((Double) number).isNaN() || ((Double) number).isInfinite())) {
883                return number;
884            }
885            if (number instanceof android.icu.math.BigDecimal) {
886                return ((android.icu.math.BigDecimal) number).toBigDecimal();
887            }
888        }
889        if ((number instanceof android.icu.math.BigDecimal) || (number instanceof BigInteger)) {
890            return number.doubleValue();
891        }
892        if (isParseIntegerOnly() && number.equals(new Double(-0.0))) {
893            return 0L;
894        }
895        return number;
896        // END Android-changed: Use ICU.
897    }
898
899    // Android-removed: STATUS_* constants, multiplier fields and methods and subparse(String, ...).
900
901    /**
902     * Returns a copy of the decimal format symbols, which is generally not
903     * changed by the programmer or user.
904     * @return a copy of the desired DecimalFormatSymbols
905     * @see java.text.DecimalFormatSymbols
906     */
907    public DecimalFormatSymbols getDecimalFormatSymbols() {
908        // Android-changed: Use ICU.
909        return DecimalFormatSymbols.fromIcuInstance(icuDecimalFormat.getDecimalFormatSymbols());
910    }
911
912
913    /**
914     * Sets the decimal format symbols, which is generally not changed
915     * by the programmer or user.
916     * @param newSymbols desired DecimalFormatSymbols
917     * @see java.text.DecimalFormatSymbols
918     */
919    public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
920        try {
921            // don't allow multiple references
922            symbols = (DecimalFormatSymbols) newSymbols.clone();
923            // Android-changed: Use ICU.
924            icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols());
925        } catch (Exception foo) {
926            // should never happen
927        }
928    }
929
930    /**
931     * Get the positive prefix.
932     * <P>Examples: +123, $123, sFr123
933     *
934     * @return the positive prefix
935     */
936    public String getPositivePrefix () {
937        // Android-changed: Use ICU.
938        return icuDecimalFormat.getPositivePrefix();
939    }
940
941    /**
942     * Set the positive prefix.
943     * <P>Examples: +123, $123, sFr123
944     *
945     * @param newValue the new positive prefix
946     */
947    public void setPositivePrefix (String newValue) {
948        // Android-changed: Use ICU.
949        icuDecimalFormat.setPositivePrefix(newValue);
950    }
951
952    // Android-removed: private helper getPositivePrefixFieldPositions().
953
954    /**
955     * Get the  prefix.
956     * <P>Examples: -123, ($123) (with negative suffix), sFr-123
957     *
958     * @return the negative prefix
959     */
960    public String getNegativePrefix () {
961        // Android-changed: Use ICU.
962        return icuDecimalFormat.getNegativePrefix();
963    }
964
965    /**
966     * Set the negative prefix.
967     * <P>Examples: -123, ($123) (with negative suffix), sFr-123
968     *
969     * @param newValue the new negative prefix
970     */
971    public void setNegativePrefix (String newValue) {
972        // Android-changed: Use ICU.
973        icuDecimalFormat.setNegativePrefix(newValue);
974    }
975
976    // Android-removed: private helper getNegativePrefixFieldPositions().
977
978    /**
979     * Get the positive suffix.
980     * <P>Example: 123%
981     *
982     * @return the positive suffix
983     */
984    public String getPositiveSuffix () {
985        // Android-changed: Use ICU.
986        return icuDecimalFormat.getPositiveSuffix();
987    }
988
989    /**
990     * Set the positive suffix.
991     * <P>Example: 123%
992     *
993     * @param newValue the new positive suffix
994     */
995    public void setPositiveSuffix (String newValue) {
996        // Android-changed: Use ICU.
997        icuDecimalFormat.setPositiveSuffix(newValue);
998    }
999
1000    // Android-removed: private helper getPositiveSuffixFieldPositions().
1001
1002    /**
1003     * Get the negative suffix.
1004     * <P>Examples: -123%, ($123) (with positive suffixes)
1005     *
1006     * @return the negative suffix
1007     */
1008    public String getNegativeSuffix () {
1009        // Android-changed: Use ICU.
1010        return icuDecimalFormat.getNegativeSuffix();
1011    }
1012
1013    /**
1014     * Set the negative suffix.
1015     * <P>Examples: 123%
1016     *
1017     * @param newValue the new negative suffix
1018     */
1019    public void setNegativeSuffix (String newValue) {
1020        // Android-changed: Use ICU.
1021        icuDecimalFormat.setNegativeSuffix(newValue);
1022    }
1023
1024    // Android-removed: private helper getNegativeSuffixFieldPositions().
1025
1026    /**
1027     * Gets the multiplier for use in percent, per mille, and similar
1028     * formats.
1029     *
1030     * @return the multiplier
1031     * @see #setMultiplier(int)
1032     */
1033    public int getMultiplier () {
1034        // Android-changed: Use ICU.
1035        return icuDecimalFormat.getMultiplier();
1036    }
1037
1038    /**
1039     * Sets the multiplier for use in percent, per mille, and similar
1040     * formats.
1041     * For a percent format, set the multiplier to 100 and the suffixes to
1042     * have '%' (for Arabic, use the Arabic percent sign).
1043     * For a per mille format, set the multiplier to 1000 and the suffixes to
1044     * have '&#92;u2030'.
1045     *
1046     * <P>Example: with multiplier 100, 1.23 is formatted as "123", and
1047     * "123" is parsed into 1.23.
1048     *
1049     * @param newValue the new multiplier
1050     * @see #getMultiplier
1051     */
1052    public void setMultiplier (int newValue) {
1053        icuDecimalFormat.setMultiplier(newValue);
1054    }
1055
1056    /**
1057     * {@inheritDoc}
1058     */
1059    @Override
1060    public void setGroupingUsed(boolean newValue) {
1061        // Android-changed: Use ICU.
1062        icuDecimalFormat.setGroupingUsed(newValue);
1063        // Android-removed: fast path related code.
1064        // fastPathCheckNeeded = true;
1065    }
1066
1067    // BEGIN Android-added: isGroupingUsed() override delegating to ICU.
1068    /**
1069     * {@inheritDoc}
1070     */
1071    @Override
1072    public boolean isGroupingUsed() {
1073        return icuDecimalFormat.isGroupingUsed();
1074    }
1075    // END Android-added: isGroupingUsed() override delegating to ICU.
1076
1077    /**
1078     * Return the grouping size. Grouping size is the number of digits between
1079     * grouping separators in the integer portion of a number.  For example,
1080     * in the number "123,456.78", the grouping size is 3.
1081     *
1082     * @return the grouping size
1083     * @see #setGroupingSize
1084     * @see java.text.NumberFormat#isGroupingUsed
1085     * @see java.text.DecimalFormatSymbols#getGroupingSeparator
1086     */
1087    public int getGroupingSize () {
1088        // Android-changed: Use ICU.
1089        return icuDecimalFormat.getGroupingSize();
1090    }
1091
1092    /**
1093     * Set the grouping size. Grouping size is the number of digits between
1094     * grouping separators in the integer portion of a number.  For example,
1095     * in the number "123,456.78", the grouping size is 3.
1096     * <br>
1097     * The value passed in is converted to a byte, which may lose information.
1098     *
1099     * @param newValue the new grouping size
1100     * @see #getGroupingSize
1101     * @see java.text.NumberFormat#setGroupingUsed
1102     * @see java.text.DecimalFormatSymbols#setGroupingSeparator
1103     */
1104    public void setGroupingSize (int newValue) {
1105        // Android-changed: Use ICU.
1106        icuDecimalFormat.setGroupingSize(newValue);
1107        // Android-removed: fast path related code.
1108        // fastPathCheckNeeded = true;
1109    }
1110
1111    /**
1112     * Allows you to get the behavior of the decimal separator with integers.
1113     * (The decimal separator will always appear with decimals.)
1114     * <P>Example: Decimal ON: 12345 &rarr; 12345.; OFF: 12345 &rarr; 12345
1115     *
1116     * @return {@code true} if the decimal separator is always shown;
1117     *         {@code false} otherwise
1118     */
1119    public boolean isDecimalSeparatorAlwaysShown() {
1120        // Android-changed: Use ICU.
1121        return icuDecimalFormat.isDecimalSeparatorAlwaysShown();
1122    }
1123
1124    /**
1125     * Allows you to set the behavior of the decimal separator with integers.
1126     * (The decimal separator will always appear with decimals.)
1127     * <P>Example: Decimal ON: 12345 &rarr; 12345.; OFF: 12345 &rarr; 12345
1128     *
1129     * @param newValue {@code true} if the decimal separator is always shown;
1130     *                 {@code false} otherwise
1131     */
1132    public void setDecimalSeparatorAlwaysShown(boolean newValue) {
1133        // Android-changed: Use ICU.
1134        icuDecimalFormat.setDecimalSeparatorAlwaysShown(newValue);
1135    }
1136
1137    /**
1138     * Returns whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1139     * method returns <code>BigDecimal</code>. The default value is false.
1140     *
1141     * @return {@code true} if the parse method returns BigDecimal;
1142     *         {@code false} otherwise
1143     * @see #setParseBigDecimal
1144     * @since 1.5
1145     */
1146    public boolean isParseBigDecimal() {
1147        // Android-changed: Use ICU.
1148        return icuDecimalFormat.isParseBigDecimal();
1149    }
1150
1151    /**
1152     * Sets whether the {@link #parse(java.lang.String, java.text.ParsePosition)}
1153     * method returns <code>BigDecimal</code>.
1154     *
1155     * @param newValue {@code true} if the parse method returns BigDecimal;
1156     *                 {@code false} otherwise
1157     * @see #isParseBigDecimal
1158     * @since 1.5
1159     */
1160    public void setParseBigDecimal(boolean newValue) {
1161        // Android-changed: Use ICU.
1162        icuDecimalFormat.setParseBigDecimal(newValue);
1163    }
1164
1165    // BEGIN Android-added: setParseIntegerOnly()/isParseIntegerOnly() overrides delegating to ICU.
1166    /**
1167     * {@inheritDoc}
1168     */
1169    @Override
1170    public boolean isParseIntegerOnly() {
1171        return icuDecimalFormat.isParseIntegerOnly();
1172    }
1173
1174    /**
1175     * {@inheritDoc}
1176     */
1177    @Override
1178    public void setParseIntegerOnly(boolean value) {
1179        super.setParseIntegerOnly(value);
1180        icuDecimalFormat.setParseIntegerOnly(value);
1181    }
1182    // END Android-added: setParseIntegerOnly()/isParseIntegerOnly() overrides delegating to ICU.
1183
1184    /**
1185     * Standard override; no change in semantics.
1186     */
1187    @Override
1188    public Object clone() {
1189        // BEGIN Android-changed: Use ICU, remove fast path related code.
1190        try {
1191            DecimalFormat other = (DecimalFormat) super.clone();
1192            other.icuDecimalFormat = (android.icu.text.DecimalFormat_ICU58_Android) icuDecimalFormat.clone();
1193            other.symbols = (DecimalFormatSymbols) symbols.clone();
1194            return other;
1195        } catch (Exception e) {
1196            throw new InternalError();
1197        }
1198        // END Android-changed: Use ICU, remove fast path related code.
1199    }
1200
1201    // BEGIN Android-changed: re-implement equals() using ICU fields.
1202    /**
1203     * Overrides equals
1204     */
1205    @Override
1206    public boolean equals(Object obj)
1207    {
1208        if (obj == null) {
1209            return false;
1210        }
1211        if (this == obj) {
1212            return true;
1213        }
1214        if (!(obj instanceof DecimalFormat)) {
1215            return false;
1216        }
1217        DecimalFormat other = (DecimalFormat) obj;
1218        return icuDecimalFormat.equals(other.icuDecimalFormat)
1219            && compareIcuRoundingIncrement(other.icuDecimalFormat);
1220    }
1221
1222    private boolean compareIcuRoundingIncrement(android.icu.text.DecimalFormat_ICU58_Android other) {
1223        BigDecimal increment = this.icuDecimalFormat.getRoundingIncrement();
1224        if (increment != null) {
1225            return (other.getRoundingIncrement() != null)
1226                && increment.equals(other.getRoundingIncrement());
1227        }
1228        return other.getRoundingIncrement() == null;
1229    }
1230    // END Android-changed: re-implement equals() using ICU fields.
1231
1232    /**
1233     * Overrides hashCode
1234     */
1235    @Override
1236    public int hashCode() {
1237        // Android-changed: use getPositivePrefix() instead of positivePrefix field.
1238        return super.hashCode() * 37 + getPositivePrefix().hashCode();
1239        // just enough fields for a reasonable distribution
1240    }
1241
1242    /**
1243     * Synthesizes a pattern string that represents the current state
1244     * of this Format object.
1245     *
1246     * @return a pattern string
1247     * @see #applyPattern
1248     */
1249    public String toPattern() {
1250        // Android-changed: use ICU.
1251        return icuDecimalFormat.toPattern();
1252    }
1253
1254    /**
1255     * Synthesizes a localized pattern string that represents the current
1256     * state of this Format object.
1257     *
1258     * @return a localized pattern string
1259     * @see #applyPattern
1260     */
1261    public String toLocalizedPattern() {
1262        // Android-changed: use ICU.
1263        return icuDecimalFormat.toLocalizedPattern();
1264    }
1265
1266    // Android-removed: private helper methods expandAffixes(), expandAffix(), toPattern(boolean).
1267
1268    /**
1269     * Apply the given pattern to this Format object.  A pattern is a
1270     * short-hand specification for the various formatting properties.
1271     * These properties can also be changed individually through the
1272     * various setter methods.
1273     * <p>
1274     * There is no limit to integer digits set
1275     * by this routine, since that is the typical end-user desire;
1276     * use setMaximumInteger if you want to set a real value.
1277     * For negative numbers, use a second pattern, separated by a semicolon
1278     * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56
1279     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
1280     * a maximum of 2 fraction digits.
1281     * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
1282     * parentheses.
1283     * <p>In negative patterns, the minimum and maximum counts are ignored;
1284     * these are presumed to be set in the positive pattern.
1285     *
1286     * @param pattern a new pattern
1287     * @exception NullPointerException if <code>pattern</code> is null
1288     * @exception IllegalArgumentException if the given pattern is invalid.
1289     */
1290    public void applyPattern(String pattern) {
1291        // Android-changed: use ICU.
1292        icuDecimalFormat.applyPattern(pattern);
1293        updateFieldsFromIcu();
1294    }
1295
1296    /**
1297     * Apply the given pattern to this Format object.  The pattern
1298     * is assumed to be in a localized notation. A pattern is a
1299     * short-hand specification for the various formatting properties.
1300     * These properties can also be changed individually through the
1301     * various setter methods.
1302     * <p>
1303     * There is no limit to integer digits set
1304     * by this routine, since that is the typical end-user desire;
1305     * use setMaximumInteger if you want to set a real value.
1306     * For negative numbers, use a second pattern, separated by a semicolon
1307     * <P>Example <code>"#,#00.0#"</code> &rarr; 1,234.56
1308     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
1309     * a maximum of 2 fraction digits.
1310     * <p>Example: <code>"#,#00.0#;(#,#00.0#)"</code> for negatives in
1311     * parentheses.
1312     * <p>In negative patterns, the minimum and maximum counts are ignored;
1313     * these are presumed to be set in the positive pattern.
1314     *
1315     * @param pattern a new pattern
1316     * @exception NullPointerException if <code>pattern</code> is null
1317     * @exception IllegalArgumentException if the given pattern is invalid.
1318     */
1319    public void applyLocalizedPattern(String pattern) {
1320        // Android-changed: use ICU.
1321        icuDecimalFormat.applyLocalizedPattern(pattern);
1322        updateFieldsFromIcu();
1323    }
1324
1325    // Android-removed: applyPattern(String, boolean) as apply[Localized]Pattern calls ICU directly.
1326
1327    /**
1328     * Sets the maximum number of digits allowed in the integer portion of a
1329     * number.
1330     * For formatting numbers other than <code>BigInteger</code> and
1331     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
1332     * 309 is used. Negative input values are replaced with 0.
1333     * @see NumberFormat#setMaximumIntegerDigits
1334     */
1335    @Override
1336    public void setMaximumIntegerDigits(int newValue) {
1337        maximumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
1338        super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
1339            DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
1340        if (minimumIntegerDigits > maximumIntegerDigits) {
1341            minimumIntegerDigits = maximumIntegerDigits;
1342            super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
1343                DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
1344        }
1345        // Android-changed: use ICU.
1346        icuDecimalFormat.setMaximumIntegerDigits(getMaximumIntegerDigits());
1347        // Android-removed: fast path related code.
1348        // fastPathCheckNeeded = true;
1349    }
1350
1351    /**
1352     * Sets the minimum number of digits allowed in the integer portion of a
1353     * number.
1354     * For formatting numbers other than <code>BigInteger</code> and
1355     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
1356     * 309 is used. Negative input values are replaced with 0.
1357     * @see NumberFormat#setMinimumIntegerDigits
1358     */
1359    @Override
1360    public void setMinimumIntegerDigits(int newValue) {
1361        minimumIntegerDigits = Math.min(Math.max(0, newValue), MAXIMUM_INTEGER_DIGITS);
1362        super.setMinimumIntegerDigits((minimumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
1363            DOUBLE_INTEGER_DIGITS : minimumIntegerDigits);
1364        if (minimumIntegerDigits > maximumIntegerDigits) {
1365            maximumIntegerDigits = minimumIntegerDigits;
1366            super.setMaximumIntegerDigits((maximumIntegerDigits > DOUBLE_INTEGER_DIGITS) ?
1367                DOUBLE_INTEGER_DIGITS : maximumIntegerDigits);
1368        }
1369        // Android-changed: use ICU.
1370        icuDecimalFormat.setMinimumIntegerDigits(getMinimumIntegerDigits());
1371        // Android-removed: fast path related code.
1372        // fastPathCheckNeeded = true;
1373    }
1374
1375    /**
1376     * Sets the maximum number of digits allowed in the fraction portion of a
1377     * number.
1378     * For formatting numbers other than <code>BigInteger</code> and
1379     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
1380     * 340 is used. Negative input values are replaced with 0.
1381     * @see NumberFormat#setMaximumFractionDigits
1382     */
1383    @Override
1384    public void setMaximumFractionDigits(int newValue) {
1385        maximumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
1386        super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
1387            DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
1388        if (minimumFractionDigits > maximumFractionDigits) {
1389            minimumFractionDigits = maximumFractionDigits;
1390            super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
1391                DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
1392        }
1393        // Android-changed: use ICU.
1394        icuDecimalFormat.setMaximumFractionDigits(getMaximumFractionDigits());
1395        // Android-removed: fast path related code.
1396        // fastPathCheckNeeded = true;
1397    }
1398
1399    /**
1400     * Sets the minimum number of digits allowed in the fraction portion of a
1401     * number.
1402     * For formatting numbers other than <code>BigInteger</code> and
1403     * <code>BigDecimal</code> objects, the lower of <code>newValue</code> and
1404     * 340 is used. Negative input values are replaced with 0.
1405     * @see NumberFormat#setMinimumFractionDigits
1406     */
1407    @Override
1408    public void setMinimumFractionDigits(int newValue) {
1409        minimumFractionDigits = Math.min(Math.max(0, newValue), MAXIMUM_FRACTION_DIGITS);
1410        super.setMinimumFractionDigits((minimumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
1411            DOUBLE_FRACTION_DIGITS : minimumFractionDigits);
1412        if (minimumFractionDigits > maximumFractionDigits) {
1413            maximumFractionDigits = minimumFractionDigits;
1414            super.setMaximumFractionDigits((maximumFractionDigits > DOUBLE_FRACTION_DIGITS) ?
1415                DOUBLE_FRACTION_DIGITS : maximumFractionDigits);
1416        }
1417        // Android-changed: use ICU.
1418        icuDecimalFormat.setMinimumFractionDigits(getMinimumFractionDigits());
1419        // Android-removed: fast path related code.
1420        // fastPathCheckNeeded = true;
1421    }
1422
1423    /**
1424     * Gets the maximum number of digits allowed in the integer portion of a
1425     * number.
1426     * For formatting numbers other than <code>BigInteger</code> and
1427     * <code>BigDecimal</code> objects, the lower of the return value and
1428     * 309 is used.
1429     * @see #setMaximumIntegerDigits
1430     */
1431    @Override
1432    public int getMaximumIntegerDigits() {
1433        return maximumIntegerDigits;
1434    }
1435
1436    /**
1437     * Gets the minimum number of digits allowed in the integer portion of a
1438     * number.
1439     * For formatting numbers other than <code>BigInteger</code> and
1440     * <code>BigDecimal</code> objects, the lower of the return value and
1441     * 309 is used.
1442     * @see #setMinimumIntegerDigits
1443     */
1444    @Override
1445    public int getMinimumIntegerDigits() {
1446        return minimumIntegerDigits;
1447    }
1448
1449    /**
1450     * Gets the maximum number of digits allowed in the fraction portion of a
1451     * number.
1452     * For formatting numbers other than <code>BigInteger</code> and
1453     * <code>BigDecimal</code> objects, the lower of the return value and
1454     * 340 is used.
1455     * @see #setMaximumFractionDigits
1456     */
1457    @Override
1458    public int getMaximumFractionDigits() {
1459        return maximumFractionDigits;
1460    }
1461
1462    /**
1463     * Gets the minimum number of digits allowed in the fraction portion of a
1464     * number.
1465     * For formatting numbers other than <code>BigInteger</code> and
1466     * <code>BigDecimal</code> objects, the lower of the return value and
1467     * 340 is used.
1468     * @see #setMinimumFractionDigits
1469     */
1470    @Override
1471    public int getMinimumFractionDigits() {
1472        return minimumFractionDigits;
1473    }
1474
1475    /**
1476     * Gets the currency used by this decimal format when formatting
1477     * currency values.
1478     * The currency is obtained by calling
1479     * {@link DecimalFormatSymbols#getCurrency DecimalFormatSymbols.getCurrency}
1480     * on this number format's symbols.
1481     *
1482     * @return the currency used by this decimal format, or <code>null</code>
1483     * @since 1.4
1484     */
1485    @Override
1486    public Currency getCurrency() {
1487        return symbols.getCurrency();
1488    }
1489
1490    /**
1491     * Sets the currency used by this number format when formatting
1492     * currency values. This does not update the minimum or maximum
1493     * number of fraction digits used by the number format.
1494     * The currency is set by calling
1495     * {@link DecimalFormatSymbols#setCurrency DecimalFormatSymbols.setCurrency}
1496     * on this number format's symbols.
1497     *
1498     * @param currency the new currency to be used by this decimal format
1499     * @exception NullPointerException if <code>currency</code> is null
1500     * @since 1.4
1501     */
1502    @Override
1503    public void setCurrency(Currency currency) {
1504        // BEGIN Android-changed: use ICU.
1505        // Set the international currency symbol, and currency symbol on the DecimalFormatSymbols
1506        // object and tell ICU to use that.
1507        if (currency != symbols.getCurrency()
1508            || !currency.getSymbol().equals(symbols.getCurrencySymbol())) {
1509            symbols.setCurrency(currency);
1510            icuDecimalFormat.setDecimalFormatSymbols(symbols.getIcuDecimalFormatSymbols());
1511            // Giving the icuDecimalFormat a new currency will cause the fractional digits to be
1512            // updated. This class is specified to not touch the fraction digits, so we re-set them.
1513            icuDecimalFormat.setMinimumFractionDigits(minimumFractionDigits);
1514            icuDecimalFormat.setMaximumFractionDigits(maximumFractionDigits);
1515        }
1516        // END Android-changed: use ICU.
1517        // Android-removed: fast path related code.
1518        // fastPathCheckNeeded = true;
1519    }
1520
1521    /**
1522     * Gets the {@link java.math.RoundingMode} used in this DecimalFormat.
1523     *
1524     * @return The <code>RoundingMode</code> used for this DecimalFormat.
1525     * @see #setRoundingMode(RoundingMode)
1526     * @since 1.6
1527     */
1528    @Override
1529    public RoundingMode getRoundingMode() {
1530        return roundingMode;
1531    }
1532
1533    // Android-added: convertRoundingMode() to convert between Java and ICU RoundingMode enums.
1534    private static int convertRoundingMode(RoundingMode rm) {
1535        switch (rm) {
1536        case UP:
1537            return MathContext.ROUND_UP;
1538        case DOWN:
1539            return MathContext.ROUND_DOWN;
1540        case CEILING:
1541            return MathContext.ROUND_CEILING;
1542        case FLOOR:
1543            return MathContext.ROUND_FLOOR;
1544        case HALF_UP:
1545            return MathContext.ROUND_HALF_UP;
1546        case HALF_DOWN:
1547            return MathContext.ROUND_HALF_DOWN;
1548        case HALF_EVEN:
1549            return MathContext.ROUND_HALF_EVEN;
1550        case UNNECESSARY:
1551            return MathContext.ROUND_UNNECESSARY;
1552        }
1553        throw new IllegalArgumentException("Invalid rounding mode specified");
1554    }
1555
1556    /**
1557     * Sets the {@link java.math.RoundingMode} used in this DecimalFormat.
1558     *
1559     * @param roundingMode The <code>RoundingMode</code> to be used
1560     * @see #getRoundingMode()
1561     * @exception NullPointerException if <code>roundingMode</code> is null.
1562     * @since 1.6
1563     */
1564    @Override
1565    public void setRoundingMode(RoundingMode roundingMode) {
1566        if (roundingMode == null) {
1567            throw new NullPointerException();
1568        }
1569
1570        this.roundingMode = roundingMode;
1571        // Android-changed: use ICU.
1572        icuDecimalFormat.setRoundingMode(convertRoundingMode(roundingMode));
1573        // Android-removed: fast path related code.
1574        // fastPathCheckNeeded = true;
1575    }
1576
1577    // BEGIN Android-added: 7u40 version of adjustForCurrencyDefaultFractionDigits().
1578    // This method was removed in OpenJDK 8 in favor of doing equivalent work in the provider. Since
1579    // Android removed support for providers for NumberFormat we keep this method around as an
1580    // "Android addition".
1581    /**
1582     * Adjusts the minimum and maximum fraction digits to values that
1583     * are reasonable for the currency's default fraction digits.
1584     */
1585    void adjustForCurrencyDefaultFractionDigits() {
1586        Currency currency = symbols.getCurrency();
1587        if (currency == null) {
1588            try {
1589                currency = Currency.getInstance(symbols.getInternationalCurrencySymbol());
1590            } catch (IllegalArgumentException e) {
1591            }
1592        }
1593        if (currency != null) {
1594            int digits = currency.getDefaultFractionDigits();
1595            if (digits != -1) {
1596                int oldMinDigits = getMinimumFractionDigits();
1597                // Common patterns are "#.##", "#.00", "#".
1598                // Try to adjust all of them in a reasonable way.
1599                if (oldMinDigits == getMaximumFractionDigits()) {
1600                    setMinimumFractionDigits(digits);
1601                    setMaximumFractionDigits(digits);
1602                } else {
1603                    setMinimumFractionDigits(Math.min(digits, oldMinDigits));
1604                    setMaximumFractionDigits(digits);
1605                }
1606            }
1607        }
1608    }
1609    // END Android-added: Upstream code from earlier OpenJDK release.
1610
1611    // BEGIN Android-added: Custom serialization code for compatibility with RI serialization.
1612    // the fields list to be serialized
1613    private static final ObjectStreamField[] serialPersistentFields = {
1614            new ObjectStreamField("positivePrefix", String.class),
1615            new ObjectStreamField("positiveSuffix", String.class),
1616            new ObjectStreamField("negativePrefix", String.class),
1617            new ObjectStreamField("negativeSuffix", String.class),
1618            new ObjectStreamField("posPrefixPattern", String.class),
1619            new ObjectStreamField("posSuffixPattern", String.class),
1620            new ObjectStreamField("negPrefixPattern", String.class),
1621            new ObjectStreamField("negSuffixPattern", String.class),
1622            new ObjectStreamField("multiplier", int.class),
1623            new ObjectStreamField("groupingSize", byte.class),
1624            new ObjectStreamField("groupingUsed", boolean.class),
1625            new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class),
1626            new ObjectStreamField("parseBigDecimal", boolean.class),
1627            new ObjectStreamField("roundingMode", RoundingMode.class),
1628            new ObjectStreamField("symbols", DecimalFormatSymbols.class),
1629            new ObjectStreamField("useExponentialNotation", boolean.class),
1630            new ObjectStreamField("minExponentDigits", byte.class),
1631            new ObjectStreamField("maximumIntegerDigits", int.class),
1632            new ObjectStreamField("minimumIntegerDigits", int.class),
1633            new ObjectStreamField("maximumFractionDigits", int.class),
1634            new ObjectStreamField("minimumFractionDigits", int.class),
1635            new ObjectStreamField("serialVersionOnStream", int.class),
1636    };
1637
1638    private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException {
1639        ObjectOutputStream.PutField fields = stream.putFields();
1640        fields.put("positivePrefix", icuDecimalFormat.getPositivePrefix());
1641        fields.put("positiveSuffix", icuDecimalFormat.getPositiveSuffix());
1642        fields.put("negativePrefix", icuDecimalFormat.getNegativePrefix());
1643        fields.put("negativeSuffix", icuDecimalFormat.getNegativeSuffix());
1644        fields.put("posPrefixPattern", (String) null);
1645        fields.put("posSuffixPattern", (String) null);
1646        fields.put("negPrefixPattern", (String) null);
1647        fields.put("negSuffixPattern", (String) null);
1648        fields.put("multiplier", icuDecimalFormat.getMultiplier());
1649        fields.put("groupingSize", (byte) icuDecimalFormat.getGroupingSize());
1650        fields.put("groupingUsed", icuDecimalFormat.isGroupingUsed());
1651        fields.put("decimalSeparatorAlwaysShown", icuDecimalFormat.isDecimalSeparatorAlwaysShown());
1652        fields.put("parseBigDecimal", icuDecimalFormat.isParseBigDecimal());
1653        fields.put("roundingMode", roundingMode);
1654        fields.put("symbols", symbols);
1655        fields.put("useExponentialNotation", false);
1656        fields.put("minExponentDigits", (byte) 0);
1657        fields.put("maximumIntegerDigits", icuDecimalFormat.getMaximumIntegerDigits());
1658        fields.put("minimumIntegerDigits", icuDecimalFormat.getMinimumIntegerDigits());
1659        fields.put("maximumFractionDigits", icuDecimalFormat.getMaximumFractionDigits());
1660        fields.put("minimumFractionDigits", icuDecimalFormat.getMinimumFractionDigits());
1661        fields.put("serialVersionOnStream", currentSerialVersion);
1662        stream.writeFields();
1663    }
1664    // BEGIN Android-added: Custom serialization code for compatibility with RI serialization.
1665
1666    /**
1667     * Reads the default serializable fields from the stream and performs
1668     * validations and adjustments for older serialized versions. The
1669     * validations and adjustments are:
1670     * <ol>
1671     * <li>
1672     * Verify that the superclass's digit count fields correctly reflect
1673     * the limits imposed on formatting numbers other than
1674     * <code>BigInteger</code> and <code>BigDecimal</code> objects. These
1675     * limits are stored in the superclass for serialization compatibility
1676     * with older versions, while the limits for <code>BigInteger</code> and
1677     * <code>BigDecimal</code> objects are kept in this class.
1678     * If, in the superclass, the minimum or maximum integer digit count is
1679     * larger than <code>DOUBLE_INTEGER_DIGITS</code> or if the minimum or
1680     * maximum fraction digit count is larger than
1681     * <code>DOUBLE_FRACTION_DIGITS</code>, then the stream data is invalid
1682     * and this method throws an <code>InvalidObjectException</code>.
1683     * <li>
1684     * If <code>serialVersionOnStream</code> is less than 4, initialize
1685     * <code>roundingMode</code> to {@link java.math.RoundingMode#HALF_EVEN
1686     * RoundingMode.HALF_EVEN}.  This field is new with version 4.
1687     * <li>
1688     * If <code>serialVersionOnStream</code> is less than 3, then call
1689     * the setters for the minimum and maximum integer and fraction digits with
1690     * the values of the corresponding superclass getters to initialize the
1691     * fields in this class. The fields in this class are new with version 3.
1692     * <li>
1693     * If <code>serialVersionOnStream</code> is less than 1, indicating that
1694     * the stream was written by JDK 1.1, initialize
1695     * <code>useExponentialNotation</code>
1696     * to false, since it was not present in JDK 1.1.
1697     * <li>
1698     * Set <code>serialVersionOnStream</code> to the maximum allowed value so
1699     * that default serialization will work properly if this object is streamed
1700     * out again.
1701     * </ol>
1702     *
1703     * <p>Stream versions older than 2 will not have the affix pattern variables
1704     * <code>posPrefixPattern</code> etc.  As a result, they will be initialized
1705     * to <code>null</code>, which means the affix strings will be taken as
1706     * literal values.  This is exactly what we want, since that corresponds to
1707     * the pre-version-2 behavior.
1708     */
1709    // BEGIN Android-added: Custom serialization code for compatibility with RI serialization.
1710    private void readObject(ObjectInputStream stream)
1711            throws IOException, ClassNotFoundException {
1712        ObjectInputStream.GetField fields = stream.readFields();
1713        this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
1714
1715        initPattern("#");
1716
1717        // Calling a setter method on an ICU DecimalFormat object will change the object's internal
1718        // state, even if the value set is the same as the default value (ICU Ticket #13266).
1719        //
1720        // In an attempt to create objects that are equals() to the ones that were serialized, it's
1721        // therefore assumed here that any values that are the same as the default values were the
1722        // default values (ie. no setter was called to explicitly set that value).
1723
1724        String positivePrefix = (String) fields.get("positivePrefix", "");
1725        if (!Objects.equals(positivePrefix, icuDecimalFormat.getPositivePrefix())) {
1726            icuDecimalFormat.setPositivePrefix(positivePrefix);
1727        }
1728
1729        String positiveSuffix = (String) fields.get("positiveSuffix", "");
1730        if (!Objects.equals(positiveSuffix, icuDecimalFormat.getPositiveSuffix())) {
1731            icuDecimalFormat.setPositiveSuffix(positiveSuffix);
1732        }
1733
1734        String negativePrefix = (String) fields.get("negativePrefix", "-");
1735        if (!Objects.equals(negativePrefix, icuDecimalFormat.getNegativePrefix())) {
1736            icuDecimalFormat.setNegativePrefix(negativePrefix);
1737        }
1738
1739        String negativeSuffix = (String) fields.get("negativeSuffix", "");
1740        if (!Objects.equals(negativeSuffix, icuDecimalFormat.getNegativeSuffix())) {
1741            icuDecimalFormat.setNegativeSuffix(negativeSuffix);
1742        }
1743
1744        int multiplier = fields.get("multiplier", 1);
1745        if (multiplier != icuDecimalFormat.getMultiplier()) {
1746            icuDecimalFormat.setMultiplier(multiplier);
1747        }
1748
1749        boolean groupingUsed = fields.get("groupingUsed", true);
1750        if (groupingUsed != icuDecimalFormat.isGroupingUsed()) {
1751            icuDecimalFormat.setGroupingUsed(groupingUsed);
1752        }
1753
1754        int groupingSize = fields.get("groupingSize", (byte) 3);
1755        if (groupingSize != icuDecimalFormat.getGroupingSize()) {
1756            icuDecimalFormat.setGroupingSize(groupingSize);
1757        }
1758
1759        boolean decimalSeparatorAlwaysShown = fields.get("decimalSeparatorAlwaysShown", false);
1760        if (decimalSeparatorAlwaysShown != icuDecimalFormat.isDecimalSeparatorAlwaysShown()) {
1761            icuDecimalFormat.setDecimalSeparatorAlwaysShown(decimalSeparatorAlwaysShown);
1762        }
1763
1764        RoundingMode roundingMode =
1765                (RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN);
1766        if (convertRoundingMode(roundingMode) != icuDecimalFormat.getRoundingMode()) {
1767            setRoundingMode(roundingMode);
1768        }
1769
1770        int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
1771        if (maximumIntegerDigits != icuDecimalFormat.getMaximumIntegerDigits()) {
1772            icuDecimalFormat.setMaximumIntegerDigits(maximumIntegerDigits);
1773        }
1774
1775        int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
1776        if (minimumIntegerDigits != icuDecimalFormat.getMinimumIntegerDigits()) {
1777            icuDecimalFormat.setMinimumIntegerDigits(minimumIntegerDigits);
1778        }
1779
1780        int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
1781        if (maximumFractionDigits != icuDecimalFormat.getMaximumFractionDigits()) {
1782            icuDecimalFormat.setMaximumFractionDigits(maximumFractionDigits);
1783        }
1784
1785        int minimumFractionDigits = fields.get("minimumFractionDigits", 340);
1786        if (minimumFractionDigits != icuDecimalFormat.getMinimumFractionDigits()) {
1787            icuDecimalFormat.setMinimumFractionDigits(minimumFractionDigits);
1788        }
1789
1790        boolean parseBigDecimal = fields.get("parseBigDecimal", true);
1791        if (parseBigDecimal != icuDecimalFormat.isParseBigDecimal()) {
1792            icuDecimalFormat.setParseBigDecimal(parseBigDecimal);
1793        }
1794
1795        updateFieldsFromIcu();
1796
1797        if (fields.get("serialVersionOnStream", 0) < 3) {
1798            setMaximumIntegerDigits(super.getMaximumIntegerDigits());
1799            setMinimumIntegerDigits(super.getMinimumIntegerDigits());
1800            setMaximumFractionDigits(super.getMaximumFractionDigits());
1801            setMinimumFractionDigits(super.getMinimumFractionDigits());
1802        }
1803    }
1804    // END Android-added: Custom serialization code for compatibility with RI serialization.
1805
1806    //----------------------------------------------------------------------
1807    // INSTANCE VARIABLES
1808    //----------------------------------------------------------------------
1809
1810    // Android-removed: various fields now stored in icuDecimalFormat.
1811
1812    /**
1813     * The <code>DecimalFormatSymbols</code> object used by this format.
1814     * It contains the symbols used to format numbers, e.g. the grouping separator,
1815     * decimal separator, and so on.
1816     *
1817     * @serial
1818     * @see #setDecimalFormatSymbols
1819     * @see java.text.DecimalFormatSymbols
1820     */
1821    private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
1822
1823    // Android-removed: useExponentialNotation, *FieldPositions, minExponentDigits.
1824
1825    /**
1826     * The maximum number of digits allowed in the integer portion of a
1827     * <code>BigInteger</code> or <code>BigDecimal</code> number.
1828     * <code>maximumIntegerDigits</code> must be greater than or equal to
1829     * <code>minimumIntegerDigits</code>.
1830     *
1831     * @serial
1832     * @see #getMaximumIntegerDigits
1833     * @since 1.5
1834     */
1835    // Android-changed: removed initialisation.
1836    private int    maximumIntegerDigits /* = super.getMaximumIntegerDigits() */;
1837
1838    /**
1839     * The minimum number of digits allowed in the integer portion of a
1840     * <code>BigInteger</code> or <code>BigDecimal</code> number.
1841     * <code>minimumIntegerDigits</code> must be less than or equal to
1842     * <code>maximumIntegerDigits</code>.
1843     *
1844     * @serial
1845     * @see #getMinimumIntegerDigits
1846     * @since 1.5
1847     */
1848    // Android-changed: removed initialisation.
1849    private int    minimumIntegerDigits /* = super.getMinimumIntegerDigits() */;
1850
1851    /**
1852     * The maximum number of digits allowed in the fractional portion of a
1853     * <code>BigInteger</code> or <code>BigDecimal</code> number.
1854     * <code>maximumFractionDigits</code> must be greater than or equal to
1855     * <code>minimumFractionDigits</code>.
1856     *
1857     * @serial
1858     * @see #getMaximumFractionDigits
1859     * @since 1.5
1860     */
1861    // Android-changed: removed initialisation.
1862    private int    maximumFractionDigits /* = super.getMaximumFractionDigits() */;
1863
1864    /**
1865     * The minimum number of digits allowed in the fractional portion of a
1866     * <code>BigInteger</code> or <code>BigDecimal</code> number.
1867     * <code>minimumFractionDigits</code> must be less than or equal to
1868     * <code>maximumFractionDigits</code>.
1869     *
1870     * @serial
1871     * @see #getMinimumFractionDigits
1872     * @since 1.5
1873     */
1874    // Android-changed: removed initialisation.
1875    private int    minimumFractionDigits /* = super.getMinimumFractionDigits() */;
1876
1877    /**
1878     * The {@link java.math.RoundingMode} used in this DecimalFormat.
1879     *
1880     * @serial
1881     * @since 1.6
1882     */
1883    private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
1884
1885    // Android-removed: FastPathData, isFastPath, fastPathCheckNeeded and fastPathData.
1886
1887    //----------------------------------------------------------------------
1888
1889    static final int currentSerialVersion = 4;
1890
1891    // Android-removed: serialVersionOnStream.
1892
1893    //----------------------------------------------------------------------
1894    // CONSTANTS
1895    //----------------------------------------------------------------------
1896
1897    // Android-removed: Fast-Path for double Constants, various constants.
1898
1899    // Upper limit on integer and fraction digits for a Java double
1900    static final int DOUBLE_INTEGER_DIGITS  = 309;
1901    static final int DOUBLE_FRACTION_DIGITS = 340;
1902
1903    // Upper limit on integer and fraction digits for BigDecimal and BigInteger
1904    static final int MAXIMUM_INTEGER_DIGITS  = Integer.MAX_VALUE;
1905    static final int MAXIMUM_FRACTION_DIGITS = Integer.MAX_VALUE;
1906
1907    // Proclaim JDK 1.1 serial compatibility.
1908    static final long serialVersionUID = 864413376551465018L;
1909}
1910