1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// BEGIN android-note
19// The icu implementation used was changed from icu4j to icu4jni.
20// END android-note
21
22package java.text;
23
24import java.io.IOException;
25import java.io.ObjectInputStream;
26import java.io.ObjectOutputStream;
27import java.io.ObjectStreamField;
28import java.math.BigDecimal;
29import java.math.BigInteger;
30import java.security.AccessController;
31import java.security.PrivilegedAction;
32import java.util.Currency;
33import java.util.Locale;
34
35import com.ibm.icu4jni.text.NativeDecimalFormat;
36import com.ibm.icu4jni.util.LocaleData;
37
38/**
39 * A concrete subclass of {@link NumberFormat} that formats decimal numbers. It
40 * has a variety of features designed to make it possible to parse and format
41 * numbers in any locale, including support for Western, Arabic, or Indic
42 * digits. It also supports different flavors of numbers, including integers
43 * ("123"), fixed-point numbers ("123.4"), scientific notation ("1.23E4"),
44 * percentages ("12%"), and currency amounts ("$123"). All of these flavors can
45 * be easily localized.
46 * <p>
47 * <strong>This is an enhanced version of {@code DecimalFormat} that is based on
48 * the standard version in the RI. New or changed functionality is labeled
49 * <strong><font color="red">NEW</font></strong>.</strong>
50 * <p>
51 * To obtain a {@link NumberFormat} for a specific locale (including the default
52 * locale), call one of {@code NumberFormat}'s factory methods such as
53 * {@code NumberFormat.getInstance}. Do not call the {@code DecimalFormat}
54 * constructors directly, unless you know what you are doing, since the
55 * {@link NumberFormat} factory methods may return subclasses other than
56 * {@code DecimalFormat}. If you need to customize the format object, do
57 * something like this: <blockquote>
58 *
59 * <pre>
60 * NumberFormat f = NumberFormat.getInstance(loc);
61 * if (f instanceof DecimalFormat) {
62 *     ((DecimalFormat)f).setDecimalSeparatorAlwaysShown(true);
63 * }
64 * </pre>
65 *
66 * </blockquote>
67 * <h5>Example:</h5>
68 * <blockquote>
69 *
70 * <pre>
71 * // Print out a number using the localized number, currency,
72 * // and percent format for each locale
73 * Locale[] locales = NumberFormat.getAvailableLocales();
74 * double myNumber = -1234.56;
75 * NumberFormat format;
76 * for (int j = 0; j &lt; 3; ++j) {
77 *     System.out.println(&quot;FORMAT&quot;);
78 *     for (int i = 0; i &lt; locales.length; ++i) {
79 *         if (locales[i].getCountry().length() == 0) {
80 *             // Skip language-only locales
81 *             continue;
82 *         }
83 *         System.out.print(locales[i].getDisplayName());
84 *         switch (j) {
85 *             case 0:
86 *                 format = NumberFormat.getInstance(locales[i]);
87 *                 break;
88 *             case 1:
89 *                 format = NumberFormat.getCurrencyInstance(locales[i]);
90 *                 break;
91 *             default:
92 *                 format = NumberFormat.getPercentInstance(locales[i]);
93 *                 break;
94 *         }
95 *         try {
96 *             // Assume format is a DecimalFormat
97 *             System.out.print(&quot;: &quot;; + ((DecimalFormat)format).toPattern() + &quot; -&gt; &quot;
98 *                     + form.format(myNumber));
99 *         } catch (Exception e) {
100 *         }
101 *         try {
102 *             System.out.println(&quot; -&gt; &quot; + format.parse(form.format(myNumber)));
103 *         } catch (ParseException e) {
104 *         }
105 *     }
106 * }
107 * </pre>
108 *
109 * </blockquote>
110 * <h4>Patterns</h4>
111 * <p>
112 * A {@code DecimalFormat} consists of a <em>pattern</em> and a set of
113 * <em>symbols</em>. The pattern may be set directly using
114 * {@link #applyPattern(String)}, or indirectly using other API methods which
115 * manipulate aspects of the pattern, such as the minimum number of integer
116 * digits. The symbols are stored in a {@link DecimalFormatSymbols} object. When
117 * using the {@link NumberFormat} factory methods, the pattern and symbols are
118 * read from ICU's locale data.
119 * <h4>Special Pattern Characters</h4>
120 * <p>
121 * Many characters in a pattern are taken literally; they are matched during
122 * parsing and are written out unchanged during formatting. On the other hand,
123 * special characters stand for other characters, strings, or classes of
124 * characters. For example, the '#' character is replaced by a localized digit.
125 * Often the replacement character is the same as the pattern character; in the
126 * U.S. locale, the ',' grouping character is replaced by ','. However, the
127 * replacement is still happening, and if the symbols are modified, the grouping
128 * character changes. Some special characters affect the behavior of the
129 * formatter by their presence; for example, if the percent character is seen,
130 * then the value is multiplied by 100 before being displayed.
131 * <p>
132 * To insert a special character in a pattern as a literal, that is, without any
133 * special meaning, the character must be quoted. There are some exceptions to
134 * this which are noted below.
135 * <p>
136 * The characters listed here are used in non-localized patterns. Localized
137 * patterns use the corresponding characters taken from this formatter's
138 * {@link DecimalFormatSymbols} object instead, and these characters lose their
139 * special status. Two exceptions are the currency sign and quote, which are not
140 * localized.
141 * <blockquote> <table border="0" cellspacing="3" cellpadding="0" summary="Chart
142 * showing symbol, location, localized, and meaning.">
143 * <tr bgcolor="#ccccff">
144 * <th align="left">Symbol</th>
145 * <th align="left">Location</th>
146 * <th align="left">Localized?</th>
147 * <th align="left">Meaning</th>
148 * </tr>
149 * <tr valign="top">
150 * <td>{@code 0}</td>
151 * <td>Number</td>
152 * <td>Yes</td>
153 * <td>Digit.</td>
154 * </tr>
155 * <tr valign="top">
156 * <td>{@code @}</td>
157 * <td>Number</td>
158 * <td>No</td>
159 * <td><strong><font color="red">NEW</font>&nbsp;</strong> Significant
160 * digit.</td>
161 * </tr>
162 * <tr valign="top" bgcolor="#eeeeff">
163 * <td>{@code #}</td>
164 * <td>Number</td>
165 * <td>Yes</td>
166 * <td>Digit, leading zeroes are not shown.</td>
167 * </tr>
168 * <tr valign="top">
169 * <td>{@code .}</td>
170 * <td>Number</td>
171 * <td>Yes</td>
172 * <td>Decimal separator or monetary decimal separator.</td>
173 * </tr>
174 * <tr valign="top" bgcolor="#eeeeff">
175 * <td>{@code -}</td>
176 * <td>Number</td>
177 * <td>Yes</td>
178 * <td>Minus sign.</td>
179 * </tr>
180 * <tr valign="top">
181 * <td>{@code ,}</td>
182 * <td>Number</td>
183 * <td>Yes</td>
184 * <td>Grouping separator.</td>
185 * </tr>
186 * <tr valign="top" bgcolor="#eeeeff">
187 * <td>{@code E}</td>
188 * <td>Number</td>
189 * <td>Yes</td>
190 * <td>Separates mantissa and exponent in scientific notation.
191 * <em>Does not need to be quoted in prefix or suffix.</em></td>
192 * </tr>
193 * <tr valign="top">
194 * <td>{@code +}</td>
195 * <td>Exponent</td>
196 * <td>Yes</td>
197 * <td><strong><font color="red">NEW</font>&nbsp;</strong> Prefix
198 * positive exponents with localized plus sign.
199 * <em>Does not need to be quoted in prefix or suffix.</em></td>
200 * </tr>
201 * <tr valign="top" bgcolor="#eeeeff">
202 * <td>{@code ;}</td>
203 * <td>Subpattern boundary</td>
204 * <td>Yes</td>
205 * <td>Separates positive and negative subpatterns.</td>
206 * </tr>
207 * <tr valign="top">
208 * <td>{@code %}</td>
209 * <td>Prefix or suffix</td>
210 * <td>Yes</td>
211 * <td>Multiply by 100 and show as percentage.</td>
212 * </tr>
213 * <tr valign="top" bgcolor="#eeeeff">
214 * <td>{@code \u2030} ({@code &#92;u2030})</td>
215 * <td>Prefix or suffix</td>
216 * <td>Yes</td>
217 * <td>Multiply by 1000 and show as per mille.</td>
218 * </tr>
219 * <tr valign="top">
220 * <td>{@code &#164;} ({@code &#92;u00A4})</td>
221 * <td>Prefix or suffix</td>
222 * <td>No</td>
223 * <td>Currency sign, replaced by currency symbol. If doubled, replaced by
224 * international currency symbol. If present in a pattern, the monetary decimal
225 * separator is used instead of the decimal separator.</td>
226 * </tr>
227 * <tr valign="top" bgcolor="#eeeeff">
228 * <td>{@code '}</td>
229 * <td>Prefix or suffix</td>
230 * <td>No</td>
231 * <td>Used to quote special characters in a prefix or suffix, for example,
232 * {@code "'#'#"} formats 123 to {@code "#123"}. To create a single quote
233 * itself, use two in a row: {@code "# o''clock"}.</td>
234 * </tr>
235 * <tr valign="top">
236 * <td>{@code *}</td>
237 * <td>Prefix or suffix boundary</td>
238 * <td>Yes</td>
239 * <td><strong><font color="red">NEW</font>&nbsp;</strong> Pad escape,
240 * precedes pad character. </td>
241 * </tr>
242 * </table> </blockquote>
243 * <p>
244 * A {@code DecimalFormat} pattern contains a postive and negative subpattern,
245 * for example, "#,##0.00;(#,##0.00)". Each subpattern has a prefix, a numeric
246 * part and a suffix. If there is no explicit negative subpattern, the negative
247 * subpattern is the localized minus sign prefixed to the positive subpattern.
248 * That is, "0.00" alone is equivalent to "0.00;-0.00". If there is an explicit
249 * negative subpattern, it serves only to specify the negative prefix and
250 * suffix; the number of digits, minimal digits, and other characteristics are
251 * ignored in the negative subpattern. This means that "#,##0.0#;(#)" produces
252 * precisely the same result as "#,##0.0#;(#,##0.0#)".
253 * <p>
254 * The prefixes, suffixes, and various symbols used for infinity, digits,
255 * thousands separators, decimal separators, etc. may be set to arbitrary
256 * values, and they will appear properly during formatting. However, care must
257 * be taken that the symbols and strings do not conflict, or parsing will be
258 * unreliable. For example, either the positive and negative prefixes or the
259 * suffixes must be distinct for {@link #parse} to be able to distinguish
260 * positive from negative values. Another example is that the decimal separator
261 * and thousands separator should be distinct characters, or parsing will be
262 * impossible.
263 * <p>
264 * The <em>grouping separator</em> is a character that separates clusters of
265 * integer digits to make large numbers more legible. It is commonly used for
266 * thousands, but in some locales it separates ten-thousands. The <em>grouping
267 * size</em>
268 * is the number of digits between the grouping separators, such as 3 for
269 * "100,000,000" or 4 for "1 0000 0000". There are actually two different
270 * grouping sizes: One used for the least significant integer digits, the
271 * <em>primary grouping size</em>, and one used for all others, the
272 * <em>secondary grouping size</em>. In most locales these are the same, but
273 * sometimes they are different. For example, if the primary grouping interval
274 * is 3, and the secondary is 2, then this corresponds to the pattern
275 * "#,##,##0", and the number 123456789 is formatted as "12,34,56,789". If a
276 * pattern contains multiple grouping separators, the interval between the last
277 * one and the end of the integer defines the primary grouping size, and the
278 * interval between the last two defines the secondary grouping size. All others
279 * are ignored, so "#,##,###,####", "###,###,####" and "##,#,###,####" produce
280 * the same result.
281 * <p>
282 * Illegal patterns, such as "#.#.#" or "#.###,###", will cause
283 * {@code DecimalFormat} to throw an {@link IllegalArgumentException} with a
284 * message that describes the problem.
285 * <h4>Pattern BNF</h4>
286 *
287 * <pre>
288 * pattern    := subpattern (';' subpattern)?
289 * subpattern := prefix? number exponent? suffix?
290 * number     := (integer ('.' fraction)?) | sigDigits
291 * prefix     := '\\u0000'..'\\uFFFD' - specialCharacters
292 * suffix     := '\\u0000'..'\\uFFFD' - specialCharacters
293 * integer    := '#'* '0'* '0'
294 * fraction   := '0'* '#'*
295 * sigDigits  := '#'* '@' '@'* '#'*
296 * exponent   := 'E' '+'? '0'* '0'
297 * padSpec    := '*' padChar
298 * padChar    := '\\u0000'..'\\uFFFD' - quote
299 *
300 * Notation:
301 *   X*       0 or more instances of X
302 *   X?       0 or 1 instances of X
303 *   X|Y      either X or Y
304 *   C..D     any character from C up to D, inclusive
305 *   S-T      characters in S, except those in T
306 * </pre>
307 *
308 * The first subpattern is for positive numbers. The second (optional)
309 * subpattern is for negative numbers.
310 * <p>
311 * Not indicated in the BNF syntax above:
312 * <ul>
313 * <li>The grouping separator ',' can occur inside the integer and sigDigits
314 * elements, between any two pattern characters of that element, as long as the
315 * integer or sigDigits element is not followed by the exponent element.
316 * <li><font color="red"><strong>NEW</strong>&nbsp;</font> Two
317 * grouping intervals are recognized: The one between the decimal point and the
318 * first grouping symbol and the one between the first and second grouping
319 * symbols. These intervals are identical in most locales, but in some locales
320 * they differ. For example, the pattern &quot;#,##,###&quot; formats the number
321 * 123456789 as &quot;12,34,56,789&quot;.</li>
322 * <li> <strong><font color="red">NEW</font>&nbsp;</strong> The pad
323 * specifier {@code padSpec} may appear before the prefix, after the prefix,
324 * before the suffix, after the suffix or not at all.
325 * </ul>
326 * <h4>Parsing</h4>
327 * <p>
328 * {@code DecimalFormat} parses all Unicode characters that represent decimal
329 * digits, as defined by {@link Character#digit(int, int)}. In addition,
330 * {@code DecimalFormat} also recognizes as digits the ten consecutive
331 * characters starting with the localized zero digit defined in the
332 * {@link DecimalFormatSymbols} object. During formatting, the
333 * {@link DecimalFormatSymbols}-based digits are written out.
334 * <p>
335 * During parsing, grouping separators are ignored.
336 * <p>
337 * If {@link #parse(String, ParsePosition)} fails to parse a string, it returns
338 * {@code null} and leaves the parse position unchanged.
339 * <h4>Formatting</h4>
340 * <p>
341 * Formatting is guided by several parameters, all of which can be specified
342 * either using a pattern or using the API. The following description applies to
343 * formats that do not use <a href="#sci">scientific notation</a> or <a
344 * href="#sigdig">significant digits</a>.
345 * <ul>
346 * <li>If the number of actual integer digits exceeds the
347 * <em>maximum integer digits</em>, then only the least significant digits
348 * are shown. For example, 1997 is formatted as "97" if maximum integer digits
349 * is set to 2.
350 * <li>If the number of actual integer digits is less than the
351 * <em>minimum integer digits</em>, then leading zeros are added. For
352 * example, 1997 is formatted as "01997" if minimum integer digits is set to 5.
353 * <li>If the number of actual fraction digits exceeds the <em>maximum
354 * fraction digits</em>,
355 * then half-even rounding is performed to the maximum fraction digits. For
356 * example, 0.125 is formatted as "0.12" if the maximum fraction digits is 2.
357 * <li>If the number of actual fraction digits is less than the
358 * <em>minimum fraction digits</em>, then trailing zeros are added. For
359 * example, 0.125 is formatted as "0.1250" if the mimimum fraction digits is set
360 * to 4.
361 * <li>Trailing fractional zeros are not displayed if they occur <em>j</em>
362 * positions after the decimal, where <em>j</em> is less than the maximum
363 * fraction digits. For example, 0.10004 is formatted as "0.1" if the maximum
364 * fraction digits is four or less.
365 * </ul>
366 * <p>
367 * <strong>Special Values</strong>
368 * <p>
369 * {@code NaN} is represented as a single character, typically
370 * {@code &#92;uFFFD}. This character is determined by the
371 * {@link DecimalFormatSymbols} object. This is the only value for which the
372 * prefixes and suffixes are not used.
373 * <p>
374 * Infinity is represented as a single character, typically {@code &#92;u221E},
375 * with the positive or negative prefixes and suffixes applied. The infinity
376 * character is determined by the {@link DecimalFormatSymbols} object. <a
377 * name="sci">
378 * <h4>Scientific Notation</h4>
379 * </a>
380 * <p>
381 * Numbers in scientific notation are expressed as the product of a mantissa and
382 * a power of ten, for example, 1234 can be expressed as 1.234 x 10<sup>3</sup>.
383 * The mantissa is typically in the half-open interval [1.0, 10.0) or sometimes
384 * [0.0, 1.0), but it does not need to be. {@code DecimalFormat} supports
385 * arbitrary mantissas. {@code DecimalFormat} can be instructed to use
386 * scientific notation through the API or through the pattern. In a pattern, the
387 * exponent character immediately followed by one or more digit characters
388 * indicates scientific notation. Example: "0.###E0" formats the number 1234 as
389 * "1.234E3".
390 * <ul>
391 * <li>The number of digit characters after the exponent character gives the
392 * minimum exponent digit count. There is no maximum. Negative exponents are
393 * formatted using the localized minus sign, <em>not</em> the prefix and
394 * suffix from the pattern. This allows patterns such as "0.###E0 m/s". To
395 * prefix positive exponents with a localized plus sign, specify '+' between the
396 * exponent and the digits: "0.###E+0" will produce formats "1E+1", "1E+0",
397 * "1E-1", etc. (In localized patterns, use the localized plus sign rather than
398 * '+'.)
399 * <li>The minimum number of integer digits is achieved by adjusting the
400 * exponent. Example: 0.00123 formatted with "00.###E0" yields "12.3E-4". This
401 * only happens if there is no maximum number of integer digits. If there is a
402 * maximum, then the minimum number of integer digits is fixed at one.
403 * <li>The maximum number of integer digits, if present, specifies the exponent
404 * grouping. The most common use of this is to generate <em>engineering
405 * notation</em>,
406 * in which the exponent is a multiple of three, e.g., "##0.###E0". The number
407 * 12345 is formatted using "##0.###E0" as "12.345E3".
408 * <li>When using scientific notation, the formatter controls the digit counts
409 * using significant digits logic. The maximum number of significant digits
410 * limits the total number of integer and fraction digits that will be shown in
411 * the mantissa; it does not affect parsing. For example, 12345 formatted with
412 * "##0.##E0" is "12.3E3". See the section on significant digits for more
413 * details.
414 * <li>The number of significant digits shown is determined as follows: If no
415 * significant digits are used in the pattern then the minimum number of
416 * significant digits shown is one, the maximum number of significant digits
417 * shown is the sum of the <em>minimum integer</em> and
418 * <em>maximum fraction</em> digits, and it is unaffected by the maximum
419 * integer digits. If this sum is zero, then all significant digits are shown.
420 * If significant digits are used in the pattern then the number of integer
421 * digits is fixed at one and there is no exponent grouping.
422 * <li>Exponential patterns may not contain grouping separators.
423 * </ul>
424 * <a name="sigdig">
425 * <h4> <strong><font color="red">NEW</font>&nbsp;</strong> Significant
426 * Digits</h4>
427 * <p>
428 * </a> {@code DecimalFormat} has two ways of controlling how many digits are
429 * shown: (a) significant digit counts or (b) integer and fraction digit counts.
430 * Integer and fraction digit counts are described above. When a formatter uses
431 * significant digits counts, the number of integer and fraction digits is not
432 * specified directly, and the formatter settings for these counts are ignored.
433 * Instead, the formatter uses as many integer and fraction digits as required
434 * to display the specified number of significant digits.
435 * <h5>Examples:</h5>
436 * <blockquote> <table border=0 cellspacing=3 cellpadding=0>
437 * <tr bgcolor="#ccccff">
438 * <th align="left">Pattern</th>
439 * <th align="left">Minimum significant digits</th>
440 * <th align="left">Maximum significant digits</th>
441 * <th align="left">Number</th>
442 * <th align="left">Output of format()</th>
443 * </tr>
444 * <tr valign="top">
445 * <td>{@code @@@}
446 * <td>3</td>
447 * <td>3</td>
448 * <td>12345</td>
449 * <td>{@code 12300}</td>
450 * </tr>
451 * <tr valign="top" bgcolor="#eeeeff">
452 * <td>{@code @@@}</td>
453 * <td>3</td>
454 * <td>3</td>
455 * <td>0.12345</td>
456 * <td>{@code 0.123}</td>
457 * </tr>
458 * <tr valign="top">
459 * <td>{@code @@##}</td>
460 * <td>2</td>
461 * <td>4</td>
462 * <td>3.14159</td>
463 * <td>{@code 3.142}</td>
464 * </tr>
465 * <tr valign="top" bgcolor="#eeeeff">
466 * <td>{@code @@##}</td>
467 * <td>2</td>
468 * <td>4</td>
469 * <td>1.23004</td>
470 * <td>{@code 1.23}</td>
471 * </tr>
472 * </table> </blockquote>
473 * <ul>
474 * <li>Significant digit counts may be expressed using patterns that specify a
475 * minimum and maximum number of significant digits. These are indicated by the
476 * {@code '@'} and {@code '#'} characters. The minimum number of significant
477 * digits is the number of {@code '@'} characters. The maximum number of
478 * significant digits is the number of {@code '@'} characters plus the number of
479 * {@code '#'} characters following on the right. For example, the pattern
480 * {@code "@@@"} indicates exactly 3 significant digits. The pattern
481 * {@code "@##"} indicates from 1 to 3 significant digits. Trailing zero digits
482 * to the right of the decimal separator are suppressed after the minimum number
483 * of significant digits have been shown. For example, the pattern {@code "@##"}
484 * formats the number 0.1203 as {@code "0.12"}.
485 * <li>If a pattern uses significant digits, it may not contain a decimal
486 * separator, nor the {@code '0'} pattern character. Patterns such as
487 * {@code "@00"} or {@code "@.###"} are disallowed.
488 * <li>Any number of {@code '#'} characters may be prepended to the left of the
489 * leftmost {@code '@'} character. These have no effect on the minimum and
490 * maximum significant digit counts, but may be used to position grouping
491 * separators. For example, {@code "#,#@#"} indicates a minimum of one
492 * significant digit, a maximum of two significant digits, and a grouping size
493 * of three.
494 * <li>In order to enable significant digits formatting, use a pattern
495 * containing the {@code '@'} pattern character.
496 * <li>In order to disable significant digits formatting, use a pattern that
497 * does not contain the {@code '@'} pattern character.
498 * <li>The number of significant digits has no effect on parsing.
499 * <li>Significant digits may be used together with exponential notation. Such
500 * patterns are equivalent to a normal exponential pattern with a minimum and
501 * maximum integer digit count of one, a minimum fraction digit count of the
502 * number of '@' characters in the pattern - 1, and a maximum fraction digit
503 * count of the number of '@' and '#' characters in the pattern - 1. For
504 * example, the pattern {@code "@@###E0"} is equivalent to {@code "0.0###E0"}.
505 * <li>If signficant digits are in use then the integer and fraction digit
506 * counts, as set via the API, are ignored.
507 * </ul>
508 * <h4> <strong><font color="red">NEW</font>&nbsp;</strong> Padding</h4>
509 * <p>
510 * {@code DecimalFormat} supports padding the result of {@code format} to a
511 * specific width. Padding may be specified either through the API or through
512 * the pattern syntax. In a pattern, the pad escape character followed by a
513 * single pad character causes padding to be parsed and formatted. The pad
514 * escape character is '*' in unlocalized patterns. For example,
515 * {@code "$*x#,##0.00"} formats 123 to {@code "$xx123.00"}, and 1234 to
516 * {@code "$1,234.00"}.
517 * <ul>
518 * <li>When padding is in effect, the width of the positive subpattern,
519 * including prefix and suffix, determines the format width. For example, in the
520 * pattern {@code "* #0 o''clock"}, the format width is 10.</li>
521 * <li>The width is counted in 16-bit code units (Java {@code char}s).</li>
522 * <li>Some parameters which usually do not matter have meaning when padding is
523 * used, because the pattern width is significant with padding. In the pattern "*
524 * ##,##,#,##0.##", the format width is 14. The initial characters "##,##," do
525 * not affect the grouping size or maximum integer digits, but they do affect
526 * the format width.</li>
527 * <li>Padding may be inserted at one of four locations: before the prefix,
528 * after the prefix, before the suffix or after the suffix. If padding is
529 * specified in any other location, {@link #applyPattern} throws an {@link
530 * IllegalArgumentException}. If there is no prefix, before the prefix and after
531 * the prefix are equivalent, likewise for the suffix.</li>
532 * <li>When specified in a pattern, the 16-bit {@code char} immediately
533 * following the pad escape is the pad character. This may be any character,
534 * including a special pattern character. That is, the pad escape
535 * <em>escapes</em> the following character. If there is no character after
536 * the pad escape, then the pattern is illegal.</li>
537 * </ul>
538 * <h4>Synchronization</h4>
539 * <p>
540 * {@code DecimalFormat} objects are not synchronized. Multiple threads should
541 * not access one formatter concurrently.
542 *
543 * @see Format
544 * @see NumberFormat
545 */
546public class DecimalFormat extends NumberFormat {
547
548    private static final long serialVersionUID = 864413376551465018L;
549
550    private transient boolean parseBigDecimal = false;
551
552    private transient DecimalFormatSymbols symbols;
553
554    private transient NativeDecimalFormat dform;
555
556    /**
557     * Constructs a new {@code DecimalFormat} for formatting and parsing numbers
558     * for the default locale.
559     */
560    public DecimalFormat() {
561        // BEGIN android-changed: reduce duplication.
562        Locale locale = Locale.getDefault();
563        this.symbols = new DecimalFormatSymbols(locale);
564        LocaleData localeData = com.ibm.icu4jni.util.Resources.getLocaleData(locale);
565        initNative(localeData.numberPattern);
566        // END android-changed
567    }
568
569    /**
570     * Constructs a new {@code DecimalFormat} using the specified non-localized
571     * pattern and the {@code DecimalFormatSymbols} for the default Locale.
572     *
573     * @param pattern
574     *            the non-localized pattern.
575     * @throws IllegalArgumentException
576     *            if the pattern cannot be parsed.
577     */
578    public DecimalFormat(String pattern) {
579        // BEGIN android-changed: reduce duplication.
580        this(pattern, Locale.getDefault());
581        // END android-changed
582    }
583
584    /**
585     * Constructs a new {@code DecimalFormat} using the specified non-localized
586     * pattern and {@code DecimalFormatSymbols}.
587     *
588     * @param pattern
589     *            the non-localized pattern.
590     * @param value
591     *            the DecimalFormatSymbols.
592     * @throws IllegalArgumentException
593     *            if the pattern cannot be parsed.
594     */
595    public DecimalFormat(String pattern, DecimalFormatSymbols value) {
596        // BEGIN android-changed: reduce duplication.
597        this.symbols = (DecimalFormatSymbols) value.clone();
598        initNative(pattern);
599        // END android-changed
600    }
601
602    // BEGIN android-added: used by NumberFormat.getInstance because cloning DecimalFormatSymbols is slow.
603    DecimalFormat(String pattern, Locale locale) {
604        this.symbols = new DecimalFormatSymbols(locale);
605        initNative(pattern);
606    }
607    // END android-added
608
609    // BEGIN android-changed: reduce duplication.
610    private void initNative(String pattern) {
611        try {
612            this.dform = new NativeDecimalFormat(pattern, symbols);
613        } catch (IllegalArgumentException ex) {
614            throw new IllegalArgumentException(pattern);
615        }
616        super.setMaximumFractionDigits(dform.getMaximumFractionDigits());
617        super.setMaximumIntegerDigits(dform.getMaximumIntegerDigits());
618        super.setMinimumFractionDigits(dform.getMinimumFractionDigits());
619        super.setMinimumIntegerDigits(dform.getMinimumIntegerDigits());
620    }
621    // END android-added
622
623    /**
624     * Changes the pattern of this decimal format to the specified pattern which
625     * uses localized pattern characters.
626     *
627     * @param pattern
628     *            the localized pattern.
629     * @throws IllegalArgumentException
630     *            if the pattern cannot be parsed.
631     */
632    public void applyLocalizedPattern(String pattern) {
633        dform.applyLocalizedPattern(pattern);
634    }
635
636    /**
637     * Changes the pattern of this decimal format to the specified pattern which
638     * uses non-localized pattern characters.
639     *
640     * @param pattern
641     *            the non-localized pattern.
642     * @throws IllegalArgumentException
643     *            if the pattern cannot be parsed.
644     */
645    public void applyPattern(String pattern) {
646        dform.applyPattern(pattern);
647    }
648
649    /**
650     * Returns a new instance of {@code DecimalFormat} with the same pattern and
651     * properties as this decimal format.
652     *
653     * @return a shallow copy of this decimal format.
654     * @see java.lang.Cloneable
655     */
656    @Override
657    public Object clone() {
658        DecimalFormat clone = (DecimalFormat) super.clone();
659        clone.dform = (NativeDecimalFormat) dform.clone();
660        clone.symbols = (DecimalFormatSymbols) symbols.clone();
661        return clone;
662    }
663
664    /**
665     * Compares the specified object to this decimal format and indicates if
666     * they are equal. In order to be equal, {@code object} must be an instance
667     * of {@code DecimalFormat} with the same pattern and properties.
668     *
669     * @param object
670     *            the object to compare with this object.
671     * @return {@code true} if the specified object is equal to this decimal
672     *         format; {@code false} otherwise.
673     * @see #hashCode
674     */
675    @Override
676    public boolean equals(Object object) {
677        if (this == object) {
678            return true;
679        }
680        if (!(object instanceof DecimalFormat)) {
681            return false;
682        }
683        DecimalFormat other = (DecimalFormat) object;
684        return (this.dform == null ? other.dform == null : this.dform.equals(other.dform)) &&
685                getDecimalFormatSymbols().equals(other.getDecimalFormatSymbols());
686    }
687
688    /**
689     * Formats the specified object using the rules of this decimal format and
690     * returns an {@code AttributedCharacterIterator} with the formatted number
691     * and attributes.
692     *
693     * @param object
694     *            the object to format.
695     * @return an AttributedCharacterIterator with the formatted number and
696     *         attributes.
697     * @throws IllegalArgumentException
698     *             if {@code object} cannot be formatted by this format.
699     * @throws NullPointerException
700     *             if {@code object} is {@code null}.
701     */
702    @Override
703    public AttributedCharacterIterator formatToCharacterIterator(Object object) {
704        if (object == null) {
705            throw new NullPointerException();
706        }
707        return dform.formatToCharacterIterator(object);
708    }
709
710    @Override
711    public StringBuffer format(double value, StringBuffer buffer, FieldPosition position) {
712        return dform.format(value, buffer, position);
713    }
714
715    @Override
716    public StringBuffer format(long value, StringBuffer buffer, FieldPosition position) {
717        return dform.format(value, buffer, position);
718    }
719
720    @Override
721    public final StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
722        if (number instanceof BigInteger) {
723            BigInteger bigInteger = (BigInteger) number;
724            if (bigInteger.bitLength() < 64) {
725                return dform.format(bigInteger.longValue(), toAppendTo, pos);
726            } else {
727                return dform.formatBigInteger(bigInteger, toAppendTo, pos);
728            }
729        } else if (number instanceof BigDecimal) {
730            return dform.formatBigDecimal((BigDecimal) number, toAppendTo, pos);
731        }
732        return super.format(number, toAppendTo, pos);
733    }
734
735    /**
736     * Returns the {@code DecimalFormatSymbols} used by this decimal format.
737     *
738     * @return a copy of the {@code DecimalFormatSymbols} used by this decimal
739     *         format.
740     */
741    public DecimalFormatSymbols getDecimalFormatSymbols() {
742        return (DecimalFormatSymbols) symbols.clone();
743    }
744
745    /**
746     * Returns the currency used by this decimal format.
747     *
748     * @return the currency used by this decimal format.
749     * @see DecimalFormatSymbols#getCurrency()
750     */
751    @Override
752    public Currency getCurrency() {
753        return symbols.getCurrency();
754    }
755
756    /**
757     * Returns the number of digits grouped together by the grouping separator.
758     * This only allows to get the primary grouping size. There is no API to get
759     * the secondary grouping size.
760     *
761     * @return the number of digits grouped together.
762     */
763    public int getGroupingSize() {
764        return dform.getGroupingSize();
765    }
766
767    /**
768     * Returns the multiplier which is applied to the number before formatting
769     * or after parsing.
770     *
771     * @return the multiplier.
772     */
773    public int getMultiplier() {
774        return dform.getMultiplier();
775    }
776
777    /**
778     * Returns the prefix which is formatted or parsed before a negative number.
779     *
780     * @return the negative prefix.
781     */
782    public String getNegativePrefix() {
783        return dform.getNegativePrefix();
784    }
785
786    /**
787     * Returns the suffix which is formatted or parsed after a negative number.
788     *
789     * @return the negative suffix.
790     */
791    public String getNegativeSuffix() {
792        return dform.getNegativeSuffix();
793    }
794
795    /**
796     * Returns the prefix which is formatted or parsed before a positive number.
797     *
798     * @return the positive prefix.
799     */
800    public String getPositivePrefix() {
801        return dform.getPositivePrefix();
802    }
803
804    /**
805     * Returns the suffix which is formatted or parsed after a positive number.
806     *
807     * @return the positive suffix.
808     */
809    public String getPositiveSuffix() {
810        return dform.getPositiveSuffix();
811    }
812
813    @Override
814    public int hashCode() {
815        return dform.hashCode();
816    }
817
818    /**
819     * Indicates whether the decimal separator is shown when there are no
820     * fractional digits.
821     *
822     * @return {@code true} if the decimal separator should always be formatted;
823     *         {@code false} otherwise.
824     */
825    public boolean isDecimalSeparatorAlwaysShown() {
826        return dform.isDecimalSeparatorAlwaysShown();
827    }
828
829    /**
830     * This value indicates whether the return object of the parse operation is
831     * of type {@code BigDecimal}. This value defaults to {@code false}.
832     *
833     * @return {@code true} if parse always returns {@code BigDecimals},
834     *         {@code false} if the type of the result is {@code Long} or
835     *         {@code Double}.
836     */
837    public boolean isParseBigDecimal() {
838        return this.parseBigDecimal;
839    }
840
841    /**
842     * Sets the flag that indicates whether numbers will be parsed as integers.
843     * When this decimal format is used for parsing and this value is set to
844     * {@code true}, then the resulting numbers will be of type
845     * {@code java.lang.Integer}. Special cases are NaN, positive and negative
846     * infinity, which are still returned as {@code java.lang.Double}.
847     *
848     *
849     * @param value
850     *            {@code true} that the resulting numbers of parse operations
851     *            will be of type {@code java.lang.Integer} except for the
852     *            special cases described above.
853     */
854    @Override
855    public void setParseIntegerOnly(boolean value) {
856        // In this implementation, NativeDecimalFormat is wrapped to
857        // fulfill most of the format and parse feature. And this method is
858        // delegated to the wrapped instance of NativeDecimalFormat.
859        dform.setParseIntegerOnly(value);
860    }
861
862    /**
863     * Indicates whether parsing with this decimal format will only
864     * return numbers of type {@code java.lang.Integer}.
865     *
866     * @return {@code true} if this {@code DecimalFormat}'s parse method only
867     *         returns {@code java.lang.Integer}; {@code false} otherwise.
868     */
869    @Override
870    public boolean isParseIntegerOnly() {
871        return dform.isParseIntegerOnly();
872    }
873
874    private static final Double NEGATIVE_ZERO_DOUBLE = new Double(-0.0);
875
876    /**
877     * Parses a {@code Long} or {@code Double} from the specified string
878     * starting at the index specified by {@code position}. If the string is
879     * successfully parsed then the index of the {@code ParsePosition} is
880     * updated to the index following the parsed text. On error, the index is
881     * unchanged and the error index of {@code ParsePosition} is set to the
882     * index where the error occurred.
883     *
884     * @param string
885     *            the string to parse.
886     * @param position
887     *            input/output parameter, specifies the start index in
888     *            {@code string} from where to start parsing. If parsing is
889     *            successful, it is updated with the index following the parsed
890     *            text; on error, the index is unchanged and the error index is
891     *            set to the index where the error occurred.
892     * @return a {@code Long} or {@code Double} resulting from the parse or
893     *         {@code null} if there is an error. The result will be a
894     *         {@code Long} if the parsed number is an integer in the range of a
895     *         long, otherwise the result is a {@code Double}. If
896     *         {@code isParseBigDecimal} is {@code true} then it returns the
897     *         result as a {@code BigDecimal}.
898     */
899    @Override
900    public Number parse(String string, ParsePosition position) {
901        Number number = dform.parse(string, position);
902        if (null == number) {
903            return null;
904        }
905        // BEGIN android-removed
906        // if (this.isParseBigDecimal()) {
907        //     if (number instanceof Long) {
908        //         return new BigDecimal(number.longValue());
909        //     }
910        //     if ((number instanceof Double) && !((Double) number).isInfinite()
911        //             && !((Double) number).isNaN()) {
912        //
913        //         return new BigDecimal(number.doubleValue());
914        //     }
915        //     if (number instanceof BigInteger) {
916        //         return new BigDecimal(number.doubleValue());
917        //     }
918        //     if (number instanceof com.ibm.icu.math.BigDecimal) {
919        //         return new BigDecimal(number.toString());
920        //     }
921        //     return number;
922        // }
923        // if ((number instanceof com.ibm.icu.math.BigDecimal)
924        //         || (number instanceof BigInteger)) {
925        //     return new Double(number.doubleValue());
926        // }
927        // END android-removed
928        // BEGIN android-added
929        if (this.isParseBigDecimal()) {
930            if (number instanceof Long) {
931                return new BigDecimal(number.longValue());
932            }
933            if ((number instanceof Double) && !((Double) number).isInfinite()
934                    && !((Double) number).isNaN()) {
935
936                return new BigDecimal(number.toString());
937            }
938            if (number instanceof BigInteger) {
939                return new BigDecimal(number.toString());
940            }
941            return number;
942        }
943        if ((number instanceof BigDecimal) || (number instanceof BigInteger)) {
944            return new Double(number.doubleValue());
945        }
946        // END android-added
947
948        if (this.isParseIntegerOnly() && number.equals(NEGATIVE_ZERO_DOUBLE)) {
949            return Long.valueOf(0); // android-changed
950        }
951        return number;
952
953    }
954
955    /**
956     * Sets the {@code DecimalFormatSymbols} used by this decimal format.
957     *
958     * @param value
959     *            the {@code DecimalFormatSymbols} to set.
960     */
961    public void setDecimalFormatSymbols(DecimalFormatSymbols value) {
962        if (value != null) {
963            // BEGIN android-changed: the Java object is canonical, and we copy down to native code.
964            this.symbols = (DecimalFormatSymbols) value.clone();
965            dform.setDecimalFormatSymbols(this.symbols);
966            // END android-changed
967        }
968    }
969
970    /**
971     * Sets the currency used by this decimal format. The min and max fraction
972     * digits remain the same.
973     *
974     * @param currency
975     *            the currency this {@code DecimalFormat} should use.
976     * @see DecimalFormatSymbols#setCurrency(Currency)
977     */
978    @Override
979    public void setCurrency(Currency currency) {
980        // BEGIN android-changed
981        dform.setCurrency(Currency.getInstance(currency.getCurrencyCode()));
982        // END android-changed
983        symbols.setCurrency(currency);
984    }
985
986    /**
987     * Sets whether the decimal separator is shown when there are no fractional
988     * digits.
989     *
990     * @param value
991     *            {@code true} if the decimal separator should always be
992     *            formatted; {@code false} otherwise.
993     */
994    public void setDecimalSeparatorAlwaysShown(boolean value) {
995        dform.setDecimalSeparatorAlwaysShown(value);
996    }
997
998    /**
999     * Sets the number of digits grouped together by the grouping separator.
1000     * This only allows to set the primary grouping size; the secondary grouping
1001     * size can only be set with a pattern.
1002     *
1003     * @param value
1004     *            the number of digits grouped together.
1005     */
1006    public void setGroupingSize(int value) {
1007        dform.setGroupingSize(value);
1008    }
1009
1010    /**
1011     * Sets whether or not grouping will be used in this format. Grouping
1012     * affects both parsing and formatting.
1013     *
1014     * @param value
1015     *            {@code true} if grouping is used; {@code false} otherwise.
1016     */
1017    @Override
1018    public void setGroupingUsed(boolean value) {
1019        dform.setGroupingUsed(value);
1020    }
1021
1022    /**
1023     * Indicates whether grouping will be used in this format.
1024     *
1025     * @return {@code true} if grouping is used; {@code false} otherwise.
1026     */
1027    @Override
1028    public boolean isGroupingUsed() {
1029        return dform.isGroupingUsed();
1030    }
1031
1032    /**
1033     * Sets the maximum number of digits after the decimal point.
1034     * If the value passed is negative then it is replaced by 0.
1035     * Regardless of this setting, no more than 340 digits will be used.
1036     *
1037     * @param value the maximum number of fraction digits.
1038     */
1039    @Override
1040    public void setMaximumFractionDigits(int value) {
1041        super.setMaximumFractionDigits(value);
1042        dform.setMaximumFractionDigits(getMaximumFractionDigits());
1043    }
1044
1045    /**
1046     * Sets the maximum number of digits before the decimal point.
1047     * If the value passed is negative then it is replaced by 0.
1048     * Regardless of this setting, no more than 309 digits will be used.
1049     *
1050     * @param value the maximum number of integer digits.
1051     */
1052    @Override
1053    public void setMaximumIntegerDigits(int value) {
1054        super.setMaximumIntegerDigits(value);
1055        dform.setMaximumIntegerDigits(getMaximumIntegerDigits());
1056    }
1057
1058    /**
1059     * Sets the minimum number of digits after the decimal point.
1060     * If the value passed is negative then it is replaced by 0.
1061     * Regardless of this setting, no more than 340 digits will be used.
1062     *
1063     * @param value the minimum number of fraction digits.
1064     */
1065    @Override
1066    public void setMinimumFractionDigits(int value) {
1067        super.setMinimumFractionDigits(value);
1068        dform.setMinimumFractionDigits(getMinimumFractionDigits());
1069    }
1070
1071    /**
1072     * Sets the minimum number of digits before the decimal point.
1073     * If the value passed is negative then it is replaced by 0.
1074     * Regardless of this setting, no more than 309 digits will be used.
1075     *
1076     * @param value the minimum number of integer digits.
1077     */
1078    @Override
1079    public void setMinimumIntegerDigits(int value) {
1080        super.setMinimumIntegerDigits(value);
1081        dform.setMinimumIntegerDigits(getMinimumIntegerDigits());
1082    }
1083
1084    /**
1085     * Sets the multiplier which is applied to the number before formatting or
1086     * after parsing.
1087     *
1088     * @param value
1089     *            the multiplier.
1090     */
1091    public void setMultiplier(int value) {
1092        dform.setMultiplier(value);
1093    }
1094
1095    /**
1096     * Sets the prefix which is formatted or parsed before a negative number.
1097     *
1098     * @param value
1099     *            the negative prefix.
1100     */
1101    public void setNegativePrefix(String value) {
1102        dform.setNegativePrefix(value);
1103    }
1104
1105    /**
1106     * Sets the suffix which is formatted or parsed after a negative number.
1107     *
1108     * @param value
1109     *            the negative suffix.
1110     */
1111    public void setNegativeSuffix(String value) {
1112        dform.setNegativeSuffix(value);
1113    }
1114
1115    /**
1116     * Sets the prefix which is formatted or parsed before a positive number.
1117     *
1118     * @param value
1119     *            the positive prefix.
1120     */
1121    public void setPositivePrefix(String value) {
1122        dform.setPositivePrefix(value);
1123    }
1124
1125    /**
1126     * Sets the suffix which is formatted or parsed after a positive number.
1127     *
1128     * @param value
1129     *            the positive suffix.
1130     */
1131    public void setPositiveSuffix(String value) {
1132        dform.setPositiveSuffix(value);
1133    }
1134
1135    /**
1136     * Sets the behaviour of the parse method. If set to {@code true} then all
1137     * the returned objects will be of type {@code BigDecimal}.
1138     *
1139     * @param newValue
1140     *            {@code true} if all the returned objects should be of type
1141     *            {@code BigDecimal}; {@code false} otherwise.
1142     */
1143    public void setParseBigDecimal(boolean newValue) {
1144        this.parseBigDecimal = newValue;
1145    }
1146
1147    /**
1148     * Returns the pattern of this decimal format using localized pattern
1149     * characters.
1150     *
1151     * @return the localized pattern.
1152     */
1153    public String toLocalizedPattern() {
1154        return dform.toLocalizedPattern();
1155    }
1156
1157    /**
1158     * Returns the pattern of this decimal format using non-localized pattern
1159     * characters.
1160     *
1161     * @return the non-localized pattern.
1162     */
1163    public String toPattern() {
1164        return dform.toPattern();
1165    }
1166
1167    // the fields list to be serialized
1168    private static final ObjectStreamField[] serialPersistentFields = {
1169            new ObjectStreamField("positivePrefix", String.class), //$NON-NLS-1$
1170            new ObjectStreamField("positiveSuffix", String.class), //$NON-NLS-1$
1171            new ObjectStreamField("negativePrefix", String.class), //$NON-NLS-1$
1172            new ObjectStreamField("negativeSuffix", String.class), //$NON-NLS-1$
1173            new ObjectStreamField("posPrefixPattern", String.class), //$NON-NLS-1$
1174            new ObjectStreamField("posSuffixPattern", String.class), //$NON-NLS-1$
1175            new ObjectStreamField("negPrefixPattern", String.class), //$NON-NLS-1$
1176            new ObjectStreamField("negSuffixPattern", String.class), //$NON-NLS-1$
1177            new ObjectStreamField("multiplier", int.class), //$NON-NLS-1$
1178            new ObjectStreamField("groupingSize", byte.class), //$NON-NLS-1$
1179            // BEGIN android-added
1180            new ObjectStreamField("groupingUsed", boolean.class), //$NON-NLS-1$
1181            // END android-added
1182            new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class), //$NON-NLS-1$
1183            new ObjectStreamField("parseBigDecimal", boolean.class), //$NON-NLS-1$
1184            new ObjectStreamField("symbols", DecimalFormatSymbols.class), //$NON-NLS-1$
1185            new ObjectStreamField("useExponentialNotation", boolean.class), //$NON-NLS-1$
1186            new ObjectStreamField("minExponentDigits", byte.class), //$NON-NLS-1$
1187            new ObjectStreamField("maximumIntegerDigits", int.class), //$NON-NLS-1$
1188            new ObjectStreamField("minimumIntegerDigits", int.class), //$NON-NLS-1$
1189            new ObjectStreamField("maximumFractionDigits", int.class), //$NON-NLS-1$
1190            new ObjectStreamField("minimumFractionDigits", int.class), //$NON-NLS-1$
1191            new ObjectStreamField("serialVersionOnStream", int.class), }; //$NON-NLS-1$
1192
1193    /**
1194     * Writes serialized fields following serialized forms specified by Java
1195     * specification.
1196     *
1197     * @param stream
1198     *            the output stream to write serialized bytes
1199     * @throws IOException
1200     *             if some I/O error occurs
1201     * @throws ClassNotFoundException
1202     */
1203    @SuppressWarnings("nls")
1204    private void writeObject(ObjectOutputStream stream) throws IOException,
1205            ClassNotFoundException {
1206        ObjectOutputStream.PutField fields = stream.putFields();
1207        fields.put("positivePrefix", dform.getPositivePrefix());
1208        fields.put("positiveSuffix", dform.getPositiveSuffix());
1209        fields.put("negativePrefix", dform.getNegativePrefix());
1210        fields.put("negativeSuffix", dform.getNegativeSuffix());
1211        fields.put("posPrefixPattern", (String) null);
1212        fields.put("posSuffixPattern", (String) null);
1213        fields.put("negPrefixPattern", (String) null);
1214        fields.put("negSuffixPattern", (String) null);
1215        fields.put("multiplier", dform.getMultiplier());
1216        fields.put("groupingSize", (byte) dform.getGroupingSize());
1217        // BEGIN android-added
1218        fields.put("groupingUsed", dform.isGroupingUsed());
1219        // END android-added
1220        fields.put("decimalSeparatorAlwaysShown", dform
1221                .isDecimalSeparatorAlwaysShown());
1222        fields.put("parseBigDecimal", parseBigDecimal);
1223        fields.put("symbols", symbols);
1224        fields.put("useExponentialNotation", false);
1225        fields.put("minExponentDigits", (byte) 0);
1226        fields.put("maximumIntegerDigits", dform.getMaximumIntegerDigits());
1227        fields.put("minimumIntegerDigits", dform.getMinimumIntegerDigits());
1228        fields.put("maximumFractionDigits", dform.getMaximumFractionDigits());
1229        fields.put("minimumFractionDigits", dform.getMinimumFractionDigits());
1230        fields.put("serialVersionOnStream", 3);
1231        stream.writeFields();
1232    }
1233
1234    /**
1235     * Reads serialized fields following serialized forms specified by Java
1236     * specification.
1237     *
1238     * @param stream
1239     *            the input stream to read serialized bytes
1240     * @throws IOException
1241     *             if some I/O error occurs
1242     * @throws ClassNotFoundException
1243     *             if some class of serialized objects or fields cannot be found
1244     */
1245    @SuppressWarnings("nls")
1246    private void readObject(ObjectInputStream stream) throws IOException,
1247            ClassNotFoundException {
1248
1249        // BEGIN android-changed
1250        ObjectInputStream.GetField fields = stream.readFields();
1251        this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
1252
1253        initNative("");
1254        dform.setPositivePrefix((String) fields.get("positivePrefix", ""));
1255        dform.setPositiveSuffix((String) fields.get("positiveSuffix", ""));
1256        dform.setNegativePrefix((String) fields.get("negativePrefix", "-"));
1257        dform.setNegativeSuffix((String) fields.get("negativeSuffix", ""));
1258        dform.setMultiplier(fields.get("multiplier", 1));
1259        dform.setGroupingSize(fields.get("groupingSize", (byte) 3));
1260        dform.setGroupingUsed(fields.get("groupingUsed", true));
1261        dform.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown", false));
1262
1263        final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
1264        final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
1265        final int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
1266        final int minimumFractionDigits = fields.get("minimumFractionDigits", 340);
1267        // BEGIN android-changed: tell ICU what we want, then ask it what we can have, and then
1268        // set that in our Java object. This isn't RI-compatible, but then very little of our
1269        // behavior in this area is, and it's not obvious how we can second-guess ICU (or tell
1270        // it to just do exactly what we ask). We only need to do this with maximumIntegerDigits
1271        // because ICU doesn't seem to have its own ideas about the other options.
1272        dform.setMaximumIntegerDigits(maximumIntegerDigits);
1273        super.setMaximumIntegerDigits(dform.getMaximumIntegerDigits());
1274
1275        setMinimumIntegerDigits(minimumIntegerDigits);
1276        setMinimumFractionDigits(minimumFractionDigits);
1277        setMaximumFractionDigits(maximumFractionDigits);
1278        setParseBigDecimal(fields.get("parseBigDecimal", false));
1279
1280        if (fields.get("serialVersionOnStream", 0) < 3) {
1281            setMaximumIntegerDigits(super.getMaximumIntegerDigits());
1282            setMinimumIntegerDigits(super.getMinimumIntegerDigits());
1283            setMaximumFractionDigits(super.getMaximumFractionDigits());
1284            setMinimumFractionDigits(super.getMinimumFractionDigits());
1285        }
1286        // END android-changed
1287    }
1288}
1289