Home | History | Annotate | Download | only in util
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 2003, 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 package java.util;
     28 
     29 import java.io.BufferedWriter;
     30 import java.io.Closeable;
     31 import java.io.IOException;
     32 import java.io.File;
     33 import java.io.FileOutputStream;
     34 import java.io.FileNotFoundException;
     35 import java.io.Flushable;
     36 import java.io.OutputStream;
     37 import java.io.OutputStreamWriter;
     38 import java.io.PrintStream;
     39 import java.io.UnsupportedEncodingException;
     40 import java.math.BigDecimal;
     41 import java.math.BigInteger;
     42 import java.math.MathContext;
     43 import java.math.RoundingMode;
     44 import java.nio.charset.Charset;
     45 import java.nio.charset.IllegalCharsetNameException;
     46 import java.nio.charset.UnsupportedCharsetException;
     47 import java.text.DateFormatSymbols;
     48 import java.text.DecimalFormat;
     49 import java.text.DecimalFormatSymbols;
     50 import java.text.NumberFormat;
     51 import java.time.DateTimeException;
     52 import java.time.Instant;
     53 import java.time.ZoneId;
     54 import java.time.ZoneOffset;
     55 import java.time.temporal.ChronoField;
     56 import java.time.temporal.TemporalAccessor;
     57 import java.time.temporal.TemporalQueries;
     58 
     59 import libcore.icu.LocaleData;
     60 import sun.misc.FpUtils;
     61 import sun.misc.DoubleConsts;
     62 import sun.misc.FormattedFloatingDecimal;
     63 
     64 /**
     65  * An interpreter for printf-style format strings.  This class provides support
     66  * for layout justification and alignment, common formats for numeric, string,
     67  * and date/time data, and locale-specific output.  Common Java types such as
     68  * {@code byte}, {@link java.math.BigDecimal BigDecimal}, and {@link Calendar}
     69  * are supported.  Limited formatting customization for arbitrary user types is
     70  * provided through the {@link Formattable} interface.
     71  *
     72  * <p> Formatters are not necessarily safe for multithreaded access.  Thread
     73  * safety is optional and is the responsibility of users of methods in this
     74  * class.
     75  *
     76  * <p> Formatted printing for the Java language is heavily inspired by C's
     77  * {@code printf}.  Although the format strings are similar to C, some
     78  * customizations have been made to accommodate the Java language and exploit
     79  * some of its features.  Also, Java formatting is more strict than C's; for
     80  * example, if a conversion is incompatible with a flag, an exception will be
     81  * thrown.  In C inapplicable flags are silently ignored.  The format strings
     82  * are thus intended to be recognizable to C programmers but not necessarily
     83  * completely compatible with those in C.
     84  *
     85  * <p> Examples of expected usage:
     86  *
     87  * <blockquote><pre>
     88  *   StringBuilder sb = new StringBuilder();
     89  *   // Send all output to the Appendable object sb
     90  *   Formatter formatter = new Formatter(sb, Locale.US);
     91  *
     92  *   // Explicit argument indices may be used to re-order output.
     93  *   formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d")
     94  *   // -&gt; " d  c  b  a"
     95  *
     96  *   // Optional locale as the first argument can be used to get
     97  *   // locale-specific formatting of numbers.  The precision and width can be
     98  *   // given to round and align the value.
     99  *   formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
    100  *   // -&gt; "e =    +2,7183"
    101  *
    102  *   // The '(' numeric flag may be used to format negative numbers with
    103  *   // parentheses rather than a minus sign.  Group separators are
    104  *   // automatically inserted.
    105  *   formatter.format("Amount gained or lost since last statement: $ %(,.2f",
    106  *                    balanceDelta);
    107  *   // -&gt; "Amount gained or lost since last statement: $ (6,217.58)"
    108  * </pre></blockquote>
    109  *
    110  * <p> Convenience methods for common formatting requests exist as illustrated
    111  * by the following invocations:
    112  *
    113  * <blockquote><pre>
    114  *   // Writes a formatted string to System.out.
    115  *   System.out.format("Local time: %tT", Calendar.getInstance());
    116  *   // -&gt; "Local time: 13:34:18"
    117  *
    118  *   // Writes formatted output to System.err.
    119  *   System.err.printf("Unable to open file '%1$s': %2$s",
    120  *                     fileName, exception.getMessage());
    121  *   // -&gt; "Unable to open file 'food': No such file or directory"
    122  * </pre></blockquote>
    123  *
    124  * <p> Like C's {@code sprintf(3)}, Strings may be formatted using the static
    125  * method {@link String#format(String,Object...) String.format}:
    126  *
    127  * <blockquote><pre>
    128  *   // Format a string containing a date.
    129  *   import java.util.Calendar;
    130  *   import java.util.GregorianCalendar;
    131  *   import static java.util.Calendar.*;
    132  *
    133  *   Calendar c = new GregorianCalendar(1995, MAY, 23);
    134  *   String s = String.format("Duke's Birthday: %1$tb %1$te, %1$tY", c);
    135  *   // -&gt; s == "Duke's Birthday: May 23, 1995"
    136  * </pre></blockquote>
    137  *
    138  * <h3><a name="org">Organization</a></h3>
    139  *
    140  * <p> This specification is divided into two sections.  The first section, <a
    141  * href="#summary">Summary</a>, covers the basic formatting concepts.  This
    142  * section is intended for users who want to get started quickly and are
    143  * familiar with formatted printing in other programming languages.  The second
    144  * section, <a href="#detail">Details</a>, covers the specific implementation
    145  * details.  It is intended for users who want more precise specification of
    146  * formatting behavior.
    147  *
    148  * <h3><a name="summary">Summary</a></h3>
    149  *
    150  * <p> This section is intended to provide a brief overview of formatting
    151  * concepts.  For precise behavioral details, refer to the <a
    152  * href="#detail">Details</a> section.
    153  *
    154  * <h4><a name="syntax">Format String Syntax</a></h4>
    155  *
    156  * <p> Every method which produces formatted output requires a <i>format
    157  * string</i> and an <i>argument list</i>.  The format string is a {@link
    158  * String} which may contain fixed text and one or more embedded <i>format
    159  * specifiers</i>.  Consider the following example:
    160  *
    161  * <blockquote><pre>
    162  *   Calendar c = ...;
    163  *   String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
    164  * </pre></blockquote>
    165  *
    166  * This format string is the first argument to the {@code format} method.  It
    167  * contains three format specifiers "{@code %1$tm}", "{@code %1$te}", and
    168  * "{@code %1$tY}" which indicate how the arguments should be processed and
    169  * where they should be inserted in the text.  The remaining portions of the
    170  * format string are fixed text including {@code "Dukes Birthday: "} and any
    171  * other spaces or punctuation.
    172  *
    173  * The argument list consists of all arguments passed to the method after the
    174  * format string.  In the above example, the argument list is of size one and
    175  * consists of the {@link java.util.Calendar Calendar} object {@code c}.
    176  *
    177  * <ul>
    178  *
    179  * <li> The format specifiers for general, character, and numeric types have
    180  * the following syntax:
    181  *
    182  * <blockquote><pre>
    183  *   %[argument_index$][flags][width][.precision]conversion
    184  * </pre></blockquote>
    185  *
    186  * <p> The optional <i>argument_index</i> is a decimal integer indicating the
    187  * position of the argument in the argument list.  The first argument is
    188  * referenced by "{@code 1$}", the second by "{@code 2$}", etc.
    189  *
    190  * <p> The optional <i>flags</i> is a set of characters that modify the output
    191  * format.  The set of valid flags depends on the conversion.
    192  *
    193  * <p> The optional <i>width</i> is a positive decimal integer indicating
    194  * the minimum number of characters to be written to the output.
    195  *
    196  * <p> The optional <i>precision</i> is a non-negative decimal integer usually
    197  * used to restrict the number of characters.  The specific behavior depends on
    198  * the conversion.
    199  *
    200  * <p> The required <i>conversion</i> is a character indicating how the
    201  * argument should be formatted.  The set of valid conversions for a given
    202  * argument depends on the argument's data type.
    203  *
    204  * <li> The format specifiers for types which are used to represents dates and
    205  * times have the following syntax:
    206  *
    207  * <blockquote><pre>
    208  *   %[argument_index$][flags][width]conversion
    209  * </pre></blockquote>
    210  *
    211  * <p> The optional <i>argument_index</i>, <i>flags</i> and <i>width</i> are
    212  * defined as above.
    213  *
    214  * <p> The required <i>conversion</i> is a two character sequence.  The first
    215  * character is {@code 't'} or {@code 'T'}.  The second character indicates
    216  * the format to be used.  These characters are similar to but not completely
    217  * identical to those defined by GNU {@code date} and POSIX
    218  * {@code strftime(3c)}.
    219  *
    220  * <li> The format specifiers which do not correspond to arguments have the
    221  * following syntax:
    222  *
    223  * <blockquote><pre>
    224  *   %[flags][width]conversion
    225  * </pre></blockquote>
    226  *
    227  * <p> The optional <i>flags</i> and <i>width</i> is defined as above.
    228  *
    229  * <p> The required <i>conversion</i> is a character indicating content to be
    230  * inserted in the output.
    231  *
    232  * </ul>
    233  *
    234  * <h4> Conversions </h4>
    235  *
    236  * <p> Conversions are divided into the following categories:
    237  *
    238  * <ol>
    239  *
    240  * <li> <b>General</b> - may be applied to any argument
    241  * type
    242  *
    243  * <li> <b>Character</b> - may be applied to basic types which represent
    244  * Unicode characters: {@code char}, {@link Character}, {@code byte}, {@link
    245  * Byte}, {@code short}, and {@link Short}. This conversion may also be
    246  * applied to the types {@code int} and {@link Integer} when {@link
    247  * Character#isValidCodePoint} returns {@code true}
    248  *
    249  * <li> <b>Numeric</b>
    250  *
    251  * <ol>
    252  *
    253  * <li> <b>Integral</b> - may be applied to Java integral types: {@code byte},
    254  * {@link Byte}, {@code short}, {@link Short}, {@code int} and {@link
    255  * Integer}, {@code long}, {@link Long}, and {@link java.math.BigInteger
    256  * BigInteger} (but not {@code char} or {@link Character})
    257  *
    258  * <li><b>Floating Point</b> - may be applied to Java floating-point types:
    259  * {@code float}, {@link Float}, {@code double}, {@link Double}, and {@link
    260  * java.math.BigDecimal BigDecimal}
    261  *
    262  * </ol>
    263  *
    264  * <li> <b>Date/Time</b> - may be applied to Java types which are capable of
    265  * encoding a date or time: {@code long}, {@link Long}, {@link Calendar},
    266  * {@link Date} and {@link TemporalAccessor TemporalAccessor}
    267  *
    268  * <li> <b>Percent</b> - produces a literal {@code '%'}
    269  * (<tt>'&#92;u0025'</tt>)
    270  *
    271  * <li> <b>Line Separator</b> - produces the platform-specific line separator
    272  *
    273  * </ol>
    274  *
    275  * <p> The following table summarizes the supported conversions.  Conversions
    276  * denoted by an upper-case character (i.e. {@code 'B'}, {@code 'H'},
    277  * {@code 'S'}, {@code 'C'}, {@code 'X'}, {@code 'E'}, {@code 'G'},
    278  * {@code 'A'}, and {@code 'T'}) are the same as those for the corresponding
    279  * lower-case conversion characters except that the result is converted to
    280  * upper case according to the rules of the prevailing {@link java.util.Locale
    281  * Locale}.  The result is equivalent to the following invocation of {@link
    282  * String#toUpperCase()}
    283  *
    284  * <pre>
    285  *    out.toUpperCase() </pre>
    286  *
    287  * <table cellpadding=5 summary="genConv">
    288  *
    289  * <tr><th valign="bottom"> Conversion
    290  *     <th valign="bottom"> Argument Category
    291  *     <th valign="bottom"> Description
    292  *
    293  * <tr><td valign="top"> {@code 'b'}, {@code 'B'}
    294  *     <td valign="top"> general
    295  *     <td> If the argument <i>arg</i> is {@code null}, then the result is
    296  *     "{@code false}".  If <i>arg</i> is a {@code boolean} or {@link
    297  *     Boolean}, then the result is the string returned by {@link
    298  *     String#valueOf(boolean) String.valueOf(arg)}.  Otherwise, the result is
    299  *     "true".
    300  *
    301  * <tr><td valign="top"> {@code 'h'}, {@code 'H'}
    302  *     <td valign="top"> general
    303  *     <td> If the argument <i>arg</i> is {@code null}, then the result is
    304  *     "{@code null}".  Otherwise, the result is obtained by invoking
    305  *     {@code Integer.toHexString(arg.hashCode())}.
    306  *
    307  * <tr><td valign="top"> {@code 's'}, {@code 'S'}
    308  *     <td valign="top"> general
    309  *     <td> If the argument <i>arg</i> is {@code null}, then the result is
    310  *     "{@code null}".  If <i>arg</i> implements {@link Formattable}, then
    311  *     {@link Formattable#formatTo arg.formatTo} is invoked. Otherwise, the
    312  *     result is obtained by invoking {@code arg.toString()}.
    313  *
    314  * <tr><td valign="top">{@code 'c'}, {@code 'C'}
    315  *     <td valign="top"> character
    316  *     <td> The result is a Unicode character
    317  *
    318  * <tr><td valign="top">{@code 'd'}
    319  *     <td valign="top"> integral
    320  *     <td> The result is formatted as a decimal integer
    321  *
    322  * <tr><td valign="top">{@code 'o'}
    323  *     <td valign="top"> integral
    324  *     <td> The result is formatted as an octal integer
    325  *
    326  * <tr><td valign="top">{@code 'x'}, {@code 'X'}
    327  *     <td valign="top"> integral
    328  *     <td> The result is formatted as a hexadecimal integer
    329  *
    330  * <tr><td valign="top">{@code 'e'}, {@code 'E'}
    331  *     <td valign="top"> floating point
    332  *     <td> The result is formatted as a decimal number in computerized
    333  *     scientific notation
    334  *
    335  * <tr><td valign="top">{@code 'f'}
    336  *     <td valign="top"> floating point
    337  *     <td> The result is formatted as a decimal number
    338  *
    339  * <tr><td valign="top">{@code 'g'}, {@code 'G'}
    340  *     <td valign="top"> floating point
    341  *     <td> The result is formatted using computerized scientific notation or
    342  *     decimal format, depending on the precision and the value after rounding.
    343  *
    344  * <tr><td valign="top">{@code 'a'}, {@code 'A'}
    345  *     <td valign="top"> floating point
    346  *     <td> The result is formatted as a hexadecimal floating-point number with
    347  *     a significand and an exponent. This conversion is <b>not</b> supported
    348  *     for the {@code BigDecimal} type despite the latter's being in the
    349  *     <i>floating point</i> argument category.
    350  *
    351  * <tr><td valign="top">{@code 't'}, {@code 'T'}
    352  *     <td valign="top"> date/time
    353  *     <td> Prefix for date and time conversion characters.  See <a
    354  *     href="#dt">Date/Time Conversions</a>.
    355  *
    356  * <tr><td valign="top">{@code '%'}
    357  *     <td valign="top"> percent
    358  *     <td> The result is a literal {@code '%'} (<tt>'&#92;u0025'</tt>)
    359  *
    360  * <tr><td valign="top">{@code 'n'}
    361  *     <td valign="top"> line separator
    362  *     <td> The result is the platform-specific line separator
    363  *
    364  * </table>
    365  *
    366  * <p> Any characters not explicitly defined as conversions are illegal and are
    367  * reserved for future extensions.
    368  *
    369  * <h4><a name="dt">Date/Time Conversions</a></h4>
    370  *
    371  * <p> The following date and time conversion suffix characters are defined for
    372  * the {@code 't'} and {@code 'T'} conversions.  The types are similar to but
    373  * not completely identical to those defined by GNU {@code date} and POSIX
    374  * {@code strftime(3c)}.  Additional conversion types are provided to access
    375  * Java-specific functionality (e.g. {@code 'L'} for milliseconds within the
    376  * second).
    377  *
    378  * <p> The following conversion characters are used for formatting times:
    379  *
    380  * <table cellpadding=5 summary="time">
    381  *
    382  * <tr><td valign="top"> {@code 'H'}
    383  *     <td> Hour of the day for the 24-hour clock, formatted as two digits with
    384  *     a leading zero as necessary i.e. {@code 00 - 23}.
    385  *
    386  * <tr><td valign="top">{@code 'I'}
    387  *     <td> Hour for the 12-hour clock, formatted as two digits with a leading
    388  *     zero as necessary, i.e.  {@code 01 - 12}.
    389  *
    390  * <tr><td valign="top">{@code 'k'}
    391  *     <td> Hour of the day for the 24-hour clock, i.e. {@code 0 - 23}.
    392  *
    393  * <tr><td valign="top">{@code 'l'}
    394  *     <td> Hour for the 12-hour clock, i.e. {@code 1 - 12}.
    395  *
    396  * <tr><td valign="top">{@code 'M'}
    397  *     <td> Minute within the hour formatted as two digits with a leading zero
    398  *     as necessary, i.e.  {@code 00 - 59}.
    399  *
    400  * <tr><td valign="top">{@code 'S'}
    401  *     <td> Seconds within the minute, formatted as two digits with a leading
    402  *     zero as necessary, i.e. {@code 00 - 60} ("{@code 60}" is a special
    403  *     value required to support leap seconds).
    404  *
    405  * <tr><td valign="top">{@code 'L'}
    406  *     <td> Millisecond within the second formatted as three digits with
    407  *     leading zeros as necessary, i.e. {@code 000 - 999}.
    408  *
    409  * <tr><td valign="top">{@code 'N'}
    410  *     <td> Nanosecond within the second, formatted as nine digits with leading
    411  *     zeros as necessary, i.e. {@code 000000000 - 999999999}.
    412  *
    413  * <tr><td valign="top">{@code 'p'}
    414  *     <td> Locale-specific {@linkplain
    415  *     java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
    416  *     in lower case, e.g."{@code am}" or "{@code pm}". Use of the conversion
    417  *     prefix {@code 'T'} forces this output to upper case.
    418  *
    419  * <tr><td valign="top">{@code 'z'}
    420  *     <td> <a href="http://www.ietf.org/rfc/rfc0822.txt">RFC&nbsp;822</a>
    421  *     style numeric time zone offset from GMT, e.g. {@code -0800}.  This
    422  *     value will be adjusted as necessary for Daylight Saving Time.  For
    423  *     {@code long}, {@link Long}, and {@link Date} the time zone used is
    424  *     the {@linkplain TimeZone#getDefault() default time zone} for this
    425  *     instance of the Java virtual machine.
    426  *
    427  * <tr><td valign="top">{@code 'Z'}
    428  *     <td> A string representing the abbreviation for the time zone.  This
    429  *     value will be adjusted as necessary for Daylight Saving Time.  For
    430  *     {@code long}, {@link Long}, and {@link Date} the  time zone used is
    431  *     the {@linkplain TimeZone#getDefault() default time zone} for this
    432  *     instance of the Java virtual machine.  The Formatter's locale will
    433  *     supersede the locale of the argument (if any).
    434  *
    435  * <tr><td valign="top">{@code 's'}
    436  *     <td> Seconds since the beginning of the epoch starting at 1 January 1970
    437  *     {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE/1000} to
    438  *     {@code Long.MAX_VALUE/1000}.
    439  *
    440  * <tr><td valign="top">{@code 'Q'}
    441  *     <td> Milliseconds since the beginning of the epoch starting at 1 January
    442  *     1970 {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE} to
    443  *     {@code Long.MAX_VALUE}.
    444  *
    445  * </table>
    446  *
    447  * <p> The following conversion characters are used for formatting dates:
    448  *
    449  * <table cellpadding=5 summary="date">
    450  *
    451  * <tr><td valign="top">{@code 'B'}
    452  *     <td> Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
    453  *     full month name}, e.g. {@code "January"}, {@code "February"}.
    454  *
    455  * <tr><td valign="top">{@code 'b'}
    456  *     <td> Locale-specific {@linkplain
    457  *     java.text.DateFormatSymbols#getShortMonths abbreviated month name},
    458  *     e.g. {@code "Jan"}, {@code "Feb"}.
    459  *
    460  * <tr><td valign="top">{@code 'h'}
    461  *     <td> Same as {@code 'b'}.
    462  *
    463  * <tr><td valign="top">{@code 'A'}
    464  *     <td> Locale-specific full name of the {@linkplain
    465  *     java.text.DateFormatSymbols#getWeekdays day of the week},
    466  *     e.g. {@code "Sunday"}, {@code "Monday"}
    467  *
    468  * <tr><td valign="top">{@code 'a'}
    469  *     <td> Locale-specific short name of the {@linkplain
    470  *     java.text.DateFormatSymbols#getShortWeekdays day of the week},
    471  *     e.g. {@code "Sun"}, {@code "Mon"}
    472  *
    473  * <tr><td valign="top">{@code 'C'}
    474  *     <td> Four-digit year divided by {@code 100}, formatted as two digits
    475  *     with leading zero as necessary, i.e. {@code 00 - 99}
    476  *
    477  * <tr><td valign="top">{@code 'Y'}
    478  *     <td> Year, formatted as at least four digits with leading zeros as
    479  *     necessary, e.g. {@code 0092} equals {@code 92} CE for the Gregorian
    480  *     calendar.
    481  *
    482  * <tr><td valign="top">{@code 'y'}
    483  *     <td> Last two digits of the year, formatted with leading zeros as
    484  *     necessary, i.e. {@code 00 - 99}.
    485  *
    486  * <tr><td valign="top">{@code 'j'}
    487  *     <td> Day of year, formatted as three digits with leading zeros as
    488  *     necessary, e.g. {@code 001 - 366} for the Gregorian calendar.
    489  *
    490  * <tr><td valign="top">{@code 'm'}
    491  *     <td> Month, formatted as two digits with leading zeros as necessary,
    492  *     i.e. {@code 01 - 13}.
    493  *
    494  * <tr><td valign="top">{@code 'd'}
    495  *     <td> Day of month, formatted as two digits with leading zeros as
    496  *     necessary, i.e. {@code 01 - 31}
    497  *
    498  * <tr><td valign="top">{@code 'e'}
    499  *     <td> Day of month, formatted as two digits, i.e. {@code 1 - 31}.
    500  *
    501  * </table>
    502  *
    503  * <p> The following conversion characters are used for formatting common
    504  * date/time compositions.
    505  *
    506  * <table cellpadding=5 summary="composites">
    507  *
    508  * <tr><td valign="top">{@code 'R'}
    509  *     <td> Time formatted for the 24-hour clock as {@code "%tH:%tM"}
    510  *
    511  * <tr><td valign="top">{@code 'T'}
    512  *     <td> Time formatted for the 24-hour clock as {@code "%tH:%tM:%tS"}.
    513  *
    514  * <tr><td valign="top">{@code 'r'}
    515  *     <td> Time formatted for the 12-hour clock as {@code "%tI:%tM:%tS %Tp"}.
    516  *     The location of the morning or afternoon marker ({@code '%Tp'}) may be
    517  *     locale-dependent.
    518  *
    519  * <tr><td valign="top">{@code 'D'}
    520  *     <td> Date formatted as {@code "%tm/%td/%ty"}.
    521  *
    522  * <tr><td valign="top">{@code 'F'}
    523  *     <td> <a href="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a>
    524  *     complete date formatted as {@code "%tY-%tm-%td"}.
    525  *
    526  * <tr><td valign="top">{@code 'c'}
    527  *     <td> Date and time formatted as {@code "%ta %tb %td %tT %tZ %tY"},
    528  *     e.g. {@code "Sun Jul 20 16:17:00 EDT 1969"}.
    529  *
    530  * </table>
    531  *
    532  * <p> Any characters not explicitly defined as date/time conversion suffixes
    533  * are illegal and are reserved for future extensions.
    534  *
    535  * <h4> Flags </h4>
    536  *
    537  * <p> The following table summarizes the supported flags.  <i>y</i> means the
    538  * flag is supported for the indicated argument types.
    539  *
    540  * <table cellpadding=5 summary="genConv">
    541  *
    542  * <tr><th valign="bottom"> Flag <th valign="bottom"> General
    543  *     <th valign="bottom"> Character <th valign="bottom"> Integral
    544  *     <th valign="bottom"> Floating Point
    545  *     <th valign="bottom"> Date/Time
    546  *     <th valign="bottom"> Description
    547  *
    548  * <tr><td> '-' <td align="center" valign="top"> y
    549  *     <td align="center" valign="top"> y
    550  *     <td align="center" valign="top"> y
    551  *     <td align="center" valign="top"> y
    552  *     <td align="center" valign="top"> y
    553  *     <td> The result will be left-justified.
    554  *
    555  * <tr><td> '#' <td align="center" valign="top"> y<sup>1</sup>
    556  *     <td align="center" valign="top"> -
    557  *     <td align="center" valign="top"> y<sup>3</sup>
    558  *     <td align="center" valign="top"> y
    559  *     <td align="center" valign="top"> -
    560  *     <td> The result should use a conversion-dependent alternate form
    561  *
    562  * <tr><td> '+' <td align="center" valign="top"> -
    563  *     <td align="center" valign="top"> -
    564  *     <td align="center" valign="top"> y<sup>4</sup>
    565  *     <td align="center" valign="top"> y
    566  *     <td align="center" valign="top"> -
    567  *     <td> The result will always include a sign
    568  *
    569  * <tr><td> '&nbsp;&nbsp;' <td align="center" valign="top"> -
    570  *     <td align="center" valign="top"> -
    571  *     <td align="center" valign="top"> y<sup>4</sup>
    572  *     <td align="center" valign="top"> y
    573  *     <td align="center" valign="top"> -
    574  *     <td> The result will include a leading space for positive values
    575  *
    576  * <tr><td> '0' <td align="center" valign="top"> -
    577  *     <td align="center" valign="top"> -
    578  *     <td align="center" valign="top"> y
    579  *     <td align="center" valign="top"> y
    580  *     <td align="center" valign="top"> -
    581  *     <td> The result will be zero-padded
    582  *
    583  * <tr><td> ',' <td align="center" valign="top"> -
    584  *     <td align="center" valign="top"> -
    585  *     <td align="center" valign="top"> y<sup>2</sup>
    586  *     <td align="center" valign="top"> y<sup>5</sup>
    587  *     <td align="center" valign="top"> -
    588  *     <td> The result will include locale-specific {@linkplain
    589  *     java.text.DecimalFormatSymbols#getGroupingSeparator grouping separators}
    590  *
    591  * <tr><td> '(' <td align="center" valign="top"> -
    592  *     <td align="center" valign="top"> -
    593  *     <td align="center" valign="top"> y<sup>4</sup>
    594  *     <td align="center" valign="top"> y<sup>5</sup>
    595  *     <td align="center"> -
    596  *     <td> The result will enclose negative numbers in parentheses
    597  *
    598  * </table>
    599  *
    600  * <p> <sup>1</sup> Depends on the definition of {@link Formattable}.
    601  *
    602  * <p> <sup>2</sup> For {@code 'd'} conversion only.
    603  *
    604  * <p> <sup>3</sup> For {@code 'o'}, {@code 'x'}, and {@code 'X'}
    605  * conversions only.
    606  *
    607  * <p> <sup>4</sup> For {@code 'd'}, {@code 'o'}, {@code 'x'}, and
    608  * {@code 'X'} conversions applied to {@link java.math.BigInteger BigInteger}
    609  * or {@code 'd'} applied to {@code byte}, {@link Byte}, {@code short}, {@link
    610  * Short}, {@code int} and {@link Integer}, {@code long}, and {@link Long}.
    611  *
    612  * <p> <sup>5</sup> For {@code 'e'}, {@code 'E'}, {@code 'f'},
    613  * {@code 'g'}, and {@code 'G'} conversions only.
    614  *
    615  * <p> Any characters not explicitly defined as flags are illegal and are
    616  * reserved for future extensions.
    617  *
    618  * <h4> Width </h4>
    619  *
    620  * <p> The width is the minimum number of characters to be written to the
    621  * output.  For the line separator conversion, width is not applicable; if it
    622  * is provided, an exception will be thrown.
    623  *
    624  * <h4> Precision </h4>
    625  *
    626  * <p> For general argument types, the precision is the maximum number of
    627  * characters to be written to the output.
    628  *
    629  * <p> For the floating-point conversions {@code 'a'}, {@code 'A'}, {@code 'e'},
    630  * {@code 'E'}, and {@code 'f'} the precision is the number of digits after the
    631  * radix point.  If the conversion is {@code 'g'} or {@code 'G'}, then the
    632  * precision is the total number of digits in the resulting magnitude after
    633  * rounding.
    634  *
    635  * <p> For character, integral, and date/time argument types and the percent
    636  * and line separator conversions, the precision is not applicable; if a
    637  * precision is provided, an exception will be thrown.
    638  *
    639  * <h4> Argument Index </h4>
    640  *
    641  * <p> The argument index is a decimal integer indicating the position of the
    642  * argument in the argument list.  The first argument is referenced by
    643  * "{@code 1$}", the second by "{@code 2$}", etc.
    644  *
    645  * <p> Another way to reference arguments by position is to use the
    646  * {@code '<'} (<tt>'&#92;u003c'</tt>) flag, which causes the argument for
    647  * the previous format specifier to be re-used.  For example, the following two
    648  * statements would produce identical strings:
    649  *
    650  * <blockquote><pre>
    651  *   Calendar c = ...;
    652  *   String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
    653  *
    654  *   String s2 = String.format("Duke's Birthday: %1$tm %&lt;te,%&lt;tY", c);
    655  * </pre></blockquote>
    656  *
    657  * <hr>
    658  * <h3><a name="detail">Details</a></h3>
    659  *
    660  * <p> This section is intended to provide behavioral details for formatting,
    661  * including conditions and exceptions, supported data types, localization, and
    662  * interactions between flags, conversions, and data types.  For an overview of
    663  * formatting concepts, refer to the <a href="#summary">Summary</a>
    664  *
    665  * <p> Any characters not explicitly defined as conversions, date/time
    666  * conversion suffixes, or flags are illegal and are reserved for
    667  * future extensions.  Use of such a character in a format string will
    668  * cause an {@link UnknownFormatConversionException} or {@link
    669  * UnknownFormatFlagsException} to be thrown.
    670  *
    671  * <p> If the format specifier contains a width or precision with an invalid
    672  * value or which is otherwise unsupported, then a {@link
    673  * IllegalFormatWidthException} or {@link IllegalFormatPrecisionException}
    674  * respectively will be thrown.
    675  *
    676  * <p> If a format specifier contains a conversion character that is not
    677  * applicable to the corresponding argument, then an {@link
    678  * IllegalFormatConversionException} will be thrown.
    679  *
    680  * <p> All specified exceptions may be thrown by any of the {@code format}
    681  * methods of {@code Formatter} as well as by any {@code format} convenience
    682  * methods such as {@link String#format(String,Object...) String.format} and
    683  * {@link java.io.PrintStream#printf(String,Object...) PrintStream.printf}.
    684  *
    685  * <p> Conversions denoted by an upper-case character (i.e. {@code 'B'},
    686  * {@code 'H'}, {@code 'S'}, {@code 'C'}, {@code 'X'}, {@code 'E'},
    687  * {@code 'G'}, {@code 'A'}, and {@code 'T'}) are the same as those for the
    688  * corresponding lower-case conversion characters except that the result is
    689  * converted to upper case according to the rules of the prevailing {@link
    690  * java.util.Locale Locale}.  The result is equivalent to the following
    691  * invocation of {@link String#toUpperCase()}
    692  *
    693  * <pre>
    694  *    out.toUpperCase() </pre>
    695  *
    696  * <h4><a name="dgen">General</a></h4>
    697  *
    698  * <p> The following general conversions may be applied to any argument type:
    699  *
    700  * <table cellpadding=5 summary="dgConv">
    701  *
    702  * <tr><td valign="top"> {@code 'b'}
    703  *     <td valign="top"> <tt>'&#92;u0062'</tt>
    704  *     <td> Produces either "{@code true}" or "{@code false}" as returned by
    705  *     {@link Boolean#toString(boolean)}.
    706  *
    707  *     <p> If the argument is {@code null}, then the result is
    708  *     "{@code false}".  If the argument is a {@code boolean} or {@link
    709  *     Boolean}, then the result is the string returned by {@link
    710  *     String#valueOf(boolean) String.valueOf()}.  Otherwise, the result is
    711  *     "{@code true}".
    712  *
    713  *     <p> If the {@code '#'} flag is given, then a {@link
    714  *     FormatFlagsConversionMismatchException} will be thrown.
    715  *
    716  * <tr><td valign="top"> {@code 'B'}
    717  *     <td valign="top"> <tt>'&#92;u0042'</tt>
    718  *     <td> The upper-case variant of {@code 'b'}.
    719  *
    720  * <tr><td valign="top"> {@code 'h'}
    721  *     <td valign="top"> <tt>'&#92;u0068'</tt>
    722  *     <td> Produces a string representing the hash code value of the object.
    723  *
    724  *     <p> If the argument, <i>arg</i> is {@code null}, then the
    725  *     result is "{@code null}".  Otherwise, the result is obtained
    726  *     by invoking {@code Integer.toHexString(arg.hashCode())}.
    727  *
    728  *     <p> If the {@code '#'} flag is given, then a {@link
    729  *     FormatFlagsConversionMismatchException} will be thrown.
    730  *
    731  * <tr><td valign="top"> {@code 'H'}
    732  *     <td valign="top"> <tt>'&#92;u0048'</tt>
    733  *     <td> The upper-case variant of {@code 'h'}.
    734  *
    735  * <tr><td valign="top"> {@code 's'}
    736  *     <td valign="top"> <tt>'&#92;u0073'</tt>
    737  *     <td> Produces a string.
    738  *
    739  *     <p> If the argument is {@code null}, then the result is
    740  *     "{@code null}".  If the argument implements {@link Formattable}, then
    741  *     its {@link Formattable#formatTo formatTo} method is invoked.
    742  *     Otherwise, the result is obtained by invoking the argument's
    743  *     {@code toString()} method.
    744  *
    745  *     <p> If the {@code '#'} flag is given and the argument is not a {@link
    746  *     Formattable} , then a {@link FormatFlagsConversionMismatchException}
    747  *     will be thrown.
    748  *
    749  * <tr><td valign="top"> {@code 'S'}
    750  *     <td valign="top"> <tt>'&#92;u0053'</tt>
    751  *     <td> The upper-case variant of {@code 's'}.
    752  *
    753  * </table>
    754  *
    755  * <p> The following <a name="dFlags">flags</a> apply to general conversions:
    756  *
    757  * <table cellpadding=5 summary="dFlags">
    758  *
    759  * <tr><td valign="top"> {@code '-'}
    760  *     <td valign="top"> <tt>'&#92;u002d'</tt>
    761  *     <td> Left justifies the output.  Spaces (<tt>'&#92;u0020'</tt>) will be
    762  *     added at the end of the converted value as required to fill the minimum
    763  *     width of the field.  If the width is not provided, then a {@link
    764  *     MissingFormatWidthException} will be thrown.  If this flag is not given
    765  *     then the output will be right-justified.
    766  *
    767  * <tr><td valign="top"> {@code '#'}
    768  *     <td valign="top"> <tt>'&#92;u0023'</tt>
    769  *     <td> Requires the output use an alternate form.  The definition of the
    770  *     form is specified by the conversion.
    771  *
    772  * </table>
    773  *
    774  * <p> The <a name="genWidth">width</a> is the minimum number of characters to
    775  * be written to the
    776  * output.  If the length of the converted value is less than the width then
    777  * the output will be padded by <tt>'&nbsp;&nbsp;'</tt> (<tt>'&#92;u0020'</tt>)
    778  * until the total number of characters equals the width.  The padding is on
    779  * the left by default.  If the {@code '-'} flag is given, then the padding
    780  * will be on the right.  If the width is not specified then there is no
    781  * minimum.
    782  *
    783  * <p> The precision is the maximum number of characters to be written to the
    784  * output.  The precision is applied before the width, thus the output will be
    785  * truncated to {@code precision} characters even if the width is greater than
    786  * the precision.  If the precision is not specified then there is no explicit
    787  * limit on the number of characters.
    788  *
    789  * <h4><a name="dchar">Character</a></h4>
    790  *
    791  * This conversion may be applied to {@code char} and {@link Character}.  It
    792  * may also be applied to the types {@code byte}, {@link Byte},
    793  * {@code short}, and {@link Short}, {@code int} and {@link Integer} when
    794  * {@link Character#isValidCodePoint} returns {@code true}.  If it returns
    795  * {@code false} then an {@link IllegalFormatCodePointException} will be
    796  * thrown.
    797  *
    798  * <table cellpadding=5 summary="charConv">
    799  *
    800  * <tr><td valign="top"> {@code 'c'}
    801  *     <td valign="top"> <tt>'&#92;u0063'</tt>
    802  *     <td> Formats the argument as a Unicode character as described in <a
    803  *     href="../lang/Character.html#unicode">Unicode Character
    804  *     Representation</a>.  This may be more than one 16-bit {@code char} in
    805  *     the case where the argument represents a supplementary character.
    806  *
    807  *     <p> If the {@code '#'} flag is given, then a {@link
    808  *     FormatFlagsConversionMismatchException} will be thrown.
    809  *
    810  * <tr><td valign="top"> {@code 'C'}
    811  *     <td valign="top"> <tt>'&#92;u0043'</tt>
    812  *     <td> The upper-case variant of {@code 'c'}.
    813  *
    814  * </table>
    815  *
    816  * <p> The {@code '-'} flag defined for <a href="#dFlags">General
    817  * conversions</a> applies.  If the {@code '#'} flag is given, then a {@link
    818  * FormatFlagsConversionMismatchException} will be thrown.
    819  *
    820  * <p> The width is defined as for <a href="#genWidth">General conversions</a>.
    821  *
    822  * <p> The precision is not applicable.  If the precision is specified then an
    823  * {@link IllegalFormatPrecisionException} will be thrown.
    824  *
    825  * <h4><a name="dnum">Numeric</a></h4>
    826  *
    827  * <p> Numeric conversions are divided into the following categories:
    828  *
    829  * <ol>
    830  *
    831  * <li> <a href="#dnint"><b>Byte, Short, Integer, and Long</b></a>
    832  *
    833  * <li> <a href="#dnbint"><b>BigInteger</b></a>
    834  *
    835  * <li> <a href="#dndec"><b>Float and Double</b></a>
    836  *
    837  * <li> <a href="#dnbdec"><b>BigDecimal</b></a>
    838  *
    839  * </ol>
    840  *
    841  * <p> Numeric types will be formatted according to the following algorithm:
    842  *
    843  * <p><b><a name="L10nAlgorithm"> Number Localization Algorithm</a></b>
    844  *
    845  * <p> After digits are obtained for the integer part, fractional part, and
    846  * exponent (as appropriate for the data type), the following transformation
    847  * is applied:
    848  *
    849  * <ol>
    850  *
    851  * <li> Each digit character <i>d</i> in the string is replaced by a
    852  * locale-specific digit computed relative to the current locale's
    853  * {@linkplain java.text.DecimalFormatSymbols#getZeroDigit() zero digit}
    854  * <i>z</i>; that is <i>d&nbsp;-&nbsp;</i> {@code '0'}
    855  * <i>&nbsp;+&nbsp;z</i>.
    856  *
    857  * <li> If a decimal separator is present, a locale-specific {@linkplain
    858  * java.text.DecimalFormatSymbols#getDecimalSeparator decimal separator} is
    859  * substituted.
    860  *
    861  * <li> If the {@code ','} (<tt>'&#92;u002c'</tt>)
    862  * <a name="L10nGroup">flag</a> is given, then the locale-specific {@linkplain
    863  * java.text.DecimalFormatSymbols#getGroupingSeparator grouping separator} is
    864  * inserted by scanning the integer part of the string from least significant
    865  * to most significant digits and inserting a separator at intervals defined by
    866  * the locale's {@linkplain java.text.DecimalFormat#getGroupingSize() grouping
    867  * size}.
    868  *
    869  * <li> If the {@code '0'} flag is given, then the locale-specific {@linkplain
    870  * java.text.DecimalFormatSymbols#getZeroDigit() zero digits} are inserted
    871  * after the sign character, if any, and before the first non-zero digit, until
    872  * the length of the string is equal to the requested field width.
    873  *
    874  * <li> If the value is negative and the {@code '('} flag is given, then a
    875  * {@code '('} (<tt>'&#92;u0028'</tt>) is prepended and a {@code ')'}
    876  * (<tt>'&#92;u0029'</tt>) is appended.
    877  *
    878  * <li> If the value is negative (or floating-point negative zero) and
    879  * {@code '('} flag is not given, then a {@code '-'} (<tt>'&#92;u002d'</tt>)
    880  * is prepended.
    881  *
    882  * <li> If the {@code '+'} flag is given and the value is positive or zero (or
    883  * floating-point positive zero), then a {@code '+'} (<tt>'&#92;u002b'</tt>)
    884  * will be prepended.
    885  *
    886  * </ol>
    887  *
    888  * <p> If the value is NaN or positive infinity the literal strings "NaN" or
    889  * "Infinity" respectively, will be output.  If the value is negative infinity,
    890  * then the output will be "(Infinity)" if the {@code '('} flag is given
    891  * otherwise the output will be "-Infinity".  These values are not localized.
    892  *
    893  * <p><a name="dnint"><b> Byte, Short, Integer, and Long </b></a>
    894  *
    895  * <p> The following conversions may be applied to {@code byte}, {@link Byte},
    896  * {@code short}, {@link Short}, {@code int} and {@link Integer},
    897  * {@code long}, and {@link Long}.
    898  *
    899  * <table cellpadding=5 summary="IntConv">
    900  *
    901  * <tr><td valign="top"> {@code 'd'}
    902  *     <td valign="top"> <tt>'&#92;u0064'</tt>
    903  *     <td> Formats the argument as a decimal integer. The <a
    904  *     href="#L10nAlgorithm">localization algorithm</a> is applied.
    905  *
    906  *     <p> If the {@code '0'} flag is given and the value is negative, then
    907  *     the zero padding will occur after the sign.
    908  *
    909  *     <p> If the {@code '#'} flag is given then a {@link
    910  *     FormatFlagsConversionMismatchException} will be thrown.
    911  *
    912  * <tr><td valign="top"> {@code 'o'}
    913  *     <td valign="top"> <tt>'&#92;u006f'</tt>
    914  *     <td> Formats the argument as an integer in base eight.  No localization
    915  *     is applied.
    916  *
    917  *     <p> If <i>x</i> is negative then the result will be an unsigned value
    918  *     generated by adding 2<sup>n</sup> to the value where {@code n} is the
    919  *     number of bits in the type as returned by the static {@code SIZE} field
    920  *     in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
    921  *     {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
    922  *     classes as appropriate.
    923  *
    924  *     <p> If the {@code '#'} flag is given then the output will always begin
    925  *     with the radix indicator {@code '0'}.
    926  *
    927  *     <p> If the {@code '0'} flag is given then the output will be padded
    928  *     with leading zeros to the field width following any indication of sign.
    929  *
    930  *     <p> If {@code '('}, {@code '+'}, '&nbsp;&nbsp;', or {@code ','} flags
    931  *     are given then a {@link FormatFlagsConversionMismatchException} will be
    932  *     thrown.
    933  *
    934  * <tr><td valign="top"> {@code 'x'}
    935  *     <td valign="top"> <tt>'&#92;u0078'</tt>
    936  *     <td> Formats the argument as an integer in base sixteen. No
    937  *     localization is applied.
    938  *
    939  *     <p> If <i>x</i> is negative then the result will be an unsigned value
    940  *     generated by adding 2<sup>n</sup> to the value where {@code n} is the
    941  *     number of bits in the type as returned by the static {@code SIZE} field
    942  *     in the {@linkplain Byte#SIZE Byte}, {@linkplain Short#SIZE Short},
    943  *     {@linkplain Integer#SIZE Integer}, or {@linkplain Long#SIZE Long}
    944  *     classes as appropriate.
    945  *
    946  *     <p> If the {@code '#'} flag is given then the output will always begin
    947  *     with the radix indicator {@code "0x"}.
    948  *
    949  *     <p> If the {@code '0'} flag is given then the output will be padded to
    950  *     the field width with leading zeros after the radix indicator or sign (if
    951  *     present).
    952  *
    953  *     <p> If {@code '('}, <tt>'&nbsp;&nbsp;'</tt>, {@code '+'}, or
    954  *     {@code ','} flags are given then a {@link
    955  *     FormatFlagsConversionMismatchException} will be thrown.
    956  *
    957  * <tr><td valign="top"> {@code 'X'}
    958  *     <td valign="top"> <tt>'&#92;u0058'</tt>
    959  *     <td> The upper-case variant of {@code 'x'}.  The entire string
    960  *     representing the number will be converted to {@linkplain
    961  *     String#toUpperCase upper case} including the {@code 'x'} (if any) and
    962  *     all hexadecimal digits {@code 'a'} - {@code 'f'}
    963  *     (<tt>'&#92;u0061'</tt> -  <tt>'&#92;u0066'</tt>).
    964  *
    965  * </table>
    966  *
    967  * <p> If the conversion is {@code 'o'}, {@code 'x'}, or {@code 'X'} and
    968  * both the {@code '#'} and the {@code '0'} flags are given, then result will
    969  * contain the radix indicator ({@code '0'} for octal and {@code "0x"} or
    970  * {@code "0X"} for hexadecimal), some number of zeros (based on the width),
    971  * and the value.
    972  *
    973  * <p> If the {@code '-'} flag is not given, then the space padding will occur
    974  * before the sign.
    975  *
    976  * <p> The following <a name="intFlags">flags</a> apply to numeric integral
    977  * conversions:
    978  *
    979  * <table cellpadding=5 summary="intFlags">
    980  *
    981  * <tr><td valign="top"> {@code '+'}
    982  *     <td valign="top"> <tt>'&#92;u002b'</tt>
    983  *     <td> Requires the output to include a positive sign for all positive
    984  *     numbers.  If this flag is not given then only negative values will
    985  *     include a sign.
    986  *
    987  *     <p> If both the {@code '+'} and <tt>'&nbsp;&nbsp;'</tt> flags are given
    988  *     then an {@link IllegalFormatFlagsException} will be thrown.
    989  *
    990  * <tr><td valign="top"> <tt>'&nbsp;&nbsp;'</tt>
    991  *     <td valign="top"> <tt>'&#92;u0020'</tt>
    992  *     <td> Requires the output to include a single extra space
    993  *     (<tt>'&#92;u0020'</tt>) for non-negative values.
    994  *
    995  *     <p> If both the {@code '+'} and <tt>'&nbsp;&nbsp;'</tt> flags are given
    996  *     then an {@link IllegalFormatFlagsException} will be thrown.
    997  *
    998  * <tr><td valign="top"> {@code '0'}
    999  *     <td valign="top"> <tt>'&#92;u0030'</tt>
   1000  *     <td> Requires the output to be padded with leading {@linkplain
   1001  *     java.text.DecimalFormatSymbols#getZeroDigit zeros} to the minimum field
   1002  *     width following any sign or radix indicator except when converting NaN
   1003  *     or infinity.  If the width is not provided, then a {@link
   1004  *     MissingFormatWidthException} will be thrown.
   1005  *
   1006  *     <p> If both the {@code '-'} and {@code '0'} flags are given then an
   1007  *     {@link IllegalFormatFlagsException} will be thrown.
   1008  *
   1009  * <tr><td valign="top"> {@code ','}
   1010  *     <td valign="top"> <tt>'&#92;u002c'</tt>
   1011  *     <td> Requires the output to include the locale-specific {@linkplain
   1012  *     java.text.DecimalFormatSymbols#getGroupingSeparator group separators} as
   1013  *     described in the <a href="#L10nGroup">"group" section</a> of the
   1014  *     localization algorithm.
   1015  *
   1016  * <tr><td valign="top"> {@code '('}
   1017  *     <td valign="top"> <tt>'&#92;u0028'</tt>
   1018  *     <td> Requires the output to prepend a {@code '('}
   1019  *     (<tt>'&#92;u0028'</tt>) and append a {@code ')'}
   1020  *     (<tt>'&#92;u0029'</tt>) to negative values.
   1021  *
   1022  * </table>
   1023  *
   1024  * <p> If no <a name="intdFlags">flags</a> are given the default formatting is
   1025  * as follows:
   1026  *
   1027  * <ul>
   1028  *
   1029  * <li> The output is right-justified within the {@code width}
   1030  *
   1031  * <li> Negative numbers begin with a {@code '-'} (<tt>'&#92;u002d'</tt>)
   1032  *
   1033  * <li> Positive numbers and zero do not include a sign or extra leading
   1034  * space
   1035  *
   1036  * <li> No grouping separators are included
   1037  *
   1038  * </ul>
   1039  *
   1040  * <p> The <a name="intWidth">width</a> is the minimum number of characters to
   1041  * be written to the output.  This includes any signs, digits, grouping
   1042  * separators, radix indicator, and parentheses.  If the length of the
   1043  * converted value is less than the width then the output will be padded by
   1044  * spaces (<tt>'&#92;u0020'</tt>) until the total number of characters equals
   1045  * width.  The padding is on the left by default.  If {@code '-'} flag is
   1046  * given then the padding will be on the right.  If width is not specified then
   1047  * there is no minimum.
   1048  *
   1049  * <p> The precision is not applicable.  If precision is specified then an
   1050  * {@link IllegalFormatPrecisionException} will be thrown.
   1051  *
   1052  * <p><a name="dnbint"><b> BigInteger </b></a>
   1053  *
   1054  * <p> The following conversions may be applied to {@link
   1055  * java.math.BigInteger}.
   1056  *
   1057  * <table cellpadding=5 summary="BIntConv">
   1058  *
   1059  * <tr><td valign="top"> {@code 'd'}
   1060  *     <td valign="top"> <tt>'&#92;u0064'</tt>
   1061  *     <td> Requires the output to be formatted as a decimal integer. The <a
   1062  *     href="#L10nAlgorithm">localization algorithm</a> is applied.
   1063  *
   1064  *     <p> If the {@code '#'} flag is given {@link
   1065  *     FormatFlagsConversionMismatchException} will be thrown.
   1066  *
   1067  * <tr><td valign="top"> {@code 'o'}
   1068  *     <td valign="top"> <tt>'&#92;u006f'</tt>
   1069  *     <td> Requires the output to be formatted as an integer in base eight.
   1070  *     No localization is applied.
   1071  *
   1072  *     <p> If <i>x</i> is negative then the result will be a signed value
   1073  *     beginning with {@code '-'} (<tt>'&#92;u002d'</tt>).  Signed output is
   1074  *     allowed for this type because unlike the primitive types it is not
   1075  *     possible to create an unsigned equivalent without assuming an explicit
   1076  *     data-type size.
   1077  *
   1078  *     <p> If <i>x</i> is positive or zero and the {@code '+'} flag is given
   1079  *     then the result will begin with {@code '+'} (<tt>'&#92;u002b'</tt>).
   1080  *
   1081  *     <p> If the {@code '#'} flag is given then the output will always begin
   1082  *     with {@code '0'} prefix.
   1083  *
   1084  *     <p> If the {@code '0'} flag is given then the output will be padded
   1085  *     with leading zeros to the field width following any indication of sign.
   1086  *
   1087  *     <p> If the {@code ','} flag is given then a {@link
   1088  *     FormatFlagsConversionMismatchException} will be thrown.
   1089  *
   1090  * <tr><td valign="top"> {@code 'x'}
   1091  *     <td valign="top"> <tt>'&#92;u0078'</tt>
   1092  *     <td> Requires the output to be formatted as an integer in base
   1093  *     sixteen.  No localization is applied.
   1094  *
   1095  *     <p> If <i>x</i> is negative then the result will be a signed value
   1096  *     beginning with {@code '-'} (<tt>'&#92;u002d'</tt>).  Signed output is
   1097  *     allowed for this type because unlike the primitive types it is not
   1098  *     possible to create an unsigned equivalent without assuming an explicit
   1099  *     data-type size.
   1100  *
   1101  *     <p> If <i>x</i> is positive or zero and the {@code '+'} flag is given
   1102  *     then the result will begin with {@code '+'} (<tt>'&#92;u002b'</tt>).
   1103  *
   1104  *     <p> If the {@code '#'} flag is given then the output will always begin
   1105  *     with the radix indicator {@code "0x"}.
   1106  *
   1107  *     <p> If the {@code '0'} flag is given then the output will be padded to
   1108  *     the field width with leading zeros after the radix indicator or sign (if
   1109  *     present).
   1110  *
   1111  *     <p> If the {@code ','} flag is given then a {@link
   1112  *     FormatFlagsConversionMismatchException} will be thrown.
   1113  *
   1114  * <tr><td valign="top"> {@code 'X'}
   1115  *     <td valign="top"> <tt>'&#92;u0058'</tt>
   1116  *     <td> The upper-case variant of {@code 'x'}.  The entire string
   1117  *     representing the number will be converted to {@linkplain
   1118  *     String#toUpperCase upper case} including the {@code 'x'} (if any) and
   1119  *     all hexadecimal digits {@code 'a'} - {@code 'f'}
   1120  *     (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
   1121  *
   1122  * </table>
   1123  *
   1124  * <p> If the conversion is {@code 'o'}, {@code 'x'}, or {@code 'X'} and
   1125  * both the {@code '#'} and the {@code '0'} flags are given, then result will
   1126  * contain the base indicator ({@code '0'} for octal and {@code "0x"} or
   1127  * {@code "0X"} for hexadecimal), some number of zeros (based on the width),
   1128  * and the value.
   1129  *
   1130  * <p> If the {@code '0'} flag is given and the value is negative, then the
   1131  * zero padding will occur after the sign.
   1132  *
   1133  * <p> If the {@code '-'} flag is not given, then the space padding will occur
   1134  * before the sign.
   1135  *
   1136  * <p> All <a href="#intFlags">flags</a> defined for Byte, Short, Integer, and
   1137  * Long apply.  The <a href="#intdFlags">default behavior</a> when no flags are
   1138  * given is the same as for Byte, Short, Integer, and Long.
   1139  *
   1140  * <p> The specification of <a href="#intWidth">width</a> is the same as
   1141  * defined for Byte, Short, Integer, and Long.
   1142  *
   1143  * <p> The precision is not applicable.  If precision is specified then an
   1144  * {@link IllegalFormatPrecisionException} will be thrown.
   1145  *
   1146  * <p><a name="dndec"><b> Float and Double</b></a>
   1147  *
   1148  * <p> The following conversions may be applied to {@code float}, {@link
   1149  * Float}, {@code double} and {@link Double}.
   1150  *
   1151  * <table cellpadding=5 summary="floatConv">
   1152  *
   1153  * <tr><td valign="top"> {@code 'e'}
   1154  *     <td valign="top"> <tt>'&#92;u0065'</tt>
   1155  *     <td> Requires the output to be formatted using <a
   1156  *     name="scientific">computerized scientific notation</a>.  The <a
   1157  *     href="#L10nAlgorithm">localization algorithm</a> is applied.
   1158  *
   1159  *     <p> The formatting of the magnitude <i>m</i> depends upon its value.
   1160  *
   1161  *     <p> If <i>m</i> is NaN or infinite, the literal strings "NaN" or
   1162  *     "Infinity", respectively, will be output.  These values are not
   1163  *     localized.
   1164  *
   1165  *     <p> If <i>m</i> is positive-zero or negative-zero, then the exponent
   1166  *     will be {@code "+00"}.
   1167  *
   1168  *     <p> Otherwise, the result is a string that represents the sign and
   1169  *     magnitude (absolute value) of the argument.  The formatting of the sign
   1170  *     is described in the <a href="#L10nAlgorithm">localization
   1171  *     algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
   1172  *     value.
   1173  *
   1174  *     <p> Let <i>n</i> be the unique integer such that 10<sup><i>n</i></sup>
   1175  *     &lt;= <i>m</i> &lt; 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
   1176  *     mathematically exact quotient of <i>m</i> and 10<sup><i>n</i></sup> so
   1177  *     that 1 &lt;= <i>a</i> &lt; 10. The magnitude is then represented as the
   1178  *     integer part of <i>a</i>, as a single decimal digit, followed by the
   1179  *     decimal separator followed by decimal digits representing the fractional
   1180  *     part of <i>a</i>, followed by the lower-case locale-specific {@linkplain
   1181  *     java.text.DecimalFormatSymbols#getExponentSeparator exponent separator}
   1182  *     (e.g. {@code 'e'}), followed by the sign of the exponent, followed
   1183  *     by a representation of <i>n</i> as a decimal integer, as produced by the
   1184  *     method {@link Long#toString(long, int)}, and zero-padded to include at
   1185  *     least two digits.
   1186  *
   1187  *     <p> The number of digits in the result for the fractional part of
   1188  *     <i>m</i> or <i>a</i> is equal to the precision.  If the precision is not
   1189  *     specified then the default value is {@code 6}. If the precision is less
   1190  *     than the number of digits which would appear after the decimal point in
   1191  *     the string returned by {@link Float#toString(float)} or {@link
   1192  *     Double#toString(double)} respectively, then the value will be rounded
   1193  *     using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
   1194  *     algorithm}.  Otherwise, zeros may be appended to reach the precision.
   1195  *     For a canonical representation of the value, use {@link
   1196  *     Float#toString(float)} or {@link Double#toString(double)} as
   1197  *     appropriate.
   1198  *
   1199  *     <p>If the {@code ','} flag is given, then an {@link
   1200  *     FormatFlagsConversionMismatchException} will be thrown.
   1201  *
   1202  * <tr><td valign="top"> {@code 'E'}
   1203  *     <td valign="top"> <tt>'&#92;u0045'</tt>
   1204  *     <td> The upper-case variant of {@code 'e'}.  The exponent symbol
   1205  *     will be the upper-case locale-specific {@linkplain
   1206  *     java.text.DecimalFormatSymbols#getExponentSeparator exponent separator}
   1207  *     (e.g. {@code 'E'}).
   1208  *
   1209  * <tr><td valign="top"> {@code 'g'}
   1210  *     <td valign="top"> <tt>'&#92;u0067'</tt>
   1211  *     <td> Requires the output to be formatted in general scientific notation
   1212  *     as described below. The <a href="#L10nAlgorithm">localization
   1213  *     algorithm</a> is applied.
   1214  *
   1215  *     <p> After rounding for the precision, the formatting of the resulting
   1216  *     magnitude <i>m</i> depends on its value.
   1217  *
   1218  *     <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
   1219  *     than 10<sup>precision</sup> then it is represented in <i><a
   1220  *     href="#decimal">decimal format</a></i>.
   1221  *
   1222  *     <p> If <i>m</i> is less than 10<sup>-4</sup> or greater than or equal to
   1223  *     10<sup>precision</sup>, then it is represented in <i><a
   1224  *     href="#scientific">computerized scientific notation</a></i>.
   1225  *
   1226  *     <p> The total number of significant digits in <i>m</i> is equal to the
   1227  *     precision.  If the precision is not specified, then the default value is
   1228  *     {@code 6}.  If the precision is {@code 0}, then it is taken to be
   1229  *     {@code 1}.
   1230  *
   1231  *     <p> If the {@code '#'} flag is given then an {@link
   1232  *     FormatFlagsConversionMismatchException} will be thrown.
   1233  *
   1234  * <tr><td valign="top"> {@code 'G'}
   1235  *     <td valign="top"> <tt>'&#92;u0047'</tt>
   1236  *     <td> The upper-case variant of {@code 'g'}.
   1237  *
   1238  * <tr><td valign="top"> {@code 'f'}
   1239  *     <td valign="top"> <tt>'&#92;u0066'</tt>
   1240  *     <td> Requires the output to be formatted using <a name="decimal">decimal
   1241  *     format</a>.  The <a href="#L10nAlgorithm">localization algorithm</a> is
   1242  *     applied.
   1243  *
   1244  *     <p> The result is a string that represents the sign and magnitude
   1245  *     (absolute value) of the argument.  The formatting of the sign is
   1246  *     described in the <a href="#L10nAlgorithm">localization
   1247  *     algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
   1248  *     value.
   1249  *
   1250  *     <p> If <i>m</i> NaN or infinite, the literal strings "NaN" or
   1251  *     "Infinity", respectively, will be output.  These values are not
   1252  *     localized.
   1253  *
   1254  *     <p> The magnitude is formatted as the integer part of <i>m</i>, with no
   1255  *     leading zeroes, followed by the decimal separator followed by one or
   1256  *     more decimal digits representing the fractional part of <i>m</i>.
   1257  *
   1258  *     <p> The number of digits in the result for the fractional part of
   1259  *     <i>m</i> or <i>a</i> is equal to the precision.  If the precision is not
   1260  *     specified then the default value is {@code 6}. If the precision is less
   1261  *     than the number of digits which would appear after the decimal point in
   1262  *     the string returned by {@link Float#toString(float)} or {@link
   1263  *     Double#toString(double)} respectively, then the value will be rounded
   1264  *     using the {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
   1265  *     algorithm}.  Otherwise, zeros may be appended to reach the precision.
   1266  *     For a canonical representation of the value, use {@link
   1267  *     Float#toString(float)} or {@link Double#toString(double)} as
   1268  *     appropriate.
   1269  *
   1270  * <tr><td valign="top"> {@code 'a'}
   1271  *     <td valign="top"> <tt>'&#92;u0061'</tt>
   1272  *     <td> Requires the output to be formatted in hexadecimal exponential
   1273  *     form.  No localization is applied.
   1274  *
   1275  *     <p> The result is a string that represents the sign and magnitude
   1276  *     (absolute value) of the argument <i>x</i>.
   1277  *
   1278  *     <p> If <i>x</i> is negative or a negative-zero value then the result
   1279  *     will begin with {@code '-'} (<tt>'&#92;u002d'</tt>).
   1280  *
   1281  *     <p> If <i>x</i> is positive or a positive-zero value and the
   1282  *     {@code '+'} flag is given then the result will begin with {@code '+'}
   1283  *     (<tt>'&#92;u002b'</tt>).
   1284  *
   1285  *     <p> The formatting of the magnitude <i>m</i> depends upon its value.
   1286  *
   1287  *     <ul>
   1288  *
   1289  *     <li> If the value is NaN or infinite, the literal strings "NaN" or
   1290  *     "Infinity", respectively, will be output.
   1291  *
   1292  *     <li> If <i>m</i> is zero then it is represented by the string
   1293  *     {@code "0x0.0p0"}.
   1294  *
   1295  *     <li> If <i>m</i> is a {@code double} value with a normalized
   1296  *     representation then substrings are used to represent the significand and
   1297  *     exponent fields.  The significand is represented by the characters
   1298  *     {@code "0x1."} followed by the hexadecimal representation of the rest
   1299  *     of the significand as a fraction.  The exponent is represented by
   1300  *     {@code 'p'} (<tt>'&#92;u0070'</tt>) followed by a decimal string of the
   1301  *     unbiased exponent as if produced by invoking {@link
   1302  *     Integer#toString(int) Integer.toString} on the exponent value.  If the
   1303  *     precision is specified, the value is rounded to the given number of
   1304  *     hexadecimal digits.
   1305  *
   1306  *     <li> If <i>m</i> is a {@code double} value with a subnormal
   1307  *     representation then, unless the precision is specified to be in the range
   1308  *     1 through 12, inclusive, the significand is represented by the characters
   1309  *     {@code '0x0.'} followed by the hexadecimal representation of the rest of
   1310  *     the significand as a fraction, and the exponent represented by
   1311  *     {@code 'p-1022'}.  If the precision is in the interval
   1312  *     [1,&nbsp;12], the subnormal value is normalized such that it
   1313  *     begins with the characters {@code '0x1.'}, rounded to the number of
   1314  *     hexadecimal digits of precision, and the exponent adjusted
   1315  *     accordingly.  Note that there must be at least one nonzero digit in a
   1316  *     subnormal significand.
   1317  *
   1318  *     </ul>
   1319  *
   1320  *     <p> If the {@code '('} or {@code ','} flags are given, then a {@link
   1321  *     FormatFlagsConversionMismatchException} will be thrown.
   1322  *
   1323  * <tr><td valign="top"> {@code 'A'}
   1324  *     <td valign="top"> <tt>'&#92;u0041'</tt>
   1325  *     <td> The upper-case variant of {@code 'a'}.  The entire string
   1326  *     representing the number will be converted to upper case including the
   1327  *     {@code 'x'} (<tt>'&#92;u0078'</tt>) and {@code 'p'}
   1328  *     (<tt>'&#92;u0070'</tt> and all hexadecimal digits {@code 'a'} -
   1329  *     {@code 'f'} (<tt>'&#92;u0061'</tt> - <tt>'&#92;u0066'</tt>).
   1330  *
   1331  * </table>
   1332  *
   1333  * <p> All <a href="#intFlags">flags</a> defined for Byte, Short, Integer, and
   1334  * Long apply.
   1335  *
   1336  * <p> If the {@code '#'} flag is given, then the decimal separator will
   1337  * always be present.
   1338  *
   1339  * <p> If no <a name="floatdFlags">flags</a> are given the default formatting
   1340  * is as follows:
   1341  *
   1342  * <ul>
   1343  *
   1344  * <li> The output is right-justified within the {@code width}
   1345  *
   1346  * <li> Negative numbers begin with a {@code '-'}
   1347  *
   1348  * <li> Positive numbers and positive zero do not include a sign or extra
   1349  * leading space
   1350  *
   1351  * <li> No grouping separators are included
   1352  *
   1353  * <li> The decimal separator will only appear if a digit follows it
   1354  *
   1355  * </ul>
   1356  *
   1357  * <p> The <a name="floatDWidth">width</a> is the minimum number of characters
   1358  * to be written to the output.  This includes any signs, digits, grouping
   1359  * separators, decimal separators, exponential symbol, radix indicator,
   1360  * parentheses, and strings representing infinity and NaN as applicable.  If
   1361  * the length of the converted value is less than the width then the output
   1362  * will be padded by spaces (<tt>'&#92;u0020'</tt>) until the total number of
   1363  * characters equals width.  The padding is on the left by default.  If the
   1364  * {@code '-'} flag is given then the padding will be on the right.  If width
   1365  * is not specified then there is no minimum.
   1366  *
   1367  * <p> If the <a name="floatDPrec">conversion</a> is {@code 'e'},
   1368  * {@code 'E'} or {@code 'f'}, then the precision is the number of digits
   1369  * after the decimal separator.  If the precision is not specified, then it is
   1370  * assumed to be {@code 6}.
   1371  *
   1372  * <p> If the conversion is {@code 'g'} or {@code 'G'}, then the precision is
   1373  * the total number of significant digits in the resulting magnitude after
   1374  * rounding.  If the precision is not specified, then the default value is
   1375  * {@code 6}.  If the precision is {@code 0}, then it is taken to be
   1376  * {@code 1}.
   1377  *
   1378  * <p> If the conversion is {@code 'a'} or {@code 'A'}, then the precision
   1379  * is the number of hexadecimal digits after the radix point.  If the
   1380  * precision is not provided, then all of the digits as returned by {@link
   1381  * Double#toHexString(double)} will be output.
   1382  *
   1383  * <p><a name="dnbdec"><b> BigDecimal </b></a>
   1384  *
   1385  * <p> The following conversions may be applied {@link java.math.BigDecimal
   1386  * BigDecimal}.
   1387  *
   1388  * <table cellpadding=5 summary="floatConv">
   1389  *
   1390  * <tr><td valign="top"> {@code 'e'}
   1391  *     <td valign="top"> <tt>'&#92;u0065'</tt>
   1392  *     <td> Requires the output to be formatted using <a
   1393  *     name="bscientific">computerized scientific notation</a>.  The <a
   1394  *     href="#L10nAlgorithm">localization algorithm</a> is applied.
   1395  *
   1396  *     <p> The formatting of the magnitude <i>m</i> depends upon its value.
   1397  *
   1398  *     <p> If <i>m</i> is positive-zero or negative-zero, then the exponent
   1399  *     will be {@code "+00"}.
   1400  *
   1401  *     <p> Otherwise, the result is a string that represents the sign and
   1402  *     magnitude (absolute value) of the argument.  The formatting of the sign
   1403  *     is described in the <a href="#L10nAlgorithm">localization
   1404  *     algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
   1405  *     value.
   1406  *
   1407  *     <p> Let <i>n</i> be the unique integer such that 10<sup><i>n</i></sup>
   1408  *     &lt;= <i>m</i> &lt; 10<sup><i>n</i>+1</sup>; then let <i>a</i> be the
   1409  *     mathematically exact quotient of <i>m</i> and 10<sup><i>n</i></sup> so
   1410  *     that 1 &lt;= <i>a</i> &lt; 10. The magnitude is then represented as the
   1411  *     integer part of <i>a</i>, as a single decimal digit, followed by the
   1412  *     decimal separator followed by decimal digits representing the fractional
   1413  *     part of <i>a</i>, followed by the exponent symbol {@code 'e'}
   1414  *     (<tt>'&#92;u0065'</tt>), followed by the sign of the exponent, followed
   1415  *     by a representation of <i>n</i> as a decimal integer, as produced by the
   1416  *     method {@link Long#toString(long, int)}, and zero-padded to include at
   1417  *     least two digits.
   1418  *
   1419  *     <p> The number of digits in the result for the fractional part of
   1420  *     <i>m</i> or <i>a</i> is equal to the precision.  If the precision is not
   1421  *     specified then the default value is {@code 6}.  If the precision is
   1422  *     less than the number of digits to the right of the decimal point then
   1423  *     the value will be rounded using the
   1424  *     {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
   1425  *     algorithm}.  Otherwise, zeros may be appended to reach the precision.
   1426  *     For a canonical representation of the value, use {@link
   1427  *     BigDecimal#toString()}.
   1428  *
   1429  *     <p> If the {@code ','} flag is given, then an {@link
   1430  *     FormatFlagsConversionMismatchException} will be thrown.
   1431  *
   1432  * <tr><td valign="top"> {@code 'E'}
   1433  *     <td valign="top"> <tt>'&#92;u0045'</tt>
   1434  *     <td> The upper-case variant of {@code 'e'}.  The exponent symbol
   1435  *     will be {@code 'E'} (<tt>'&#92;u0045'</tt>).
   1436  *
   1437  * <tr><td valign="top"> {@code 'g'}
   1438  *     <td valign="top"> <tt>'&#92;u0067'</tt>
   1439  *     <td> Requires the output to be formatted in general scientific notation
   1440  *     as described below. The <a href="#L10nAlgorithm">localization
   1441  *     algorithm</a> is applied.
   1442  *
   1443  *     <p> After rounding for the precision, the formatting of the resulting
   1444  *     magnitude <i>m</i> depends on its value.
   1445  *
   1446  *     <p> If <i>m</i> is greater than or equal to 10<sup>-4</sup> but less
   1447  *     than 10<sup>precision</sup> then it is represented in <i><a
   1448  *     href="#bdecimal">decimal format</a></i>.
   1449  *
   1450  *     <p> If <i>m</i> is less than 10<sup>-4</sup> or greater than or equal to
   1451  *     10<sup>precision</sup>, then it is represented in <i><a
   1452  *     href="#bscientific">computerized scientific notation</a></i>.
   1453  *
   1454  *     <p> The total number of significant digits in <i>m</i> is equal to the
   1455  *     precision.  If the precision is not specified, then the default value is
   1456  *     {@code 6}.  If the precision is {@code 0}, then it is taken to be
   1457  *     {@code 1}.
   1458  *
   1459  *     <p> If the {@code '#'} flag is given then an {@link
   1460  *     FormatFlagsConversionMismatchException} will be thrown.
   1461  *
   1462  * <tr><td valign="top"> {@code 'G'}
   1463  *     <td valign="top"> <tt>'&#92;u0047'</tt>
   1464  *     <td> The upper-case variant of {@code 'g'}.
   1465  *
   1466  * <tr><td valign="top"> {@code 'f'}
   1467  *     <td valign="top"> <tt>'&#92;u0066'</tt>
   1468  *     <td> Requires the output to be formatted using <a name="bdecimal">decimal
   1469  *     format</a>.  The <a href="#L10nAlgorithm">localization algorithm</a> is
   1470  *     applied.
   1471  *
   1472  *     <p> The result is a string that represents the sign and magnitude
   1473  *     (absolute value) of the argument.  The formatting of the sign is
   1474  *     described in the <a href="#L10nAlgorithm">localization
   1475  *     algorithm</a>. The formatting of the magnitude <i>m</i> depends upon its
   1476  *     value.
   1477  *
   1478  *     <p> The magnitude is formatted as the integer part of <i>m</i>, with no
   1479  *     leading zeroes, followed by the decimal separator followed by one or
   1480  *     more decimal digits representing the fractional part of <i>m</i>.
   1481  *
   1482  *     <p> The number of digits in the result for the fractional part of
   1483  *     <i>m</i> or <i>a</i> is equal to the precision. If the precision is not
   1484  *     specified then the default value is {@code 6}.  If the precision is
   1485  *     less than the number of digits to the right of the decimal point
   1486  *     then the value will be rounded using the
   1487  *     {@linkplain java.math.BigDecimal#ROUND_HALF_UP round half up
   1488  *     algorithm}.  Otherwise, zeros may be appended to reach the precision.
   1489  *     For a canonical representation of the value, use {@link
   1490  *     BigDecimal#toString()}.
   1491  *
   1492  * </table>
   1493  *
   1494  * <p> All <a href="#intFlags">flags</a> defined for Byte, Short, Integer, and
   1495  * Long apply.
   1496  *
   1497  * <p> If the {@code '#'} flag is given, then the decimal separator will
   1498  * always be present.
   1499  *
   1500  * <p> The <a href="#floatdFlags">default behavior</a> when no flags are
   1501  * given is the same as for Float and Double.
   1502  *
   1503  * <p> The specification of <a href="#floatDWidth">width</a> and <a
   1504  * href="#floatDPrec">precision</a> is the same as defined for Float and
   1505  * Double.
   1506  *
   1507  * <h4><a name="ddt">Date/Time</a></h4>
   1508  *
   1509  * <p> This conversion may be applied to {@code long}, {@link Long}, {@link
   1510  * Calendar}, {@link Date} and {@link TemporalAccessor TemporalAccessor}
   1511  *
   1512  * <table cellpadding=5 summary="DTConv">
   1513  *
   1514  * <tr><td valign="top"> {@code 't'}
   1515  *     <td valign="top"> <tt>'&#92;u0074'</tt>
   1516  *     <td> Prefix for date and time conversion characters.
   1517  * <tr><td valign="top"> {@code 'T'}
   1518  *     <td valign="top"> <tt>'&#92;u0054'</tt>
   1519  *     <td> The upper-case variant of {@code 't'}.
   1520  *
   1521  * </table>
   1522  *
   1523  * <p> The following date and time conversion character suffixes are defined
   1524  * for the {@code 't'} and {@code 'T'} conversions.  The types are similar to
   1525  * but not completely identical to those defined by GNU {@code date} and
   1526  * POSIX {@code strftime(3c)}.  Additional conversion types are provided to
   1527  * access Java-specific functionality (e.g. {@code 'L'} for milliseconds
   1528  * within the second).
   1529  *
   1530  * <p> The following conversion characters are used for formatting times:
   1531  *
   1532  * <table cellpadding=5 summary="time">
   1533  *
   1534  * <tr><td valign="top"> {@code 'H'}
   1535  *     <td valign="top"> <tt>'&#92;u0048'</tt>
   1536  *     <td> Hour of the day for the 24-hour clock, formatted as two digits with
   1537  *     a leading zero as necessary i.e. {@code 00 - 23}. {@code 00}
   1538  *     corresponds to midnight.
   1539  *
   1540  * <tr><td valign="top">{@code 'I'}
   1541  *     <td valign="top"> <tt>'&#92;u0049'</tt>
   1542  *     <td> Hour for the 12-hour clock, formatted as two digits with a leading
   1543  *     zero as necessary, i.e.  {@code 01 - 12}.  {@code 01} corresponds to
   1544  *     one o'clock (either morning or afternoon).
   1545  *
   1546  * <tr><td valign="top">{@code 'k'}
   1547  *     <td valign="top"> <tt>'&#92;u006b'</tt>
   1548  *     <td> Hour of the day for the 24-hour clock, i.e. {@code 0 - 23}.
   1549  *     {@code 0} corresponds to midnight.
   1550  *
   1551  * <tr><td valign="top">{@code 'l'}
   1552  *     <td valign="top"> <tt>'&#92;u006c'</tt>
   1553  *     <td> Hour for the 12-hour clock, i.e. {@code 1 - 12}.  {@code 1}
   1554  *     corresponds to one o'clock (either morning or afternoon).
   1555  *
   1556  * <tr><td valign="top">{@code 'M'}
   1557  *     <td valign="top"> <tt>'&#92;u004d'</tt>
   1558  *     <td> Minute within the hour formatted as two digits with a leading zero
   1559  *     as necessary, i.e.  {@code 00 - 59}.
   1560  *
   1561  * <tr><td valign="top">{@code 'S'}
   1562  *     <td valign="top"> <tt>'&#92;u0053'</tt>
   1563  *     <td> Seconds within the minute, formatted as two digits with a leading
   1564  *     zero as necessary, i.e. {@code 00 - 60} ("{@code 60}" is a special
   1565  *     value required to support leap seconds).
   1566  *
   1567  * <tr><td valign="top">{@code 'L'}
   1568  *     <td valign="top"> <tt>'&#92;u004c'</tt>
   1569  *     <td> Millisecond within the second formatted as three digits with
   1570  *     leading zeros as necessary, i.e. {@code 000 - 999}.
   1571  *
   1572  * <tr><td valign="top">{@code 'N'}
   1573  *     <td valign="top"> <tt>'&#92;u004e'</tt>
   1574  *     <td> Nanosecond within the second, formatted as nine digits with leading
   1575  *     zeros as necessary, i.e. {@code 000000000 - 999999999}.  The precision
   1576  *     of this value is limited by the resolution of the underlying operating
   1577  *     system or hardware.
   1578  *
   1579  * <tr><td valign="top">{@code 'p'}
   1580  *     <td valign="top"> <tt>'&#92;u0070'</tt>
   1581  *     <td> Locale-specific {@linkplain
   1582  *     java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker
   1583  *     in lower case, e.g."{@code am}" or "{@code pm}".  Use of the
   1584  *     conversion prefix {@code 'T'} forces this output to upper case.  (Note
   1585  *     that {@code 'p'} produces lower-case output.  This is different from
   1586  *     GNU {@code date} and POSIX {@code strftime(3c)} which produce
   1587  *     upper-case output.)
   1588  *
   1589  * <tr><td valign="top">{@code 'z'}
   1590  *     <td valign="top"> <tt>'&#92;u007a'</tt>
   1591  *     <td> <a href="http://www.ietf.org/rfc/rfc0822.txt">RFC&nbsp;822</a>
   1592  *     style numeric time zone offset from GMT, e.g. {@code -0800}.  This
   1593  *     value will be adjusted as necessary for Daylight Saving Time.  For
   1594  *     {@code long}, {@link Long}, and {@link Date} the time zone used is
   1595  *     the {@linkplain TimeZone#getDefault() default time zone} for this
   1596  *     instance of the Java virtual machine.
   1597  *
   1598  * <tr><td valign="top">{@code 'Z'}
   1599  *     <td valign="top"> <tt>'&#92;u005a'</tt>
   1600  *     <td> A string representing the abbreviation for the time zone.  This
   1601  *     value will be adjusted as necessary for Daylight Saving Time.  For
   1602  *     {@code long}, {@link Long}, and {@link Date} the time zone used is
   1603  *     the {@linkplain TimeZone#getDefault() default time zone} for this
   1604  *     instance of the Java virtual machine.  The Formatter's locale will
   1605  *     supersede the locale of the argument (if any).
   1606  *
   1607  * <tr><td valign="top">{@code 's'}
   1608  *     <td valign="top"> <tt>'&#92;u0073'</tt>
   1609  *     <td> Seconds since the beginning of the epoch starting at 1 January 1970
   1610  *     {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE/1000} to
   1611  *     {@code Long.MAX_VALUE/1000}.
   1612  *
   1613  * <tr><td valign="top">{@code 'Q'}
   1614  *     <td valign="top"> <tt>'&#92;u004f'</tt>
   1615  *     <td> Milliseconds since the beginning of the epoch starting at 1 January
   1616  *     1970 {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE} to
   1617  *     {@code Long.MAX_VALUE}. The precision of this value is limited by
   1618  *     the resolution of the underlying operating system or hardware.
   1619  *
   1620  * </table>
   1621  *
   1622  * <p> The following conversion characters are used for formatting dates:
   1623  *
   1624  * <table cellpadding=5 summary="date">
   1625  *
   1626  * <tr><td valign="top">{@code 'B'}
   1627  *     <td valign="top"> <tt>'&#92;u0042'</tt>
   1628  *     <td> Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths
   1629  *     full month name}, e.g. {@code "January"}, {@code "February"}.
   1630  *
   1631  * <tr><td valign="top">{@code 'b'}
   1632  *     <td valign="top"> <tt>'&#92;u0062'</tt>
   1633  *     <td> Locale-specific {@linkplain
   1634  *     java.text.DateFormatSymbols#getShortMonths abbreviated month name},
   1635  *     e.g. {@code "Jan"}, {@code "Feb"}.
   1636  *
   1637  * <tr><td valign="top">{@code 'h'}
   1638  *     <td valign="top"> <tt>'&#92;u0068'</tt>
   1639  *     <td> Same as {@code 'b'}.
   1640  *
   1641  * <tr><td valign="top">{@code 'A'}
   1642  *     <td valign="top"> <tt>'&#92;u0041'</tt>
   1643  *     <td> Locale-specific full name of the {@linkplain
   1644  *     java.text.DateFormatSymbols#getWeekdays day of the week},
   1645  *     e.g. {@code "Sunday"}, {@code "Monday"}
   1646  *
   1647  * <tr><td valign="top">{@code 'a'}
   1648  *     <td valign="top"> <tt>'&#92;u0061'</tt>
   1649  *     <td> Locale-specific short name of the {@linkplain
   1650  *     java.text.DateFormatSymbols#getShortWeekdays day of the week},
   1651  *     e.g. {@code "Sun"}, {@code "Mon"}
   1652  *
   1653  * <tr><td valign="top">{@code 'C'}
   1654  *     <td valign="top"> <tt>'&#92;u0043'</tt>
   1655  *     <td> Four-digit year divided by {@code 100}, formatted as two digits
   1656  *     with leading zero as necessary, i.e. {@code 00 - 99}
   1657  *
   1658  * <tr><td valign="top">{@code 'Y'}
   1659  *     <td valign="top"> <tt>'&#92;u0059'</tt> <td> Year, formatted to at least
   1660  *     four digits with leading zeros as necessary, e.g. {@code 0092} equals
   1661  *     {@code 92} CE for the Gregorian calendar.
   1662  *
   1663  * <tr><td valign="top">{@code 'y'}
   1664  *     <td valign="top"> <tt>'&#92;u0079'</tt>
   1665  *     <td> Last two digits of the year, formatted with leading zeros as
   1666  *     necessary, i.e. {@code 00 - 99}.
   1667  *
   1668  * <tr><td valign="top">{@code 'j'}
   1669  *     <td valign="top"> <tt>'&#92;u006a'</tt>
   1670  *     <td> Day of year, formatted as three digits with leading zeros as
   1671  *     necessary, e.g. {@code 001 - 366} for the Gregorian calendar.
   1672  *     {@code 001} corresponds to the first day of the year.
   1673  *
   1674  * <tr><td valign="top">{@code 'm'}
   1675  *     <td valign="top"> <tt>'&#92;u006d'</tt>
   1676  *     <td> Month, formatted as two digits with leading zeros as necessary,
   1677  *     i.e. {@code 01 - 13}, where "{@code 01}" is the first month of the
   1678  *     year and ("{@code 13}" is a special value required to support lunar
   1679  *     calendars).
   1680  *
   1681  * <tr><td valign="top">{@code 'd'}
   1682  *     <td valign="top"> <tt>'&#92;u0064'</tt>
   1683  *     <td> Day of month, formatted as two digits with leading zeros as
   1684  *     necessary, i.e. {@code 01 - 31}, where "{@code 01}" is the first day
   1685  *     of the month.
   1686  *
   1687  * <tr><td valign="top">{@code 'e'}
   1688  *     <td valign="top"> <tt>'&#92;u0065'</tt>
   1689  *     <td> Day of month, formatted as two digits, i.e. {@code 1 - 31} where
   1690  *     "{@code 1}" is the first day of the month.
   1691  *
   1692  * </table>
   1693  *
   1694  * <p> The following conversion characters are used for formatting common
   1695  * date/time compositions.
   1696  *
   1697  * <table cellpadding=5 summary="composites">
   1698  *
   1699  * <tr><td valign="top">{@code 'R'}
   1700  *     <td valign="top"> <tt>'&#92;u0052'</tt>
   1701  *     <td> Time formatted for the 24-hour clock as {@code "%tH:%tM"}
   1702  *
   1703  * <tr><td valign="top">{@code 'T'}
   1704  *     <td valign="top"> <tt>'&#92;u0054'</tt>
   1705  *     <td> Time formatted for the 24-hour clock as {@code "%tH:%tM:%tS"}.
   1706  *
   1707  * <tr><td valign="top">{@code 'r'}
   1708  *     <td valign="top"> <tt>'&#92;u0072'</tt>
   1709  *     <td> Time formatted for the 12-hour clock as {@code "%tI:%tM:%tS
   1710  *     %Tp"}.  The location of the morning or afternoon marker
   1711  *     ({@code '%Tp'}) may be locale-dependent.
   1712  *
   1713  * <tr><td valign="top">{@code 'D'}
   1714  *     <td valign="top"> <tt>'&#92;u0044'</tt>
   1715  *     <td> Date formatted as {@code "%tm/%td/%ty"}.
   1716  *
   1717  * <tr><td valign="top">{@code 'F'}
   1718  *     <td valign="top"> <tt>'&#92;u0046'</tt>
   1719  *     <td> <a href="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a>
   1720  *     complete date formatted as {@code "%tY-%tm-%td"}.
   1721  *
   1722  * <tr><td valign="top">{@code 'c'}
   1723  *     <td valign="top"> <tt>'&#92;u0063'</tt>
   1724  *     <td> Date and time formatted as {@code "%ta %tb %td %tT %tZ %tY"},
   1725  *     e.g. {@code "Sun Jul 20 16:17:00 EDT 1969"}.
   1726  *
   1727  * </table>
   1728  *
   1729  * <p> The {@code '-'} flag defined for <a href="#dFlags">General
   1730  * conversions</a> applies.  If the {@code '#'} flag is given, then a {@link
   1731  * FormatFlagsConversionMismatchException} will be thrown.
   1732  *
   1733  * <p> The width is the minimum number of characters to
   1734  * be written to the output.  If the length of the converted value is less than
   1735  * the {@code width} then the output will be padded by spaces
   1736  * (<tt>'&#92;u0020'</tt>) until the total number of characters equals width.
   1737  * The padding is on the left by default.  If the {@code '-'} flag is given
   1738  * then the padding will be on the right.  If width is not specified then there
   1739  * is no minimum.
   1740  *
   1741  * <p> The precision is not applicable.  If the precision is specified then an
   1742  * {@link IllegalFormatPrecisionException} will be thrown.
   1743  *
   1744  * <h4><a name="dper">Percent</a></h4>
   1745  *
   1746  * <p> The conversion does not correspond to any argument.
   1747  *
   1748  * <table cellpadding=5 summary="DTConv">
   1749  *
   1750  * <tr><td valign="top">{@code '%'}
   1751  *     <td> The result is a literal {@code '%'} (<tt>'&#92;u0025'</tt>)
   1752  *
   1753  * <p> The width is the minimum number of characters to
   1754  * be written to the output including the {@code '%'}.  If the length of the
   1755  * converted value is less than the {@code width} then the output will be
   1756  * padded by spaces (<tt>'&#92;u0020'</tt>) until the total number of
   1757  * characters equals width.  The padding is on the left.  If width is not
   1758  * specified then just the {@code '%'} is output.
   1759  *
   1760  * <p> The {@code '-'} flag defined for <a href="#dFlags">General
   1761  * conversions</a> applies.  If any other flags are provided, then a
   1762  * {@link FormatFlagsConversionMismatchException} will be thrown.
   1763  *
   1764  * <p> The precision is not applicable.  If the precision is specified an
   1765  * {@link IllegalFormatPrecisionException} will be thrown.
   1766  *
   1767  * </table>
   1768  *
   1769  * <h4><a name="dls">Line Separator</a></h4>
   1770  *
   1771  * <p> The conversion does not correspond to any argument.
   1772  *
   1773  * <table cellpadding=5 summary="DTConv">
   1774  *
   1775  * <tr><td valign="top">{@code 'n'}
   1776  *     <td> the platform-specific line separator as returned by {@link
   1777  *     System#getProperty System.getProperty("line.separator")}.
   1778  *
   1779  * </table>
   1780  *
   1781  * <p> Flags, width, and precision are not applicable.  If any are provided an
   1782  * {@link IllegalFormatFlagsException}, {@link IllegalFormatWidthException},
   1783  * and {@link IllegalFormatPrecisionException}, respectively will be thrown.
   1784  *
   1785  * <h4><a name="dpos">Argument Index</a></h4>
   1786  *
   1787  * <p> Format specifiers can reference arguments in three ways:
   1788  *
   1789  * <ul>
   1790  *
   1791  * <li> <i>Explicit indexing</i> is used when the format specifier contains an
   1792  * argument index.  The argument index is a decimal integer indicating the
   1793  * position of the argument in the argument list.  The first argument is
   1794  * referenced by "{@code 1$}", the second by "{@code 2$}", etc.  An argument
   1795  * may be referenced more than once.
   1796  *
   1797  * <p> For example:
   1798  *
   1799  * <blockquote><pre>
   1800  *   formatter.format("%4$s %3$s %2$s %1$s %4$s %3$s %2$s %1$s",
   1801  *                    "a", "b", "c", "d")
   1802  *   // -&gt; "d c b a d c b a"
   1803  * </pre></blockquote>
   1804  *
   1805  * <li> <i>Relative indexing</i> is used when the format specifier contains a
   1806  * {@code '<'} (<tt>'&#92;u003c'</tt>) flag which causes the argument for
   1807  * the previous format specifier to be re-used.  If there is no previous
   1808  * argument, then a {@link MissingFormatArgumentException} is thrown.
   1809  *
   1810  * <blockquote><pre>
   1811  *    formatter.format("%s %s %&lt;s %&lt;s", "a", "b", "c", "d")
   1812  *    // -&gt; "a b b b"
   1813  *    // "c" and "d" are ignored because they are not referenced
   1814  * </pre></blockquote>
   1815  *
   1816  * <li> <i>Ordinary indexing</i> is used when the format specifier contains
   1817  * neither an argument index nor a {@code '<'} flag.  Each format specifier
   1818  * which uses ordinary indexing is assigned a sequential implicit index into
   1819  * argument list which is independent of the indices used by explicit or
   1820  * relative indexing.
   1821  *
   1822  * <blockquote><pre>
   1823  *   formatter.format("%s %s %s %s", "a", "b", "c", "d")
   1824  *   // -&gt; "a b c d"
   1825  * </pre></blockquote>
   1826  *
   1827  * </ul>
   1828  *
   1829  * <p> It is possible to have a format string which uses all forms of indexing,
   1830  * for example:
   1831  *
   1832  * <blockquote><pre>
   1833  *   formatter.format("%2$s %s %&lt;s %s", "a", "b", "c", "d")
   1834  *   // -&gt; "b a a b"
   1835  *   // "c" and "d" are ignored because they are not referenced
   1836  * </pre></blockquote>
   1837  *
   1838  * <p> The maximum number of arguments is limited by the maximum dimension of a
   1839  * Java array as defined by
   1840  * <cite>The Java&trade; Virtual Machine Specification</cite>.
   1841  * If the argument index is does not correspond to an
   1842  * available argument, then a {@link MissingFormatArgumentException} is thrown.
   1843  *
   1844  * <p> If there are more arguments than format specifiers, the extra arguments
   1845  * are ignored.
   1846  *
   1847  * <p> Unless otherwise specified, passing a {@code null} argument to any
   1848  * method or constructor in this class will cause a {@link
   1849  * NullPointerException} to be thrown.
   1850  *
   1851  * @author  Iris Clark
   1852  * @since 1.5
   1853  */
   1854 public final class Formatter implements Closeable, Flushable {
   1855     private Appendable a;
   1856     private final Locale l;
   1857 
   1858     private IOException lastException;
   1859 
   1860     private final char zero;
   1861     private static double scaleUp;
   1862 
   1863     // 1 (sign) + 19 (max # sig digits) + 1 ('.') + 1 ('e') + 1 (sign)
   1864     // + 3 (max # exp digits) + 4 (error) = 30
   1865     private static final int MAX_FD_CHARS = 30;
   1866 
   1867     /**
   1868      * Returns a charset object for the given charset name.
   1869      * @throws NullPointerException          is csn is null
   1870      * @throws UnsupportedEncodingException  if the charset is not supported
   1871      */
   1872     private static Charset toCharset(String csn)
   1873         throws UnsupportedEncodingException
   1874     {
   1875         Objects.requireNonNull(csn, "charsetName");
   1876         try {
   1877             return Charset.forName(csn);
   1878         } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
   1879             // UnsupportedEncodingException should be thrown
   1880             throw new UnsupportedEncodingException(csn);
   1881         }
   1882     }
   1883 
   1884     private static final Appendable nonNullAppendable(Appendable a) {
   1885         if (a == null)
   1886             return new StringBuilder();
   1887 
   1888         return a;
   1889     }
   1890 
   1891     /* Private constructors */
   1892     private Formatter(Locale l, Appendable a) {
   1893         this.a = a;
   1894         this.l = l;
   1895         this.zero = getZero(l);
   1896     }
   1897 
   1898     private Formatter(Charset charset, Locale l, File file)
   1899         throws FileNotFoundException
   1900     {
   1901         this(l,
   1902              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)));
   1903     }
   1904 
   1905     /**
   1906      * Constructs a new formatter.
   1907      *
   1908      * <p> The destination of the formatted output is a {@link StringBuilder}
   1909      * which may be retrieved by invoking {@link #out out()} and whose
   1910      * current content may be converted into a string by invoking {@link
   1911      * #toString toString()}.  The locale used is the {@linkplain
   1912      * Locale#getDefault(Locale.Category) default locale} for
   1913      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   1914      * virtual machine.
   1915      */
   1916     public Formatter() {
   1917         this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
   1918     }
   1919 
   1920     /**
   1921      * Constructs a new formatter with the specified destination.
   1922      *
   1923      * <p> The locale used is the {@linkplain
   1924      * Locale#getDefault(Locale.Category) default locale} for
   1925      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   1926      * virtual machine.
   1927      *
   1928      * @param  a
   1929      *         Destination for the formatted output.  If {@code a} is
   1930      *         {@code null} then a {@link StringBuilder} will be created.
   1931      */
   1932     public Formatter(Appendable a) {
   1933         this(Locale.getDefault(Locale.Category.FORMAT), nonNullAppendable(a));
   1934     }
   1935 
   1936     /**
   1937      * Constructs a new formatter with the specified locale.
   1938      *
   1939      * <p> The destination of the formatted output is a {@link StringBuilder}
   1940      * which may be retrieved by invoking {@link #out out()} and whose current
   1941      * content may be converted into a string by invoking {@link #toString
   1942      * toString()}.
   1943      *
   1944      * @param  l
   1945      *         The {@linkplain java.util.Locale locale} to apply during
   1946      *         formatting.  If {@code l} is {@code null} then no localization
   1947      *         is applied.
   1948      */
   1949     public Formatter(Locale l) {
   1950         this(l, new StringBuilder());
   1951     }
   1952 
   1953     /**
   1954      * Constructs a new formatter with the specified destination and locale.
   1955      *
   1956      * @param  a
   1957      *         Destination for the formatted output.  If {@code a} is
   1958      *         {@code null} then a {@link StringBuilder} will be created.
   1959      *
   1960      * @param  l
   1961      *         The {@linkplain java.util.Locale locale} to apply during
   1962      *         formatting.  If {@code l} is {@code null} then no localization
   1963      *         is applied.
   1964      */
   1965     public Formatter(Appendable a, Locale l) {
   1966         this(l, nonNullAppendable(a));
   1967     }
   1968 
   1969     /**
   1970      * Constructs a new formatter with the specified file name.
   1971      *
   1972      * <p> The charset used is the {@linkplain
   1973      * java.nio.charset.Charset#defaultCharset() default charset} for this
   1974      * instance of the Java virtual machine.
   1975      *
   1976      * <p> The locale used is the {@linkplain
   1977      * Locale#getDefault(Locale.Category) default locale} for
   1978      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   1979      * virtual machine.
   1980      *
   1981      * @param  fileName
   1982      *         The name of the file to use as the destination of this
   1983      *         formatter.  If the file exists then it will be truncated to
   1984      *         zero size; otherwise, a new file will be created.  The output
   1985      *         will be written to the file and is buffered.
   1986      *
   1987      * @throws  SecurityException
   1988      *          If a security manager is present and {@link
   1989      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   1990      *          access to the file
   1991      *
   1992      * @throws  FileNotFoundException
   1993      *          If the given file name does not denote an existing, writable
   1994      *          regular file and a new regular file of that name cannot be
   1995      *          created, or if some other error occurs while opening or
   1996      *          creating the file
   1997      */
   1998     public Formatter(String fileName) throws FileNotFoundException {
   1999         this(Locale.getDefault(Locale.Category.FORMAT),
   2000              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))));
   2001     }
   2002 
   2003     /**
   2004      * Constructs a new formatter with the specified file name and charset.
   2005      *
   2006      * <p> The locale used is the {@linkplain
   2007      * Locale#getDefault(Locale.Category) default locale} for
   2008      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   2009      * virtual machine.
   2010      *
   2011      * @param  fileName
   2012      *         The name of the file to use as the destination of this
   2013      *         formatter.  If the file exists then it will be truncated to
   2014      *         zero size; otherwise, a new file will be created.  The output
   2015      *         will be written to the file and is buffered.
   2016      *
   2017      * @param  csn
   2018      *         The name of a supported {@linkplain java.nio.charset.Charset
   2019      *         charset}
   2020      *
   2021      * @throws  FileNotFoundException
   2022      *          If the given file name does not denote an existing, writable
   2023      *          regular file and a new regular file of that name cannot be
   2024      *          created, or if some other error occurs while opening or
   2025      *          creating the file
   2026      *
   2027      * @throws  SecurityException
   2028      *          If a security manager is present and {@link
   2029      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   2030      *          access to the file
   2031      *
   2032      * @throws  UnsupportedEncodingException
   2033      *          If the named charset is not supported
   2034      */
   2035     public Formatter(String fileName, String csn)
   2036         throws FileNotFoundException, UnsupportedEncodingException
   2037     {
   2038         this(fileName, csn, Locale.getDefault(Locale.Category.FORMAT));
   2039     }
   2040 
   2041     /**
   2042      * Constructs a new formatter with the specified file name, charset, and
   2043      * locale.
   2044      *
   2045      * @param  fileName
   2046      *         The name of the file to use as the destination of this
   2047      *         formatter.  If the file exists then it will be truncated to
   2048      *         zero size; otherwise, a new file will be created.  The output
   2049      *         will be written to the file and is buffered.
   2050      *
   2051      * @param  csn
   2052      *         The name of a supported {@linkplain java.nio.charset.Charset
   2053      *         charset}
   2054      *
   2055      * @param  l
   2056      *         The {@linkplain java.util.Locale locale} to apply during
   2057      *         formatting.  If {@code l} is {@code null} then no localization
   2058      *         is applied.
   2059      *
   2060      * @throws  FileNotFoundException
   2061      *          If the given file name does not denote an existing, writable
   2062      *          regular file and a new regular file of that name cannot be
   2063      *          created, or if some other error occurs while opening or
   2064      *          creating the file
   2065      *
   2066      * @throws  SecurityException
   2067      *          If a security manager is present and {@link
   2068      *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   2069      *          access to the file
   2070      *
   2071      * @throws  UnsupportedEncodingException
   2072      *          If the named charset is not supported
   2073      */
   2074     public Formatter(String fileName, String csn, Locale l)
   2075         throws FileNotFoundException, UnsupportedEncodingException
   2076     {
   2077         this(toCharset(csn), l, new File(fileName));
   2078     }
   2079 
   2080     /**
   2081      * Constructs a new formatter with the specified file.
   2082      *
   2083      * <p> The charset used is the {@linkplain
   2084      * java.nio.charset.Charset#defaultCharset() default charset} for this
   2085      * instance of the Java virtual machine.
   2086      *
   2087      * <p> The locale used is the {@linkplain
   2088      * Locale#getDefault(Locale.Category) default locale} for
   2089      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   2090      * virtual machine.
   2091      *
   2092      * @param  file
   2093      *         The file to use as the destination of this formatter.  If the
   2094      *         file exists then it will be truncated to zero size; otherwise,
   2095      *         a new file will be created.  The output will be written to the
   2096      *         file and is buffered.
   2097      *
   2098      * @throws  SecurityException
   2099      *          If a security manager is present and {@link
   2100      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
   2101      *          write access to the file
   2102      *
   2103      * @throws  FileNotFoundException
   2104      *          If the given file object does not denote an existing, writable
   2105      *          regular file and a new regular file of that name cannot be
   2106      *          created, or if some other error occurs while opening or
   2107      *          creating the file
   2108      */
   2109     public Formatter(File file) throws FileNotFoundException {
   2110         this(Locale.getDefault(Locale.Category.FORMAT),
   2111              new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))));
   2112     }
   2113 
   2114     /**
   2115      * Constructs a new formatter with the specified file and charset.
   2116      *
   2117      * <p> The locale used is the {@linkplain
   2118      * Locale#getDefault(Locale.Category) default locale} for
   2119      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   2120      * virtual machine.
   2121      *
   2122      * @param  file
   2123      *         The file to use as the destination of this formatter.  If the
   2124      *         file exists then it will be truncated to zero size; otherwise,
   2125      *         a new file will be created.  The output will be written to the
   2126      *         file and is buffered.
   2127      *
   2128      * @param  csn
   2129      *         The name of a supported {@linkplain java.nio.charset.Charset
   2130      *         charset}
   2131      *
   2132      * @throws  FileNotFoundException
   2133      *          If the given file object does not denote an existing, writable
   2134      *          regular file and a new regular file of that name cannot be
   2135      *          created, or if some other error occurs while opening or
   2136      *          creating the file
   2137      *
   2138      * @throws  SecurityException
   2139      *          If a security manager is present and {@link
   2140      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
   2141      *          write access to the file
   2142      *
   2143      * @throws  UnsupportedEncodingException
   2144      *          If the named charset is not supported
   2145      */
   2146     public Formatter(File file, String csn)
   2147         throws FileNotFoundException, UnsupportedEncodingException
   2148     {
   2149         this(file, csn, Locale.getDefault(Locale.Category.FORMAT));
   2150     }
   2151 
   2152     /**
   2153      * Constructs a new formatter with the specified file, charset, and
   2154      * locale.
   2155      *
   2156      * @param  file
   2157      *         The file to use as the destination of this formatter.  If the
   2158      *         file exists then it will be truncated to zero size; otherwise,
   2159      *         a new file will be created.  The output will be written to the
   2160      *         file and is buffered.
   2161      *
   2162      * @param  csn
   2163      *         The name of a supported {@linkplain java.nio.charset.Charset
   2164      *         charset}
   2165      *
   2166      * @param  l
   2167      *         The {@linkplain java.util.Locale locale} to apply during
   2168      *         formatting.  If {@code l} is {@code null} then no localization
   2169      *         is applied.
   2170      *
   2171      * @throws  FileNotFoundException
   2172      *          If the given file object does not denote an existing, writable
   2173      *          regular file and a new regular file of that name cannot be
   2174      *          created, or if some other error occurs while opening or
   2175      *          creating the file
   2176      *
   2177      * @throws  SecurityException
   2178      *          If a security manager is present and {@link
   2179      *          SecurityManager#checkWrite checkWrite(file.getPath())} denies
   2180      *          write access to the file
   2181      *
   2182      * @throws  UnsupportedEncodingException
   2183      *          If the named charset is not supported
   2184      */
   2185     public Formatter(File file, String csn, Locale l)
   2186         throws FileNotFoundException, UnsupportedEncodingException
   2187     {
   2188         this(toCharset(csn), l, file);
   2189     }
   2190 
   2191     /**
   2192      * Constructs a new formatter with the specified print stream.
   2193      *
   2194      * <p> The locale used is the {@linkplain
   2195      * Locale#getDefault(Locale.Category) default locale} for
   2196      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   2197      * virtual machine.
   2198      *
   2199      * <p> Characters are written to the given {@link java.io.PrintStream
   2200      * PrintStream} object and are therefore encoded using that object's
   2201      * charset.
   2202      *
   2203      * @param  ps
   2204      *         The stream to use as the destination of this formatter.
   2205      */
   2206     public Formatter(PrintStream ps) {
   2207         this(Locale.getDefault(Locale.Category.FORMAT),
   2208              (Appendable)Objects.requireNonNull(ps));
   2209     }
   2210 
   2211     /**
   2212      * Constructs a new formatter with the specified output stream.
   2213      *
   2214      * <p> The charset used is the {@linkplain
   2215      * java.nio.charset.Charset#defaultCharset() default charset} for this
   2216      * instance of the Java virtual machine.
   2217      *
   2218      * <p> The locale used is the {@linkplain
   2219      * Locale#getDefault(Locale.Category) default locale} for
   2220      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   2221      * virtual machine.
   2222      *
   2223      * @param  os
   2224      *         The output stream to use as the destination of this formatter.
   2225      *         The output will be buffered.
   2226      */
   2227     public Formatter(OutputStream os) {
   2228         this(Locale.getDefault(Locale.Category.FORMAT),
   2229              new BufferedWriter(new OutputStreamWriter(os)));
   2230     }
   2231 
   2232     /**
   2233      * Constructs a new formatter with the specified output stream and
   2234      * charset.
   2235      *
   2236      * <p> The locale used is the {@linkplain
   2237      * Locale#getDefault(Locale.Category) default locale} for
   2238      * {@linkplain Locale.Category#FORMAT formatting} for this instance of the Java
   2239      * virtual machine.
   2240      *
   2241      * @param  os
   2242      *         The output stream to use as the destination of this formatter.
   2243      *         The output will be buffered.
   2244      *
   2245      * @param  csn
   2246      *         The name of a supported {@linkplain java.nio.charset.Charset
   2247      *         charset}
   2248      *
   2249      * @throws  UnsupportedEncodingException
   2250      *          If the named charset is not supported
   2251      */
   2252     public Formatter(OutputStream os, String csn)
   2253         throws UnsupportedEncodingException
   2254     {
   2255         this(os, csn, Locale.getDefault(Locale.Category.FORMAT));
   2256     }
   2257 
   2258     /**
   2259      * Constructs a new formatter with the specified output stream, charset,
   2260      * and locale.
   2261      *
   2262      * @param  os
   2263      *         The output stream to use as the destination of this formatter.
   2264      *         The output will be buffered.
   2265      *
   2266      * @param  csn
   2267      *         The name of a supported {@linkplain java.nio.charset.Charset
   2268      *         charset}
   2269      *
   2270      * @param  l
   2271      *         The {@linkplain java.util.Locale locale} to apply during
   2272      *         formatting.  If {@code l} is {@code null} then no localization
   2273      *         is applied.
   2274      *
   2275      * @throws  UnsupportedEncodingException
   2276      *          If the named charset is not supported
   2277      */
   2278     public Formatter(OutputStream os, String csn, Locale l)
   2279         throws UnsupportedEncodingException
   2280     {
   2281         this(l, new BufferedWriter(new OutputStreamWriter(os, csn)));
   2282     }
   2283 
   2284     private static char getZero(Locale l) {
   2285         if ((l != null) && !l.equals(Locale.US)) {
   2286             DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
   2287             return dfs.getZeroDigit();
   2288         } else {
   2289             return '0';
   2290         }
   2291     }
   2292 
   2293     /**
   2294      * Returns the locale set by the construction of this formatter.
   2295      *
   2296      * <p> The {@link #format(java.util.Locale,String,Object...) format} method
   2297      * for this object which has a locale argument does not change this value.
   2298      *
   2299      * @return  {@code null} if no localization is applied, otherwise a
   2300      *          locale
   2301      *
   2302      * @throws  FormatterClosedException
   2303      *          If this formatter has been closed by invoking its {@link
   2304      *          #close()} method
   2305      */
   2306     public Locale locale() {
   2307         ensureOpen();
   2308         return l;
   2309     }
   2310 
   2311     /**
   2312      * Returns the destination for the output.
   2313      *
   2314      * @return  The destination for the output
   2315      *
   2316      * @throws  FormatterClosedException
   2317      *          If this formatter has been closed by invoking its {@link
   2318      *          #close()} method
   2319      */
   2320     public Appendable out() {
   2321         ensureOpen();
   2322         return a;
   2323     }
   2324 
   2325     /**
   2326      * Returns the result of invoking {@code toString()} on the destination
   2327      * for the output.  For example, the following code formats text into a
   2328      * {@link StringBuilder} then retrieves the resultant string:
   2329      *
   2330      * <blockquote><pre>
   2331      *   Formatter f = new Formatter();
   2332      *   f.format("Last reboot at %tc", lastRebootDate);
   2333      *   String s = f.toString();
   2334      *   // -&gt; s == "Last reboot at Sat Jan 01 00:00:00 PST 2000"
   2335      * </pre></blockquote>
   2336      *
   2337      * <p> An invocation of this method behaves in exactly the same way as the
   2338      * invocation
   2339      *
   2340      * <pre>
   2341      *     out().toString() </pre>
   2342      *
   2343      * <p> Depending on the specification of {@code toString} for the {@link
   2344      * Appendable}, the returned string may or may not contain the characters
   2345      * written to the destination.  For instance, buffers typically return
   2346      * their contents in {@code toString()}, but streams cannot since the
   2347      * data is discarded.
   2348      *
   2349      * @return  The result of invoking {@code toString()} on the destination
   2350      *          for the output
   2351      *
   2352      * @throws  FormatterClosedException
   2353      *          If this formatter has been closed by invoking its {@link
   2354      *          #close()} method
   2355      */
   2356     public String toString() {
   2357         ensureOpen();
   2358         return a.toString();
   2359     }
   2360 
   2361     /**
   2362      * Flushes this formatter.  If the destination implements the {@link
   2363      * java.io.Flushable} interface, its {@code flush} method will be invoked.
   2364      *
   2365      * <p> Flushing a formatter writes any buffered output in the destination
   2366      * to the underlying stream.
   2367      *
   2368      * @throws  FormatterClosedException
   2369      *          If this formatter has been closed by invoking its {@link
   2370      *          #close()} method
   2371      */
   2372     public void flush() {
   2373         ensureOpen();
   2374         if (a instanceof Flushable) {
   2375             try {
   2376                 ((Flushable)a).flush();
   2377             } catch (IOException ioe) {
   2378                 lastException = ioe;
   2379             }
   2380         }
   2381     }
   2382 
   2383     /**
   2384      * Closes this formatter.  If the destination implements the {@link
   2385      * java.io.Closeable} interface, its {@code close} method will be invoked.
   2386      *
   2387      * <p> Closing a formatter allows it to release resources it may be holding
   2388      * (such as open files).  If the formatter is already closed, then invoking
   2389      * this method has no effect.
   2390      *
   2391      * <p> Attempting to invoke any methods except {@link #ioException()} in
   2392      * this formatter after it has been closed will result in a {@link
   2393      * FormatterClosedException}.
   2394      */
   2395     public void close() {
   2396         if (a == null)
   2397             return;
   2398         try {
   2399             if (a instanceof Closeable)
   2400                 ((Closeable)a).close();
   2401         } catch (IOException ioe) {
   2402             lastException = ioe;
   2403         } finally {
   2404             a = null;
   2405         }
   2406     }
   2407 
   2408     private void ensureOpen() {
   2409         if (a == null)
   2410             throw new FormatterClosedException();
   2411     }
   2412 
   2413     /**
   2414      * Returns the {@code IOException} last thrown by this formatter's {@link
   2415      * Appendable}.
   2416      *
   2417      * <p> If the destination's {@code append()} method never throws
   2418      * {@code IOException}, then this method will always return {@code null}.
   2419      *
   2420      * @return  The last exception thrown by the Appendable or {@code null} if
   2421      *          no such exception exists.
   2422      */
   2423     public IOException ioException() {
   2424         return lastException;
   2425     }
   2426 
   2427     /**
   2428      * Writes a formatted string to this object's destination using the
   2429      * specified format string and arguments.  The locale used is the one
   2430      * defined during the construction of this formatter.
   2431      *
   2432      * @param  format
   2433      *         A format string as described in <a href="#syntax">Format string
   2434      *         syntax</a>.
   2435      *
   2436      * @param  args
   2437      *         Arguments referenced by the format specifiers in the format
   2438      *         string.  If there are more arguments than format specifiers, the
   2439      *         extra arguments are ignored.  The maximum number of arguments is
   2440      *         limited by the maximum dimension of a Java array as defined by
   2441      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   2442      *
   2443      * @throws  IllegalFormatException
   2444      *          If a format string contains an illegal syntax, a format
   2445      *          specifier that is incompatible with the given arguments,
   2446      *          insufficient arguments given the format string, or other
   2447      *          illegal conditions.  For specification of all possible
   2448      *          formatting errors, see the <a href="#detail">Details</a>
   2449      *          section of the formatter class specification.
   2450      *
   2451      * @throws  FormatterClosedException
   2452      *          If this formatter has been closed by invoking its {@link
   2453      *          #close()} method
   2454      *
   2455      * @return  This formatter
   2456      */
   2457     public Formatter format(String format, Object ... args) {
   2458         return format(l, format, args);
   2459     }
   2460 
   2461     /**
   2462      * Writes a formatted string to this object's destination using the
   2463      * specified locale, format string, and arguments.
   2464      *
   2465      * @param  l
   2466      *         The {@linkplain java.util.Locale locale} to apply during
   2467      *         formatting.  If {@code l} is {@code null} then no localization
   2468      *         is applied.  This does not change this object's locale that was
   2469      *         set during construction.
   2470      *
   2471      * @param  format
   2472      *         A format string as described in <a href="#syntax">Format string
   2473      *         syntax</a>
   2474      *
   2475      * @param  args
   2476      *         Arguments referenced by the format specifiers in the format
   2477      *         string.  If there are more arguments than format specifiers, the
   2478      *         extra arguments are ignored.  The maximum number of arguments is
   2479      *         limited by the maximum dimension of a Java array as defined by
   2480      *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   2481      *
   2482      * @throws  IllegalFormatException
   2483      *          If a format string contains an illegal syntax, a format
   2484      *          specifier that is incompatible with the given arguments,
   2485      *          insufficient arguments given the format string, or other
   2486      *          illegal conditions.  For specification of all possible
   2487      *          formatting errors, see the <a href="#detail">Details</a>
   2488      *          section of the formatter class specification.
   2489      *
   2490      * @throws  FormatterClosedException
   2491      *          If this formatter has been closed by invoking its {@link
   2492      *          #close()} method
   2493      *
   2494      * @return  This formatter
   2495      */
   2496     public Formatter format(Locale l, String format, Object ... args) {
   2497         ensureOpen();
   2498 
   2499         // index of last argument referenced
   2500         int last = -1;
   2501         // last ordinary index
   2502         int lasto = -1;
   2503 
   2504         FormatString[] fsa = parse(format);
   2505         for (int i = 0; i < fsa.length; i++) {
   2506             FormatString fs = fsa[i];
   2507             int index = fs.index();
   2508             try {
   2509                 switch (index) {
   2510                 case -2:  // fixed string, "%n", or "%%"
   2511                     fs.print(null, l);
   2512                     break;
   2513                 case -1:  // relative index
   2514                     if (last < 0 || (args != null && last > args.length - 1))
   2515                         throw new MissingFormatArgumentException(fs.toString());
   2516                     fs.print((args == null ? null : args[last]), l);
   2517                     break;
   2518                 case 0:  // ordinary index
   2519                     lasto++;
   2520                     last = lasto;
   2521                     if (args != null && lasto > args.length - 1)
   2522                         throw new MissingFormatArgumentException(fs.toString());
   2523                     fs.print((args == null ? null : args[lasto]), l);
   2524                     break;
   2525                 default:  // explicit index
   2526                     last = index - 1;
   2527                     if (args != null && last > args.length - 1)
   2528                         throw new MissingFormatArgumentException(fs.toString());
   2529                     fs.print((args == null ? null : args[last]), l);
   2530                     break;
   2531                 }
   2532             } catch (IOException x) {
   2533                 lastException = x;
   2534             }
   2535         }
   2536         return this;
   2537     }
   2538 
   2539     // BEGIN Android-changed: changed parse() to manual parsing instead of regex.
   2540     /**
   2541      * Finds format specifiers in the format string.
   2542      */
   2543     private FormatString[] parse(String s) {
   2544         ArrayList<FormatString> al = new ArrayList<>();
   2545         for (int i = 0, len = s.length(); i < len; ) {
   2546             int nextPercent = s.indexOf('%', i);
   2547             if (s.charAt(i) != '%') {
   2548                 // This is plain-text part, find the maximal plain-text
   2549                 // sequence and store it.
   2550                 int plainTextStart = i;
   2551                 int plainTextEnd = (nextPercent == -1) ? len: nextPercent;
   2552                 al.add(new FixedString(s.substring(plainTextStart,
   2553                                                    plainTextEnd)));
   2554                 i = plainTextEnd;
   2555             } else {
   2556                 // We have a format specifier
   2557                 FormatSpecifierParser fsp = new FormatSpecifierParser(s, i + 1);
   2558                 al.add(fsp.getFormatSpecifier());
   2559                 i = fsp.getEndIdx();
   2560             }
   2561         }
   2562         return al.toArray(new FormatString[al.size()]);
   2563     }
   2564 
   2565     /**
   2566      * Parses the format specifier.
   2567      * %[argument_index$][flags][width][.precision][t]conversion
   2568      */
   2569     private class FormatSpecifierParser {
   2570         private final String format;
   2571         private int cursor;
   2572         private FormatSpecifier fs;
   2573 
   2574         private String index;
   2575         private String flags;
   2576         private String width;
   2577         private String precision;
   2578         private String tT;
   2579         private String conv;
   2580 
   2581         private static final String FLAGS = ",-(+# 0<";
   2582 
   2583         public FormatSpecifierParser(String format, int startIdx) {
   2584             this.format = format;
   2585             cursor = startIdx;
   2586             // Index
   2587             if (nextIsInt()) {
   2588                 String nint = nextInt();
   2589                 if (peek() == '$') {
   2590                     index = nint;
   2591                     advance();
   2592                 } else if (nint.charAt(0) == '0') {
   2593                     // This is a flag, skip to parsing flags.
   2594                     back(nint.length());
   2595                 } else {
   2596                     // This is the width, skip to parsing precision.
   2597                     width = nint;
   2598                 }
   2599             }
   2600             // Flags
   2601             flags = "";
   2602             while (width == null && FLAGS.indexOf(peek()) >= 0) {
   2603                 flags += advance();
   2604             }
   2605             // Width
   2606             if (width == null && nextIsInt()) {
   2607                 width = nextInt();
   2608             }
   2609             // Precision
   2610             if (peek() == '.') {
   2611                 advance();
   2612                 if (!nextIsInt()) {
   2613                     throw new IllegalFormatPrecisionException(peek());
   2614                 }
   2615                 precision = nextInt();
   2616             }
   2617             // tT
   2618             if (peek() == 't' || peek() == 'T') {
   2619                 tT = String.valueOf(advance());
   2620             }
   2621             // Conversion
   2622             conv = String.valueOf(advance());
   2623 
   2624             fs = new FormatSpecifier(index, flags, width, precision, tT, conv);
   2625         }
   2626 
   2627         private String nextInt() {
   2628             int strBegin = cursor;
   2629             while (nextIsInt()) {
   2630                 advance();
   2631             }
   2632             return format.substring(strBegin, cursor);
   2633         }
   2634 
   2635         private boolean nextIsInt() {
   2636             return !isEnd() && Character.isDigit(peek());
   2637         }
   2638 
   2639         private char peek() {
   2640             if (isEnd()) {
   2641                 throw new UnknownFormatConversionException("End of String");
   2642             }
   2643             return format.charAt(cursor);
   2644         }
   2645 
   2646         private char advance() {
   2647             if (isEnd()) {
   2648                 throw new UnknownFormatConversionException("End of String");
   2649             }
   2650             return format.charAt(cursor++);
   2651         }
   2652 
   2653         private void back(int len) {
   2654             cursor -= len;
   2655         }
   2656 
   2657         private boolean isEnd() {
   2658             return cursor == format.length();
   2659         }
   2660 
   2661         public FormatSpecifier getFormatSpecifier() {
   2662             return fs;
   2663         }
   2664 
   2665         public int getEndIdx() {
   2666             return cursor;
   2667         }
   2668     }
   2669     // END Android-changed: changed parse() to manual parsing instead of regex.
   2670 
   2671     private interface FormatString {
   2672         int index();
   2673         void print(Object arg, Locale l) throws IOException;
   2674         String toString();
   2675     }
   2676 
   2677     private class FixedString implements FormatString {
   2678         private String s;
   2679         FixedString(String s) { this.s = s; }
   2680         public int index() { return -2; }
   2681         public void print(Object arg, Locale l)
   2682             throws IOException { a.append(s); }
   2683         public String toString() { return s; }
   2684     }
   2685 
   2686     /**
   2687      * Enum for {@code BigDecimal} formatting.
   2688      */
   2689     public enum BigDecimalLayoutForm {
   2690         /**
   2691          * Format the {@code BigDecimal} in computerized scientific notation.
   2692          */
   2693         SCIENTIFIC,
   2694 
   2695         /**
   2696          * Format the {@code BigDecimal} as a decimal number.
   2697          */
   2698         DECIMAL_FLOAT
   2699     };
   2700 
   2701     private class FormatSpecifier implements FormatString {
   2702         private int index = -1;
   2703         private Flags f = Flags.NONE;
   2704         private int width;
   2705         private int precision;
   2706         private boolean dt = false;
   2707         private char c;
   2708 
   2709         private int index(String s) {
   2710             if (s != null) {
   2711                 try {
   2712                     // Android-changed: FormatSpecifierParser passes in correct String.
   2713                     // index = Integer.parseInt(s.substring(0, s.length() - 1));
   2714                     index = Integer.parseInt(s);
   2715                 } catch (NumberFormatException x) {
   2716                     assert(false);
   2717                 }
   2718             } else {
   2719                 index = 0;
   2720             }
   2721             return index;
   2722         }
   2723 
   2724         public int index() {
   2725             return index;
   2726         }
   2727 
   2728         private Flags flags(String s) {
   2729             f = Flags.parse(s);
   2730             if (f.contains(Flags.PREVIOUS))
   2731                 index = -1;
   2732             return f;
   2733         }
   2734 
   2735         Flags flags() {
   2736             return f;
   2737         }
   2738 
   2739         private int width(String s) {
   2740             width = -1;
   2741             if (s != null) {
   2742                 try {
   2743                     width  = Integer.parseInt(s);
   2744                     if (width < 0)
   2745                         throw new IllegalFormatWidthException(width);
   2746                 } catch (NumberFormatException x) {
   2747                     assert(false);
   2748                 }
   2749             }
   2750             return width;
   2751         }
   2752 
   2753         int width() {
   2754             return width;
   2755         }
   2756 
   2757         private int precision(String s) {
   2758             precision = -1;
   2759             if (s != null) {
   2760                 try {
   2761                     // Android-changed: FormatSpecifierParser passes in correct String.
   2762                     // precision = Integer.parseInt(s.substring(1));
   2763                     precision = Integer.parseInt(s);
   2764                     if (precision < 0)
   2765                         throw new IllegalFormatPrecisionException(precision);
   2766                 } catch (NumberFormatException x) {
   2767                     assert(false);
   2768                 }
   2769             }
   2770             return precision;
   2771         }
   2772 
   2773         int precision() {
   2774             return precision;
   2775         }
   2776 
   2777         private char conversion(String s) {
   2778             c = s.charAt(0);
   2779             if (!dt) {
   2780                 if (!Conversion.isValid(c))
   2781                     throw new UnknownFormatConversionException(String.valueOf(c));
   2782                 if (Character.isUpperCase(c))
   2783                     f.add(Flags.UPPERCASE);
   2784                 c = Character.toLowerCase(c);
   2785                 if (Conversion.isText(c))
   2786                     index = -2;
   2787             }
   2788             return c;
   2789         }
   2790 
   2791         private char conversion() {
   2792             return c;
   2793         }
   2794 
   2795         // BEGIN Android-changed: FormatSpecifierParser passes in the values instead of a Matcher.
   2796         FormatSpecifier(String indexStr, String flagsStr, String widthStr,
   2797                         String precisionStr, String tTStr, String convStr) {
   2798             int idx = 1;
   2799 
   2800             index(indexStr);
   2801             flags(flagsStr);
   2802             width(widthStr);
   2803             precision(precisionStr);
   2804 
   2805             if (tTStr != null) {
   2806                 dt = true;
   2807                 if (tTStr.equals("T"))
   2808                     f.add(Flags.UPPERCASE);
   2809             }
   2810 
   2811             conversion(convStr);
   2812         // END Android-changed: FormatSpecifierParser passes in the values instead of a Matcher.
   2813             if (dt)
   2814                 checkDateTime();
   2815             else if (Conversion.isGeneral(c))
   2816                 checkGeneral();
   2817             else if (Conversion.isCharacter(c))
   2818                 checkCharacter();
   2819             else if (Conversion.isInteger(c))
   2820                 checkInteger();
   2821             else if (Conversion.isFloat(c))
   2822                 checkFloat();
   2823             else if (Conversion.isText(c))
   2824                 checkText();
   2825             else
   2826                 throw new UnknownFormatConversionException(String.valueOf(c));
   2827         }
   2828 
   2829         public void print(Object arg, Locale l) throws IOException {
   2830             if (dt) {
   2831                 printDateTime(arg, l);
   2832                 return;
   2833             }
   2834             switch(c) {
   2835             case Conversion.DECIMAL_INTEGER:
   2836             case Conversion.OCTAL_INTEGER:
   2837             case Conversion.HEXADECIMAL_INTEGER:
   2838                 printInteger(arg, l);
   2839                 break;
   2840             case Conversion.SCIENTIFIC:
   2841             case Conversion.GENERAL:
   2842             case Conversion.DECIMAL_FLOAT:
   2843             case Conversion.HEXADECIMAL_FLOAT:
   2844                 printFloat(arg, l);
   2845                 break;
   2846             case Conversion.CHARACTER:
   2847             case Conversion.CHARACTER_UPPER:
   2848                 printCharacter(arg);
   2849                 break;
   2850             case Conversion.BOOLEAN:
   2851                 printBoolean(arg);
   2852                 break;
   2853             case Conversion.STRING:
   2854                 printString(arg, l);
   2855                 break;
   2856             case Conversion.HASHCODE:
   2857                 printHashCode(arg);
   2858                 break;
   2859             case Conversion.LINE_SEPARATOR:
   2860                 a.append(System.lineSeparator());
   2861                 break;
   2862             case Conversion.PERCENT_SIGN:
   2863                 a.append('%');
   2864                 break;
   2865             default:
   2866                 assert false;
   2867             }
   2868         }
   2869 
   2870         private void printInteger(Object arg, Locale l) throws IOException {
   2871             if (arg == null)
   2872                 print("null");
   2873             else if (arg instanceof Byte)
   2874                 print(((Byte)arg).byteValue(), l);
   2875             else if (arg instanceof Short)
   2876                 print(((Short)arg).shortValue(), l);
   2877             else if (arg instanceof Integer)
   2878                 print(((Integer)arg).intValue(), l);
   2879             else if (arg instanceof Long)
   2880                 print(((Long)arg).longValue(), l);
   2881             else if (arg instanceof BigInteger)
   2882                 print(((BigInteger)arg), l);
   2883             else
   2884                 failConversion(c, arg);
   2885         }
   2886 
   2887         private void printFloat(Object arg, Locale l) throws IOException {
   2888             if (arg == null)
   2889                 print("null");
   2890             else if (arg instanceof Float)
   2891                 print(((Float)arg).floatValue(), l);
   2892             else if (arg instanceof Double)
   2893                 print(((Double)arg).doubleValue(), l);
   2894             else if (arg instanceof BigDecimal)
   2895                 print(((BigDecimal)arg), l);
   2896             else
   2897                 failConversion(c, arg);
   2898         }
   2899 
   2900         private void printDateTime(Object arg, Locale l) throws IOException {
   2901             if (arg == null) {
   2902                 print("null");
   2903                 return;
   2904             }
   2905             Calendar cal = null;
   2906 
   2907             // Instead of Calendar.setLenient(true), perhaps we should
   2908             // wrap the IllegalArgumentException that might be thrown?
   2909             if (arg instanceof Long) {
   2910                 // Note that the following method uses an instance of the
   2911                 // default time zone (TimeZone.getDefaultRef().
   2912                 cal = Calendar.getInstance(l == null ? Locale.US : l);
   2913                 cal.setTimeInMillis((Long)arg);
   2914             } else if (arg instanceof Date) {
   2915                 // Note that the following method uses an instance of the
   2916                 // default time zone (TimeZone.getDefaultRef().
   2917                 cal = Calendar.getInstance(l == null ? Locale.US : l);
   2918                 cal.setTime((Date)arg);
   2919             } else if (arg instanceof Calendar) {
   2920                 cal = (Calendar) ((Calendar) arg).clone();
   2921                 cal.setLenient(true);
   2922             } else if (arg instanceof TemporalAccessor) {
   2923                 print((TemporalAccessor) arg, c, l);
   2924                 return;
   2925             } else {
   2926                 failConversion(c, arg);
   2927             }
   2928             // Use the provided locale so that invocations of
   2929             // localizedMagnitude() use optimizations for null.
   2930             print(cal, c, l);
   2931         }
   2932 
   2933         private void printCharacter(Object arg) throws IOException {
   2934             if (arg == null) {
   2935                 print("null");
   2936                 return;
   2937             }
   2938             String s = null;
   2939             if (arg instanceof Character) {
   2940                 s = ((Character)arg).toString();
   2941             } else if (arg instanceof Byte) {
   2942                 byte i = ((Byte)arg).byteValue();
   2943                 if (Character.isValidCodePoint(i))
   2944                     s = new String(Character.toChars(i));
   2945                 else
   2946                     throw new IllegalFormatCodePointException(i);
   2947             } else if (arg instanceof Short) {
   2948                 short i = ((Short)arg).shortValue();
   2949                 if (Character.isValidCodePoint(i))
   2950                     s = new String(Character.toChars(i));
   2951                 else
   2952                     throw new IllegalFormatCodePointException(i);
   2953             } else if (arg instanceof Integer) {
   2954                 int i = ((Integer)arg).intValue();
   2955                 if (Character.isValidCodePoint(i))
   2956                     s = new String(Character.toChars(i));
   2957                 else
   2958                     throw new IllegalFormatCodePointException(i);
   2959             } else {
   2960                 failConversion(c, arg);
   2961             }
   2962             print(s);
   2963         }
   2964 
   2965         private void printString(Object arg, Locale l) throws IOException {
   2966             if (arg instanceof Formattable) {
   2967                 Formatter fmt = Formatter.this;
   2968                 if (fmt.locale() != l)
   2969                     fmt = new Formatter(fmt.out(), l);
   2970                 ((Formattable)arg).formatTo(fmt, f.valueOf(), width, precision);
   2971             } else {
   2972                 if (f.contains(Flags.ALTERNATE))
   2973                     failMismatch(Flags.ALTERNATE, 's');
   2974                 if (arg == null)
   2975                     print("null");
   2976                 else
   2977                     print(arg.toString());
   2978             }
   2979         }
   2980 
   2981         private void printBoolean(Object arg) throws IOException {
   2982             String s;
   2983             if (arg != null)
   2984                 s = ((arg instanceof Boolean)
   2985                      ? ((Boolean)arg).toString()
   2986                      : Boolean.toString(true));
   2987             else
   2988                 s = Boolean.toString(false);
   2989             print(s);
   2990         }
   2991 
   2992         private void printHashCode(Object arg) throws IOException {
   2993             String s = (arg == null
   2994                         ? "null"
   2995                         : Integer.toHexString(arg.hashCode()));
   2996             print(s);
   2997         }
   2998 
   2999         private void print(String s) throws IOException {
   3000             if (precision != -1 && precision < s.length())
   3001                 s = s.substring(0, precision);
   3002             if (f.contains(Flags.UPPERCASE)) {
   3003                 // Android-changed: Use provided locale instead of default, if it is non-null.
   3004                 // s = s.toUpperCase();
   3005                 s = s.toUpperCase(l != null ? l : Locale.getDefault());
   3006             }
   3007             a.append(justify(s));
   3008         }
   3009 
   3010         private String justify(String s) {
   3011             if (width == -1)
   3012                 return s;
   3013             StringBuilder sb = new StringBuilder();
   3014             boolean pad = f.contains(Flags.LEFT_JUSTIFY);
   3015             int sp = width - s.length();
   3016             if (!pad)
   3017                 for (int i = 0; i < sp; i++) sb.append(' ');
   3018             sb.append(s);
   3019             if (pad)
   3020                 for (int i = 0; i < sp; i++) sb.append(' ');
   3021             return sb.toString();
   3022         }
   3023 
   3024         public String toString() {
   3025             StringBuilder sb = new StringBuilder("%");
   3026             // Flags.UPPERCASE is set internally for legal conversions.
   3027             Flags dupf = f.dup().remove(Flags.UPPERCASE);
   3028             sb.append(dupf.toString());
   3029             if (index > 0)
   3030                 sb.append(index).append('$');
   3031             if (width != -1)
   3032                 sb.append(width);
   3033             if (precision != -1)
   3034                 sb.append('.').append(precision);
   3035             if (dt)
   3036                 sb.append(f.contains(Flags.UPPERCASE) ? 'T' : 't');
   3037             sb.append(f.contains(Flags.UPPERCASE)
   3038                       ? Character.toUpperCase(c) : c);
   3039             return sb.toString();
   3040         }
   3041 
   3042         private void checkGeneral() {
   3043             if ((c == Conversion.BOOLEAN || c == Conversion.HASHCODE)
   3044                 && f.contains(Flags.ALTERNATE))
   3045                 failMismatch(Flags.ALTERNATE, c);
   3046             // '-' requires a width
   3047             if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
   3048                 throw new MissingFormatWidthException(toString());
   3049             checkBadFlags(Flags.PLUS, Flags.LEADING_SPACE, Flags.ZERO_PAD,
   3050                           Flags.GROUP, Flags.PARENTHESES);
   3051         }
   3052 
   3053         private void checkDateTime() {
   3054             if (precision != -1)
   3055                 throw new IllegalFormatPrecisionException(precision);
   3056             if (!DateTime.isValid(c))
   3057                 throw new UnknownFormatConversionException("t" + c);
   3058             checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE,
   3059                           Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES);
   3060             // '-' requires a width
   3061             if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
   3062                 throw new MissingFormatWidthException(toString());
   3063         }
   3064 
   3065         private void checkCharacter() {
   3066             if (precision != -1)
   3067                 throw new IllegalFormatPrecisionException(precision);
   3068             checkBadFlags(Flags.ALTERNATE, Flags.PLUS, Flags.LEADING_SPACE,
   3069                           Flags.ZERO_PAD, Flags.GROUP, Flags.PARENTHESES);
   3070             // '-' requires a width
   3071             if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
   3072                 throw new MissingFormatWidthException(toString());
   3073         }
   3074 
   3075         private void checkInteger() {
   3076             checkNumeric();
   3077             if (precision != -1)
   3078                 throw new IllegalFormatPrecisionException(precision);
   3079 
   3080             if (c == Conversion.DECIMAL_INTEGER)
   3081                 checkBadFlags(Flags.ALTERNATE);
   3082             else if (c == Conversion.OCTAL_INTEGER)
   3083                 checkBadFlags(Flags.GROUP);
   3084             else
   3085                 checkBadFlags(Flags.GROUP);
   3086         }
   3087 
   3088         private void checkBadFlags(Flags ... badFlags) {
   3089             for (int i = 0; i < badFlags.length; i++)
   3090                 if (f.contains(badFlags[i]))
   3091                     failMismatch(badFlags[i], c);
   3092         }
   3093 
   3094         private void checkFloat() {
   3095             checkNumeric();
   3096             if (c == Conversion.DECIMAL_FLOAT) {
   3097             } else if (c == Conversion.HEXADECIMAL_FLOAT) {
   3098                 checkBadFlags(Flags.PARENTHESES, Flags.GROUP);
   3099             } else if (c == Conversion.SCIENTIFIC) {
   3100                 checkBadFlags(Flags.GROUP);
   3101             } else if (c == Conversion.GENERAL) {
   3102                 checkBadFlags(Flags.ALTERNATE);
   3103             }
   3104         }
   3105 
   3106         private void checkNumeric() {
   3107             if (width != -1 && width < 0)
   3108                 throw new IllegalFormatWidthException(width);
   3109 
   3110             if (precision != -1 && precision < 0)
   3111                 throw new IllegalFormatPrecisionException(precision);
   3112 
   3113             // '-' and '0' require a width
   3114             if (width == -1
   3115                 && (f.contains(Flags.LEFT_JUSTIFY) || f.contains(Flags.ZERO_PAD)))
   3116                 throw new MissingFormatWidthException(toString());
   3117 
   3118             // bad combination
   3119             if ((f.contains(Flags.PLUS) && f.contains(Flags.LEADING_SPACE))
   3120                 || (f.contains(Flags.LEFT_JUSTIFY) && f.contains(Flags.ZERO_PAD)))
   3121                 throw new IllegalFormatFlagsException(f.toString());
   3122         }
   3123 
   3124         private void checkText() {
   3125             if (precision != -1)
   3126                 throw new IllegalFormatPrecisionException(precision);
   3127             switch (c) {
   3128             case Conversion.PERCENT_SIGN:
   3129                 if (f.valueOf() != Flags.LEFT_JUSTIFY.valueOf()
   3130                     && f.valueOf() != Flags.NONE.valueOf())
   3131                     throw new IllegalFormatFlagsException(f.toString());
   3132                 // '-' requires a width
   3133                 if (width == -1 && f.contains(Flags.LEFT_JUSTIFY))
   3134                     throw new MissingFormatWidthException(toString());
   3135                 break;
   3136             case Conversion.LINE_SEPARATOR:
   3137                 if (width != -1)
   3138                     throw new IllegalFormatWidthException(width);
   3139                 if (f.valueOf() != Flags.NONE.valueOf())
   3140                     throw new IllegalFormatFlagsException(f.toString());
   3141                 break;
   3142             default:
   3143                 assert false;
   3144             }
   3145         }
   3146 
   3147         private void print(byte value, Locale l) throws IOException {
   3148             long v = value;
   3149             if (value < 0
   3150                 && (c == Conversion.OCTAL_INTEGER
   3151                     || c == Conversion.HEXADECIMAL_INTEGER)) {
   3152                 v += (1L << 8);
   3153                 assert v >= 0 : v;
   3154             }
   3155             print(v, l);
   3156         }
   3157 
   3158         private void print(short value, Locale l) throws IOException {
   3159             long v = value;
   3160             if (value < 0
   3161                 && (c == Conversion.OCTAL_INTEGER
   3162                     || c == Conversion.HEXADECIMAL_INTEGER)) {
   3163                 v += (1L << 16);
   3164                 assert v >= 0 : v;
   3165             }
   3166             print(v, l);
   3167         }
   3168 
   3169         private void print(int value, Locale l) throws IOException {
   3170             long v = value;
   3171             if (value < 0
   3172                 && (c == Conversion.OCTAL_INTEGER
   3173                     || c == Conversion.HEXADECIMAL_INTEGER)) {
   3174                 v += (1L << 32);
   3175                 assert v >= 0 : v;
   3176             }
   3177             print(v, l);
   3178         }
   3179 
   3180         private void print(long value, Locale l) throws IOException {
   3181 
   3182             StringBuilder sb = new StringBuilder();
   3183 
   3184             if (c == Conversion.DECIMAL_INTEGER) {
   3185                 boolean neg = value < 0;
   3186                 char[] va;
   3187                 if (value < 0)
   3188                     va = Long.toString(value, 10).substring(1).toCharArray();
   3189                 else
   3190                     va = Long.toString(value, 10).toCharArray();
   3191 
   3192                 // leading sign indicator
   3193                 leadingSign(sb, neg);
   3194 
   3195                 // the value
   3196                 localizedMagnitude(sb, va, f, adjustWidth(width, f, neg), l);
   3197 
   3198                 // trailing sign indicator
   3199                 trailingSign(sb, neg);
   3200             } else if (c == Conversion.OCTAL_INTEGER) {
   3201                 checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE,
   3202                               Flags.PLUS);
   3203                 String s = Long.toOctalString(value);
   3204                 int len = (f.contains(Flags.ALTERNATE)
   3205                            ? s.length() + 1
   3206                            : s.length());
   3207 
   3208                 // apply ALTERNATE (radix indicator for octal) before ZERO_PAD
   3209                 if (f.contains(Flags.ALTERNATE))
   3210                     sb.append('0');
   3211                 if (f.contains(Flags.ZERO_PAD))
   3212                     for (int i = 0; i < width - len; i++) sb.append('0');
   3213                 sb.append(s);
   3214             } else if (c == Conversion.HEXADECIMAL_INTEGER) {
   3215                 checkBadFlags(Flags.PARENTHESES, Flags.LEADING_SPACE,
   3216                               Flags.PLUS);
   3217                 String s = Long.toHexString(value);
   3218                 int len = (f.contains(Flags.ALTERNATE)
   3219                            ? s.length() + 2
   3220                            : s.length());
   3221 
   3222                 // apply ALTERNATE (radix indicator for hex) before ZERO_PAD
   3223                 if (f.contains(Flags.ALTERNATE))
   3224                     sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x");
   3225                 if (f.contains(Flags.ZERO_PAD))
   3226                     for (int i = 0; i < width - len; i++) sb.append('0');
   3227                 if (f.contains(Flags.UPPERCASE))
   3228                     s = s.toUpperCase();
   3229                 sb.append(s);
   3230             }
   3231 
   3232             // justify based on width
   3233             a.append(justify(sb.toString()));
   3234         }
   3235 
   3236         // neg := val < 0
   3237         private StringBuilder leadingSign(StringBuilder sb, boolean neg) {
   3238             if (!neg) {
   3239                 if (f.contains(Flags.PLUS)) {
   3240                     sb.append('+');
   3241                 } else if (f.contains(Flags.LEADING_SPACE)) {
   3242                     sb.append(' ');
   3243                 }
   3244             } else {
   3245                 if (f.contains(Flags.PARENTHESES))
   3246                     sb.append('(');
   3247                 else
   3248                     sb.append('-');
   3249             }
   3250             return sb;
   3251         }
   3252 
   3253         // neg := val < 0
   3254         private StringBuilder trailingSign(StringBuilder sb, boolean neg) {
   3255             if (neg && f.contains(Flags.PARENTHESES))
   3256                 sb.append(')');
   3257             return sb;
   3258         }
   3259 
   3260         private void print(BigInteger value, Locale l) throws IOException {
   3261             StringBuilder sb = new StringBuilder();
   3262             boolean neg = value.signum() == -1;
   3263             BigInteger v = value.abs();
   3264 
   3265             // leading sign indicator
   3266             leadingSign(sb, neg);
   3267 
   3268             // the value
   3269             if (c == Conversion.DECIMAL_INTEGER) {
   3270                 char[] va = v.toString().toCharArray();
   3271                 localizedMagnitude(sb, va, f, adjustWidth(width, f, neg), l);
   3272             } else if (c == Conversion.OCTAL_INTEGER) {
   3273                 String s = v.toString(8);
   3274 
   3275                 int len = s.length() + sb.length();
   3276                 if (neg && f.contains(Flags.PARENTHESES))
   3277                     len++;
   3278 
   3279                 // apply ALTERNATE (radix indicator for octal) before ZERO_PAD
   3280                 if (f.contains(Flags.ALTERNATE)) {
   3281                     len++;
   3282                     sb.append('0');
   3283                 }
   3284                 if (f.contains(Flags.ZERO_PAD)) {
   3285                     for (int i = 0; i < width - len; i++)
   3286                         sb.append('0');
   3287                 }
   3288                 sb.append(s);
   3289             } else if (c == Conversion.HEXADECIMAL_INTEGER) {
   3290                 String s = v.toString(16);
   3291 
   3292                 int len = s.length() + sb.length();
   3293                 if (neg && f.contains(Flags.PARENTHESES))
   3294                     len++;
   3295 
   3296                 // apply ALTERNATE (radix indicator for hex) before ZERO_PAD
   3297                 if (f.contains(Flags.ALTERNATE)) {
   3298                     len += 2;
   3299                     sb.append(f.contains(Flags.UPPERCASE) ? "0X" : "0x");
   3300                 }
   3301                 if (f.contains(Flags.ZERO_PAD))
   3302                     for (int i = 0; i < width - len; i++)
   3303                         sb.append('0');
   3304                 if (f.contains(Flags.UPPERCASE))
   3305                     s = s.toUpperCase();
   3306                 sb.append(s);
   3307             }
   3308 
   3309             // trailing sign indicator
   3310             trailingSign(sb, (value.signum() == -1));
   3311 
   3312             // justify based on width
   3313             a.append(justify(sb.toString()));
   3314         }
   3315 
   3316         private void print(float value, Locale l) throws IOException {
   3317             print((double) value, l);
   3318         }
   3319 
   3320         private void print(double value, Locale l) throws IOException {
   3321             StringBuilder sb = new StringBuilder();
   3322             boolean neg = Double.compare(value, 0.0) == -1;
   3323 
   3324             if (!Double.isNaN(value)) {
   3325                 double v = Math.abs(value);
   3326 
   3327                 // leading sign indicator
   3328                 leadingSign(sb, neg);
   3329 
   3330                 // the value
   3331                 if (!Double.isInfinite(v))
   3332                     print(sb, v, l, f, c, precision, neg);
   3333                 else
   3334                     sb.append(f.contains(Flags.UPPERCASE)
   3335                               ? "INFINITY" : "Infinity");
   3336 
   3337                 // trailing sign indicator
   3338                 trailingSign(sb, neg);
   3339             } else {
   3340                 sb.append(f.contains(Flags.UPPERCASE) ? "NAN" : "NaN");
   3341             }
   3342 
   3343             // justify based on width
   3344             a.append(justify(sb.toString()));
   3345         }
   3346 
   3347         // !Double.isInfinite(value) && !Double.isNaN(value)
   3348         private void print(StringBuilder sb, double value, Locale l,
   3349                            Flags f, char c, int precision, boolean neg)
   3350             throws IOException
   3351         {
   3352             if (c == Conversion.SCIENTIFIC) {
   3353                 // Create a new FormattedFloatingDecimal with the desired
   3354                 // precision.
   3355                 int prec = (precision == -1 ? 6 : precision);
   3356 
   3357                 FormattedFloatingDecimal fd
   3358                         = FormattedFloatingDecimal.valueOf(value, prec,
   3359                           FormattedFloatingDecimal.Form.SCIENTIFIC);
   3360 
   3361                 char[] mant = addZeros(fd.getMantissa(), prec);
   3362 
   3363                 // If the precision is zero and the '#' flag is set, add the
   3364                 // requested decimal point.
   3365                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
   3366                     mant = addDot(mant);
   3367 
   3368                 char[] exp = (value == 0.0)
   3369                     ? new char[] {'+','0','0'} : fd.getExponent();
   3370 
   3371                 int newW = width;
   3372                 if (width != -1)
   3373                     newW = adjustWidth(width - exp.length - 1, f, neg);
   3374                 localizedMagnitude(sb, mant, f, newW, l);
   3375 
   3376                 // BEGIN Android-changed: Use localized exponent separator for %e.
   3377                 Locale separatorLocale = (l != null) ? l : Locale.getDefault();
   3378                 LocaleData localeData = LocaleData.get(separatorLocale);
   3379                 sb.append(f.contains(Flags.UPPERCASE) ?
   3380                         localeData.exponentSeparator.toUpperCase(separatorLocale) :
   3381                         localeData.exponentSeparator.toLowerCase(separatorLocale));
   3382                 // END Android-changed: Use localized exponent separator for %e.
   3383 
   3384                 Flags flags = f.dup().remove(Flags.GROUP);
   3385                 char sign = exp[0];
   3386                 assert(sign == '+' || sign == '-');
   3387                 sb.append(sign);
   3388 
   3389                 char[] tmp = new char[exp.length - 1];
   3390                 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
   3391                 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
   3392             } else if (c == Conversion.DECIMAL_FLOAT) {
   3393                 // Create a new FormattedFloatingDecimal with the desired
   3394                 // precision.
   3395                 int prec = (precision == -1 ? 6 : precision);
   3396 
   3397                 FormattedFloatingDecimal fd
   3398                         = FormattedFloatingDecimal.valueOf(value, prec,
   3399                           FormattedFloatingDecimal.Form.DECIMAL_FLOAT);
   3400 
   3401                 char[] mant = addZeros(fd.getMantissa(), prec);
   3402 
   3403                 // If the precision is zero and the '#' flag is set, add the
   3404                 // requested decimal point.
   3405                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
   3406                     mant = addDot(mant);
   3407 
   3408                 int newW = width;
   3409                 if (width != -1)
   3410                     newW = adjustWidth(width, f, neg);
   3411                 localizedMagnitude(sb, mant, f, newW, l);
   3412             } else if (c == Conversion.GENERAL) {
   3413                 int prec = precision;
   3414                 if (precision == -1)
   3415                     prec = 6;
   3416                 else if (precision == 0)
   3417                     prec = 1;
   3418 
   3419                 char[] exp;
   3420                 char[] mant;
   3421                 int expRounded;
   3422                 if (value == 0.0) {
   3423                     exp = null;
   3424                     mant = new char[] {'0'};
   3425                     expRounded = 0;
   3426                 } else {
   3427                     FormattedFloatingDecimal fd
   3428                         = FormattedFloatingDecimal.valueOf(value, prec,
   3429                           FormattedFloatingDecimal.Form.GENERAL);
   3430                     exp = fd.getExponent();
   3431                     mant = fd.getMantissa();
   3432                     expRounded = fd.getExponentRounded();
   3433                 }
   3434 
   3435                 if (exp != null) {
   3436                     prec -= 1;
   3437                 } else {
   3438                     prec -= expRounded + 1;
   3439                 }
   3440 
   3441                 mant = addZeros(mant, prec);
   3442                 // If the precision is zero and the '#' flag is set, add the
   3443                 // requested decimal point.
   3444                 if (f.contains(Flags.ALTERNATE) && (prec == 0))
   3445                     mant = addDot(mant);
   3446 
   3447                 int newW = width;
   3448                 if (width != -1) {
   3449                     if (exp != null)
   3450                         newW = adjustWidth(width - exp.length - 1, f, neg);
   3451                     else
   3452                         newW = adjustWidth(width, f, neg);
   3453                 }
   3454                 localizedMagnitude(sb, mant, f, newW, l);
   3455 
   3456                 if (exp != null) {
   3457                     sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
   3458 
   3459                     Flags flags = f.dup().remove(Flags.GROUP);
   3460                     char sign = exp[0];
   3461                     assert(sign == '+' || sign == '-');
   3462                     sb.append(sign);
   3463 
   3464                     char[] tmp = new char[exp.length - 1];
   3465                     System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
   3466                     sb.append(localizedMagnitude(null, tmp, flags, -1, l));
   3467                 }
   3468             } else if (c == Conversion.HEXADECIMAL_FLOAT) {
   3469                 int prec = precision;
   3470                 if (precision == -1)
   3471                     // assume that we want all of the digits
   3472                     prec = 0;
   3473                 else if (precision == 0)
   3474                     prec = 1;
   3475 
   3476                 String s = hexDouble(value, prec);
   3477 
   3478                 char[] va;
   3479                 boolean upper = f.contains(Flags.UPPERCASE);
   3480                 sb.append(upper ? "0X" : "0x");
   3481 
   3482                 if (f.contains(Flags.ZERO_PAD))
   3483                     for (int i = 0; i < width - s.length() - 2; i++)
   3484                         sb.append('0');
   3485 
   3486                 int idx = s.indexOf('p');
   3487                 va = s.substring(0, idx).toCharArray();
   3488                 if (upper) {
   3489                     String tmp = new String(va);
   3490                     // don't localize hex
   3491                     tmp = tmp.toUpperCase(Locale.US);
   3492                     va = tmp.toCharArray();
   3493                 }
   3494                 sb.append(prec != 0 ? addZeros(va, prec) : va);
   3495                 sb.append(upper ? 'P' : 'p');
   3496                 sb.append(s.substring(idx+1));
   3497             }
   3498         }
   3499 
   3500         // Add zeros to the requested precision.
   3501         private char[] addZeros(char[] v, int prec) {
   3502             // Look for the dot.  If we don't find one, the we'll need to add
   3503             // it before we add the zeros.
   3504             int i;
   3505             for (i = 0; i < v.length; i++) {
   3506                 if (v[i] == '.')
   3507                     break;
   3508             }
   3509             boolean needDot = false;
   3510             if (i == v.length) {
   3511                 needDot = true;
   3512             }
   3513 
   3514             // Determine existing precision.
   3515             int outPrec = v.length - i - (needDot ? 0 : 1);
   3516             assert (outPrec <= prec);
   3517             if (outPrec == prec)
   3518                 return v;
   3519 
   3520             // Create new array with existing contents.
   3521             char[] tmp
   3522                 = new char[v.length + prec - outPrec + (needDot ? 1 : 0)];
   3523             System.arraycopy(v, 0, tmp, 0, v.length);
   3524 
   3525             // Add dot if previously determined to be necessary.
   3526             int start = v.length;
   3527             if (needDot) {
   3528                 tmp[v.length] = '.';
   3529                 start++;
   3530             }
   3531 
   3532             // Add zeros.
   3533             for (int j = start; j < tmp.length; j++)
   3534                 tmp[j] = '0';
   3535 
   3536             return tmp;
   3537         }
   3538 
   3539         // Method assumes that d > 0.
   3540         private String hexDouble(double d, int prec) {
   3541             // Let Double.toHexString handle simple cases
   3542             if(!Double.isFinite(d) || d == 0.0 || prec == 0 || prec >= 13)
   3543                 // remove "0x"
   3544                 return Double.toHexString(d).substring(2);
   3545             else {
   3546                 assert(prec >= 1 && prec <= 12);
   3547 
   3548                 int exponent  = Math.getExponent(d);
   3549                 boolean subnormal
   3550                     = (exponent == DoubleConsts.MIN_EXPONENT - 1);
   3551 
   3552                 // If this is subnormal input so normalize (could be faster to
   3553                 // do as integer operation).
   3554                 if (subnormal) {
   3555                     scaleUp = Math.scalb(1.0, 54);
   3556                     d *= scaleUp;
   3557                     // Calculate the exponent.  This is not just exponent + 54
   3558                     // since the former is not the normalized exponent.
   3559                     exponent = Math.getExponent(d);
   3560                     assert exponent >= DoubleConsts.MIN_EXPONENT &&
   3561                         exponent <= DoubleConsts.MAX_EXPONENT: exponent;
   3562                 }
   3563 
   3564                 int precision = 1 + prec*4;
   3565                 int shiftDistance
   3566                     =  DoubleConsts.SIGNIFICAND_WIDTH - precision;
   3567                 assert(shiftDistance >= 1 && shiftDistance < DoubleConsts.SIGNIFICAND_WIDTH);
   3568 
   3569                 long doppel = Double.doubleToLongBits(d);
   3570                 // Deterime the number of bits to keep.
   3571                 long newSignif
   3572                     = (doppel & (DoubleConsts.EXP_BIT_MASK
   3573                                  | DoubleConsts.SIGNIF_BIT_MASK))
   3574                                      >> shiftDistance;
   3575                 // Bits to round away.
   3576                 long roundingBits = doppel & ~(~0L << shiftDistance);
   3577 
   3578                 // To decide how to round, look at the low-order bit of the
   3579                 // working significand, the highest order discarded bit (the
   3580                 // round bit) and whether any of the lower order discarded bits
   3581                 // are nonzero (the sticky bit).
   3582 
   3583                 boolean leastZero = (newSignif & 0x1L) == 0L;
   3584                 boolean round
   3585                     = ((1L << (shiftDistance - 1) ) & roundingBits) != 0L;
   3586                 boolean sticky  = shiftDistance > 1 &&
   3587                     (~(1L<< (shiftDistance - 1)) & roundingBits) != 0;
   3588                 if((leastZero && round && sticky) || (!leastZero && round)) {
   3589                     newSignif++;
   3590                 }
   3591 
   3592                 long signBit = doppel & DoubleConsts.SIGN_BIT_MASK;
   3593                 newSignif = signBit | (newSignif << shiftDistance);
   3594                 double result = Double.longBitsToDouble(newSignif);
   3595 
   3596                 if (Double.isInfinite(result) ) {
   3597                     // Infinite result generated by rounding
   3598                     return "1.0p1024";
   3599                 } else {
   3600                     String res = Double.toHexString(result).substring(2);
   3601                     if (!subnormal)
   3602                         return res;
   3603                     else {
   3604                         // Create a normalized subnormal string.
   3605                         int idx = res.indexOf('p');
   3606                         if (idx == -1) {
   3607                             // No 'p' character in hex string.
   3608                             assert false;
   3609                             return null;
   3610                         } else {
   3611                             // Get exponent and append at the end.
   3612                             String exp = res.substring(idx + 1);
   3613                             int iexp = Integer.parseInt(exp) -54;
   3614                             return res.substring(0, idx) + "p"
   3615                                 + Integer.toString(iexp);
   3616                         }
   3617                     }
   3618                 }
   3619             }
   3620         }
   3621 
   3622         private void print(BigDecimal value, Locale l) throws IOException {
   3623             if (c == Conversion.HEXADECIMAL_FLOAT)
   3624                 failConversion(c, value);
   3625             StringBuilder sb = new StringBuilder();
   3626             boolean neg = value.signum() == -1;
   3627             BigDecimal v = value.abs();
   3628             // leading sign indicator
   3629             leadingSign(sb, neg);
   3630 
   3631             // the value
   3632             print(sb, v, l, f, c, precision, neg);
   3633 
   3634             // trailing sign indicator
   3635             trailingSign(sb, neg);
   3636 
   3637             // justify based on width
   3638             a.append(justify(sb.toString()));
   3639         }
   3640 
   3641         // value > 0
   3642         private void print(StringBuilder sb, BigDecimal value, Locale l,
   3643                            Flags f, char c, int precision, boolean neg)
   3644             throws IOException
   3645         {
   3646             if (c == Conversion.SCIENTIFIC) {
   3647                 // Create a new BigDecimal with the desired precision.
   3648                 int prec = (precision == -1 ? 6 : precision);
   3649                 int scale = value.scale();
   3650                 int origPrec = value.precision();
   3651                 int nzeros = 0;
   3652                 int compPrec;
   3653 
   3654                 if (prec > origPrec - 1) {
   3655                     compPrec = origPrec;
   3656                     nzeros = prec - (origPrec - 1);
   3657                 } else {
   3658                     compPrec = prec + 1;
   3659                 }
   3660 
   3661                 MathContext mc = new MathContext(compPrec);
   3662                 BigDecimal v
   3663                     = new BigDecimal(value.unscaledValue(), scale, mc);
   3664 
   3665                 BigDecimalLayout bdl
   3666                     = new BigDecimalLayout(v.unscaledValue(), v.scale(),
   3667                                            BigDecimalLayoutForm.SCIENTIFIC);
   3668 
   3669                 char[] mant = bdl.mantissa();
   3670 
   3671                 // Add a decimal point if necessary.  The mantissa may not
   3672                 // contain a decimal point if the scale is zero (the internal
   3673                 // representation has no fractional part) or the original
   3674                 // precision is one. Append a decimal point if '#' is set or if
   3675                 // we require zero padding to get to the requested precision.
   3676                 if ((origPrec == 1 || !bdl.hasDot())
   3677                     && (nzeros > 0 || (f.contains(Flags.ALTERNATE))))
   3678                     mant = addDot(mant);
   3679 
   3680                 // Add trailing zeros in the case precision is greater than
   3681                 // the number of available digits after the decimal separator.
   3682                 mant = trailingZeros(mant, nzeros);
   3683 
   3684                 char[] exp = bdl.exponent();
   3685                 int newW = width;
   3686                 if (width != -1)
   3687                     newW = adjustWidth(width - exp.length - 1, f, neg);
   3688                 localizedMagnitude(sb, mant, f, newW, l);
   3689 
   3690                 sb.append(f.contains(Flags.UPPERCASE) ? 'E' : 'e');
   3691 
   3692                 Flags flags = f.dup().remove(Flags.GROUP);
   3693                 char sign = exp[0];
   3694                 assert(sign == '+' || sign == '-');
   3695                 sb.append(exp[0]);
   3696 
   3697                 char[] tmp = new char[exp.length - 1];
   3698                 System.arraycopy(exp, 1, tmp, 0, exp.length - 1);
   3699                 sb.append(localizedMagnitude(null, tmp, flags, -1, l));
   3700             } else if (c == Conversion.DECIMAL_FLOAT) {
   3701                 // Create a new BigDecimal with the desired precision.
   3702                 int prec = (precision == -1 ? 6 : precision);
   3703                 int scale = value.scale();
   3704 
   3705                 if (scale > prec) {
   3706                     // more "scale" digits than the requested "precision"
   3707                     int compPrec = value.precision();
   3708                     if (compPrec <= scale) {
   3709                         // case of 0.xxxxxx
   3710                         value = value.setScale(prec, RoundingMode.HALF_UP);
   3711                     } else {
   3712                         compPrec -= (scale - prec);
   3713                         value = new BigDecimal(value.unscaledValue(),
   3714                                                scale,
   3715                                                new MathContext(compPrec));
   3716                     }
   3717                 }
   3718                 BigDecimalLayout bdl = new BigDecimalLayout(
   3719                                            value.unscaledValue(),
   3720                                            value.scale(),
   3721                                            BigDecimalLayoutForm.DECIMAL_FLOAT);
   3722 
   3723                 char mant[] = bdl.mantissa();
   3724                 int nzeros = (bdl.scale() < prec ? prec - bdl.scale() : 0);
   3725 
   3726                 // Add a decimal point if necessary.  The mantissa may not
   3727                 // contain a decimal point if the scale is zero (the internal
   3728                 // representation has no fractional part).  Append a decimal
   3729                 // point if '#' is set or we require zero padding to get to the
   3730                 // requested precision.
   3731                 if (bdl.scale() == 0 && (f.contains(Flags.ALTERNATE) || nzeros > 0))
   3732                     mant = addDot(bdl.mantissa());
   3733 
   3734                 // Add trailing zeros if the precision is greater than the
   3735                 // number of available digits after the decimal separator.
   3736                 mant = trailingZeros(mant, nzeros);
   3737 
   3738                 localizedMagnitude(sb, mant, f, adjustWidth(width, f, neg), l);
   3739             } else if (c == Conversion.GENERAL) {
   3740                 int prec = precision;
   3741                 if (precision == -1)
   3742                     prec = 6;
   3743                 else if (precision == 0)
   3744                     prec = 1;
   3745 
   3746                 BigDecimal tenToTheNegFour = BigDecimal.valueOf(1, 4);
   3747                 BigDecimal tenToThePrec = BigDecimal.valueOf(1, -prec);
   3748                 if ((value.equals(BigDecimal.ZERO))
   3749                     || ((value.compareTo(tenToTheNegFour) != -1)
   3750                         && (value.compareTo(tenToThePrec) == -1))) {
   3751 
   3752                     int e = - value.scale()
   3753                         + (value.unscaledValue().toString().length() - 1);
   3754 
   3755                     // xxx.yyy
   3756                     //   g precision (# sig digits) = #x + #y
   3757                     //   f precision = #y
   3758                     //   exponent = #x - 1
   3759                     // => f precision = g precision - exponent - 1
   3760                     // 0.000zzz
   3761                     //   g precision (# sig digits) = #z
   3762                     //   f precision = #0 (after '.') + #z
   3763                     //   exponent = - #0 (after '.') - 1
   3764                     // => f precision = g precision - exponent - 1
   3765                     prec = prec - e - 1;
   3766 
   3767                     print(sb, value, l, f, Conversion.DECIMAL_FLOAT, prec,
   3768                           neg);
   3769                 } else {
   3770                     print(sb, value, l, f, Conversion.SCIENTIFIC, prec - 1, neg);
   3771                 }
   3772             } else if (c == Conversion.HEXADECIMAL_FLOAT) {
   3773                 // This conversion isn't supported.  The error should be
   3774                 // reported earlier.
   3775                 assert false;
   3776             }
   3777         }
   3778 
   3779         private class BigDecimalLayout {
   3780             private StringBuilder mant;
   3781             private StringBuilder exp;
   3782             private boolean dot = false;
   3783             private int scale;
   3784 
   3785             public BigDecimalLayout(BigInteger intVal, int scale, BigDecimalLayoutForm form) {
   3786                 layout(intVal, scale, form);
   3787             }
   3788 
   3789             public boolean hasDot() {
   3790                 return dot;
   3791             }
   3792 
   3793             public int scale() {
   3794                 return scale;
   3795             }
   3796 
   3797             // char[] with canonical string representation
   3798             public char[] layoutChars() {
   3799                 StringBuilder sb = new StringBuilder(mant);
   3800                 if (exp != null) {
   3801                     sb.append('E');
   3802                     sb.append(exp);
   3803                 }
   3804                 return toCharArray(sb);
   3805             }
   3806 
   3807             public char[] mantissa() {
   3808                 return toCharArray(mant);
   3809             }
   3810 
   3811             // The exponent will be formatted as a sign ('+' or '-') followed
   3812             // by the exponent zero-padded to include at least two digits.
   3813             public char[] exponent() {
   3814                 return toCharArray(exp);
   3815             }
   3816 
   3817             private char[] toCharArray(StringBuilder sb) {
   3818                 if (sb == null)
   3819                     return null;
   3820                 char[] result = new char[sb.length()];
   3821                 sb.getChars(0, result.length, result, 0);
   3822                 return result;
   3823             }
   3824 
   3825             private void layout(BigInteger intVal, int scale, BigDecimalLayoutForm form) {
   3826                 char coeff[] = intVal.toString().toCharArray();
   3827                 this.scale = scale;
   3828 
   3829                 // Construct a buffer, with sufficient capacity for all cases.
   3830                 // If E-notation is needed, length will be: +1 if negative, +1
   3831                 // if '.' needed, +2 for "E+", + up to 10 for adjusted
   3832                 // exponent.  Otherwise it could have +1 if negative, plus
   3833                 // leading "0.00000"
   3834                 mant = new StringBuilder(coeff.length + 14);
   3835 
   3836                 if (scale == 0) {
   3837                     int len = coeff.length;
   3838                     if (len > 1) {
   3839                         mant.append(coeff[0]);
   3840                         if (form == BigDecimalLayoutForm.SCIENTIFIC) {
   3841                             mant.append('.');
   3842                             dot = true;
   3843                             mant.append(coeff, 1, len - 1);
   3844                             exp = new StringBuilder("+");
   3845                             if (len < 10)
   3846                                 exp.append("0").append(len - 1);
   3847                             else
   3848                                 exp.append(len - 1);
   3849                         } else {
   3850                             mant.append(coeff, 1, len - 1);
   3851                         }
   3852                     } else {
   3853                         mant.append(coeff);
   3854                         if (form == BigDecimalLayoutForm.SCIENTIFIC)
   3855                             exp = new StringBuilder("+00");
   3856                     }
   3857                     return;
   3858                 }
   3859                 long adjusted = -(long) scale + (coeff.length - 1);
   3860                 if (form == BigDecimalLayoutForm.DECIMAL_FLOAT) {
   3861                     // count of padding zeros
   3862                     int pad = scale - coeff.length;
   3863                     if (pad >= 0) {
   3864                         // 0.xxx form
   3865                         mant.append("0.");
   3866                         dot = true;
   3867                         for (; pad > 0 ; pad--) mant.append('0');
   3868                         mant.append(coeff);
   3869                     } else {
   3870                         if (-pad < coeff.length) {
   3871                             // xx.xx form
   3872                             mant.append(coeff, 0, -pad);
   3873                             mant.append('.');
   3874                             dot = true;
   3875                             mant.append(coeff, -pad, scale);
   3876                         } else {
   3877                             // xx form
   3878                             mant.append(coeff, 0, coeff.length);
   3879                             for (int i = 0; i < -scale; i++)
   3880                                 mant.append('0');
   3881                             this.scale = 0;
   3882                         }
   3883                     }
   3884                 } else {
   3885                     // x.xxx form
   3886                     mant.append(coeff[0]);
   3887                     if (coeff.length > 1) {
   3888                         mant.append('.');
   3889                         dot = true;
   3890                         mant.append(coeff, 1, coeff.length-1);
   3891                     }
   3892                     exp = new StringBuilder();
   3893                     if (adjusted != 0) {
   3894                         long abs = Math.abs(adjusted);
   3895                         // require sign
   3896                         exp.append(adjusted < 0 ? '-' : '+');
   3897                         if (abs < 10)
   3898                             exp.append('0');
   3899                         exp.append(abs);
   3900                     } else {
   3901                         exp.append("+00");
   3902                     }
   3903                 }
   3904             }
   3905         }
   3906 
   3907         private int adjustWidth(int width, Flags f, boolean neg) {
   3908             int newW = width;
   3909             if (newW != -1 && neg && f.contains(Flags.PARENTHESES))
   3910                 newW--;
   3911             return newW;
   3912         }
   3913 
   3914         // Add a '.' to th mantissa if required
   3915         private char[] addDot(char[] mant) {
   3916             char[] tmp = mant;
   3917             tmp = new char[mant.length + 1];
   3918             System.arraycopy(mant, 0, tmp, 0, mant.length);
   3919             tmp[tmp.length - 1] = '.';
   3920             return tmp;
   3921         }
   3922 
   3923         // Add trailing zeros in the case precision is greater than the number
   3924         // of available digits after the decimal separator.
   3925         private char[] trailingZeros(char[] mant, int nzeros) {
   3926             char[] tmp = mant;
   3927             if (nzeros > 0) {
   3928                 tmp = new char[mant.length + nzeros];
   3929                 System.arraycopy(mant, 0, tmp, 0, mant.length);
   3930                 for (int i = mant.length; i < tmp.length; i++)
   3931                     tmp[i] = '0';
   3932             }
   3933             return tmp;
   3934         }
   3935 
   3936         private void print(Calendar t, char c, Locale l)  throws IOException
   3937         {
   3938             StringBuilder sb = new StringBuilder();
   3939             print(sb, t, c, l);
   3940 
   3941             // justify based on width
   3942             String s = justify(sb.toString());
   3943             if (f.contains(Flags.UPPERCASE))
   3944                 s = s.toUpperCase();
   3945 
   3946             a.append(s);
   3947         }
   3948 
   3949         private Appendable print(StringBuilder sb, Calendar t, char c,
   3950                                  Locale l)
   3951             throws IOException
   3952         {
   3953             if (sb == null)
   3954                 sb = new StringBuilder();
   3955             switch (c) {
   3956             case DateTime.HOUR_OF_DAY_0: // 'H' (00 - 23)
   3957             case DateTime.HOUR_0:        // 'I' (01 - 12)
   3958             case DateTime.HOUR_OF_DAY:   // 'k' (0 - 23) -- like H
   3959             case DateTime.HOUR:        { // 'l' (1 - 12) -- like I
   3960                 int i = t.get(Calendar.HOUR_OF_DAY);
   3961                 if (c == DateTime.HOUR_0 || c == DateTime.HOUR)
   3962                     i = (i == 0 || i == 12 ? 12 : i % 12);
   3963                 Flags flags = (c == DateTime.HOUR_OF_DAY_0
   3964                                || c == DateTime.HOUR_0
   3965                                ? Flags.ZERO_PAD
   3966                                : Flags.NONE);
   3967                 sb.append(localizedMagnitude(null, i, flags, 2, l));
   3968                 break;
   3969             }
   3970             case DateTime.MINUTE:      { // 'M' (00 - 59)
   3971                 int i = t.get(Calendar.MINUTE);
   3972                 Flags flags = Flags.ZERO_PAD;
   3973                 sb.append(localizedMagnitude(null, i, flags, 2, l));
   3974                 break;
   3975             }
   3976             case DateTime.NANOSECOND:  { // 'N' (000000000 - 999999999)
   3977                 int i = t.get(Calendar.MILLISECOND) * 1000000;
   3978                 Flags flags = Flags.ZERO_PAD;
   3979                 sb.append(localizedMagnitude(null, i, flags, 9, l));
   3980                 break;
   3981             }
   3982             case DateTime.MILLISECOND: { // 'L' (000 - 999)
   3983                 int i = t.get(Calendar.MILLISECOND);
   3984                 Flags flags = Flags.ZERO_PAD;
   3985                 sb.append(localizedMagnitude(null, i, flags, 3, l));
   3986                 break;
   3987             }
   3988             case DateTime.MILLISECOND_SINCE_EPOCH: { // 'Q' (0 - 99...?)
   3989                 long i = t.getTimeInMillis();
   3990                 Flags flags = Flags.NONE;
   3991                 sb.append(localizedMagnitude(null, i, flags, width, l));
   3992                 break;
   3993             }
   3994             case DateTime.AM_PM:       { // 'p' (am or pm)
   3995                 // Calendar.AM = 0, Calendar.PM = 1, LocaleElements defines upper
   3996                 String[] ampm = { "AM", "PM" };
   3997                 if (l != null && l != Locale.US) {
   3998                     DateFormatSymbols dfs = DateFormatSymbols.getInstance(l);
   3999                     ampm = dfs.getAmPmStrings();
   4000                 }
   4001                 String s = ampm[t.get(Calendar.AM_PM)];
   4002                 sb.append(s.toLowerCase(l != null ? l : Locale.US));
   4003                 break;
   4004             }
   4005             case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
   4006                 long i = t.getTimeInMillis() / 1000;
   4007                 Flags flags = Flags.NONE;
   4008                 sb.append(localizedMagnitude(null, i, flags, width, l));
   4009                 break;
   4010             }
   4011             case DateTime.SECOND:      { // 'S' (00 - 60 - leap second)
   4012                 int i = t.get(Calendar.SECOND);
   4013                 Flags flags = Flags.ZERO_PAD;
   4014                 sb.append(localizedMagnitude(null, i, flags, 2, l));
   4015                 break;
   4016             }
   4017             case DateTime.ZONE_NUMERIC: { // 'z' ({-|+}####) - ls minus?
   4018                 int i = t.get(Calendar.ZONE_OFFSET) + t.get(Calendar.DST_OFFSET);
   4019                 boolean neg = i < 0;
   4020                 sb.append(neg ? '-' : '+');
   4021                 if (neg)
   4022                     i = -i;
   4023                 int min = i / 60000;
   4024                 // combine minute and hour into a single integer
   4025                 int offset = (min / 60) * 100 + (min % 60);
   4026                 Flags flags = Flags.ZERO_PAD;
   4027 
   4028                 sb.append(localizedMagnitude(null, offset, flags, 4, l));
   4029                 break;
   4030             }
   4031             case DateTime.ZONE:        { // 'Z' (symbol)
   4032                 TimeZone tz = t.getTimeZone();
   4033                 sb.append(tz.getDisplayName((t.get(Calendar.DST_OFFSET) != 0),
   4034                                            TimeZone.SHORT,
   4035                                             (l == null) ? Locale.US : l));
   4036                 break;
   4037             }
   4038 
   4039             // Date
   4040             case DateTime.NAME_OF_DAY_ABBREV:     // 'a'
   4041             case DateTime.NAME_OF_DAY:          { // 'A'
   4042                 int i = t.get(Calendar.DAY_OF_WEEK);
   4043                 Locale lt = ((l == null) ? Locale.US : l);
   4044                 DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
   4045                 if (c == DateTime.NAME_OF_DAY)
   4046                     sb.append(dfs.getWeekdays()[i]);
   4047                 else
   4048                     sb.append(dfs.getShortWeekdays()[i]);
   4049                 break;
   4050             }
   4051             case DateTime.NAME_OF_MONTH_ABBREV:   // 'b'
   4052             case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
   4053             case DateTime.NAME_OF_MONTH:        { // 'B'
   4054                 int i = t.get(Calendar.MONTH);
   4055                 Locale lt = ((l == null) ? Locale.US : l);
   4056                 DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
   4057                 if (c == DateTime.NAME_OF_MONTH)
   4058                     sb.append(dfs.getMonths()[i]);
   4059                 else
   4060                     sb.append(dfs.getShortMonths()[i]);
   4061                 break;
   4062             }
   4063             case DateTime.CENTURY:                // 'C' (00 - 99)
   4064             case DateTime.YEAR_2:                 // 'y' (00 - 99)
   4065             case DateTime.YEAR_4:               { // 'Y' (0000 - 9999)
   4066                 int i = t.get(Calendar.YEAR);
   4067                 int size = 2;
   4068                 switch (c) {
   4069                 case DateTime.CENTURY:
   4070                     i /= 100;
   4071                     break;
   4072                 case DateTime.YEAR_2:
   4073                     i %= 100;
   4074                     break;
   4075                 case DateTime.YEAR_4:
   4076                     size = 4;
   4077                     break;
   4078                 }
   4079                 Flags flags = Flags.ZERO_PAD;
   4080                 sb.append(localizedMagnitude(null, i, flags, size, l));
   4081                 break;
   4082             }
   4083             case DateTime.DAY_OF_MONTH_0:         // 'd' (01 - 31)
   4084             case DateTime.DAY_OF_MONTH:         { // 'e' (1 - 31) -- like d
   4085                 int i = t.get(Calendar.DATE);
   4086                 Flags flags = (c == DateTime.DAY_OF_MONTH_0
   4087                                ? Flags.ZERO_PAD
   4088                                : Flags.NONE);
   4089                 sb.append(localizedMagnitude(null, i, flags, 2, l));
   4090                 break;
   4091             }
   4092             case DateTime.DAY_OF_YEAR:          { // 'j' (001 - 366)
   4093                 int i = t.get(Calendar.DAY_OF_YEAR);
   4094                 Flags flags = Flags.ZERO_PAD;
   4095                 sb.append(localizedMagnitude(null, i, flags, 3, l));
   4096                 break;
   4097             }
   4098             case DateTime.MONTH:                { // 'm' (01 - 12)
   4099                 int i = t.get(Calendar.MONTH) + 1;
   4100                 Flags flags = Flags.ZERO_PAD;
   4101                 sb.append(localizedMagnitude(null, i, flags, 2, l));
   4102                 break;
   4103             }
   4104 
   4105             // Composites
   4106             case DateTime.TIME:         // 'T' (24 hour hh:mm:ss - %tH:%tM:%tS)
   4107             case DateTime.TIME_24_HOUR:    { // 'R' (hh:mm same as %H:%M)
   4108                 char sep = ':';
   4109                 print(sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep);
   4110                 print(sb, t, DateTime.MINUTE, l);
   4111                 if (c == DateTime.TIME) {
   4112                     sb.append(sep);
   4113                     print(sb, t, DateTime.SECOND, l);
   4114                 }
   4115                 break;
   4116             }
   4117             case DateTime.TIME_12_HOUR:    { // 'r' (hh:mm:ss [AP]M)
   4118                 char sep = ':';
   4119                 print(sb, t, DateTime.HOUR_0, l).append(sep);
   4120                 print(sb, t, DateTime.MINUTE, l).append(sep);
   4121                 print(sb, t, DateTime.SECOND, l).append(' ');
   4122                 // this may be in wrong place for some locales
   4123                 StringBuilder tsb = new StringBuilder();
   4124                 print(tsb, t, DateTime.AM_PM, l);
   4125                 sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
   4126                 break;
   4127             }
   4128             case DateTime.DATE_TIME:    { // 'c' (Sat Nov 04 12:02:33 EST 1999)
   4129                 char sep = ' ';
   4130                 print(sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep);
   4131                 print(sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep);
   4132                 print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
   4133                 print(sb, t, DateTime.TIME, l).append(sep);
   4134                 print(sb, t, DateTime.ZONE, l).append(sep);
   4135                 print(sb, t, DateTime.YEAR_4, l);
   4136                 break;
   4137             }
   4138             case DateTime.DATE:            { // 'D' (mm/dd/yy)
   4139                 char sep = '/';
   4140                 print(sb, t, DateTime.MONTH, l).append(sep);
   4141                 print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
   4142                 print(sb, t, DateTime.YEAR_2, l);
   4143                 break;
   4144             }
   4145             case DateTime.ISO_STANDARD_DATE: { // 'F' (%Y-%m-%d)
   4146                 char sep = '-';
   4147                 print(sb, t, DateTime.YEAR_4, l).append(sep);
   4148                 print(sb, t, DateTime.MONTH, l).append(sep);
   4149                 print(sb, t, DateTime.DAY_OF_MONTH_0, l);
   4150                 break;
   4151             }
   4152             default:
   4153                 assert false;
   4154             }
   4155             return sb;
   4156         }
   4157 
   4158         private void print(TemporalAccessor t, char c, Locale l)  throws IOException {
   4159             StringBuilder sb = new StringBuilder();
   4160             print(sb, t, c, l);
   4161             // justify based on width
   4162             String s = justify(sb.toString());
   4163             if (f.contains(Flags.UPPERCASE))
   4164                 s = s.toUpperCase();
   4165             a.append(s);
   4166         }
   4167 
   4168         private Appendable print(StringBuilder sb, TemporalAccessor t, char c,
   4169                                  Locale l) throws IOException {
   4170             if (sb == null)
   4171                 sb = new StringBuilder();
   4172             try {
   4173                 switch (c) {
   4174                 case DateTime.HOUR_OF_DAY_0: {  // 'H' (00 - 23)
   4175                     int i = t.get(ChronoField.HOUR_OF_DAY);
   4176                     sb.append(localizedMagnitude(null, i, Flags.ZERO_PAD, 2, l));
   4177                     break;
   4178                 }
   4179                 case DateTime.HOUR_OF_DAY: {   // 'k' (0 - 23) -- like H
   4180                     int i = t.get(ChronoField.HOUR_OF_DAY);
   4181                     sb.append(localizedMagnitude(null, i, Flags.NONE, 2, l));
   4182                     break;
   4183                 }
   4184                 case DateTime.HOUR_0:      {  // 'I' (01 - 12)
   4185                     int i = t.get(ChronoField.CLOCK_HOUR_OF_AMPM);
   4186                     sb.append(localizedMagnitude(null, i, Flags.ZERO_PAD, 2, l));
   4187                     break;
   4188                 }
   4189                 case DateTime.HOUR:        { // 'l' (1 - 12) -- like I
   4190                     int i = t.get(ChronoField.CLOCK_HOUR_OF_AMPM);
   4191                     sb.append(localizedMagnitude(null, i, Flags.NONE, 2, l));
   4192                     break;
   4193                 }
   4194                 case DateTime.MINUTE:      { // 'M' (00 - 59)
   4195                     int i = t.get(ChronoField.MINUTE_OF_HOUR);
   4196                     Flags flags = Flags.ZERO_PAD;
   4197                     sb.append(localizedMagnitude(null, i, flags, 2, l));
   4198                     break;
   4199                 }
   4200                 case DateTime.NANOSECOND:  { // 'N' (000000000 - 999999999)
   4201                     int i = t.get(ChronoField.MILLI_OF_SECOND) * 1000000;
   4202                     Flags flags = Flags.ZERO_PAD;
   4203                     sb.append(localizedMagnitude(null, i, flags, 9, l));
   4204                     break;
   4205                 }
   4206                 case DateTime.MILLISECOND: { // 'L' (000 - 999)
   4207                     int i = t.get(ChronoField.MILLI_OF_SECOND);
   4208                     Flags flags = Flags.ZERO_PAD;
   4209                     sb.append(localizedMagnitude(null, i, flags, 3, l));
   4210                     break;
   4211                 }
   4212                 case DateTime.MILLISECOND_SINCE_EPOCH: { // 'Q' (0 - 99...?)
   4213                     long i = t.getLong(ChronoField.INSTANT_SECONDS) * 1000L +
   4214                              t.getLong(ChronoField.MILLI_OF_SECOND);
   4215                     Flags flags = Flags.NONE;
   4216                     sb.append(localizedMagnitude(null, i, flags, width, l));
   4217                     break;
   4218                 }
   4219                 case DateTime.AM_PM:       { // 'p' (am or pm)
   4220                     // Calendar.AM = 0, Calendar.PM = 1, LocaleElements defines upper
   4221                     String[] ampm = { "AM", "PM" };
   4222                     if (l != null && l != Locale.US) {
   4223                         DateFormatSymbols dfs = DateFormatSymbols.getInstance(l);
   4224                         ampm = dfs.getAmPmStrings();
   4225                     }
   4226                     String s = ampm[t.get(ChronoField.AMPM_OF_DAY)];
   4227                     sb.append(s.toLowerCase(l != null ? l : Locale.US));
   4228                     break;
   4229                 }
   4230                 case DateTime.SECONDS_SINCE_EPOCH: { // 's' (0 - 99...?)
   4231                     long i = t.getLong(ChronoField.INSTANT_SECONDS);
   4232                     Flags flags = Flags.NONE;
   4233                     sb.append(localizedMagnitude(null, i, flags, width, l));
   4234                     break;
   4235                 }
   4236                 case DateTime.SECOND:      { // 'S' (00 - 60 - leap second)
   4237                     int i = t.get(ChronoField.SECOND_OF_MINUTE);
   4238                     Flags flags = Flags.ZERO_PAD;
   4239                     sb.append(localizedMagnitude(null, i, flags, 2, l));
   4240                     break;
   4241                 }
   4242                 case DateTime.ZONE_NUMERIC: { // 'z' ({-|+}####) - ls minus?
   4243                     int i = t.get(ChronoField.OFFSET_SECONDS);
   4244                     boolean neg = i < 0;
   4245                     sb.append(neg ? '-' : '+');
   4246                     if (neg)
   4247                         i = -i;
   4248                     int min = i / 60;
   4249                     // combine minute and hour into a single integer
   4250                     int offset = (min / 60) * 100 + (min % 60);
   4251                     Flags flags = Flags.ZERO_PAD;
   4252                     sb.append(localizedMagnitude(null, offset, flags, 4, l));
   4253                     break;
   4254                 }
   4255                 case DateTime.ZONE:        { // 'Z' (symbol)
   4256                     ZoneId zid = t.query(TemporalQueries.zone());
   4257                     if (zid == null) {
   4258                         throw new IllegalFormatConversionException(c, t.getClass());
   4259                     }
   4260                     if (!(zid instanceof ZoneOffset) &&
   4261                         t.isSupported(ChronoField.INSTANT_SECONDS)) {
   4262                         Instant instant = Instant.from(t);
   4263                         sb.append(TimeZone.getTimeZone(zid.getId())
   4264                                           .getDisplayName(zid.getRules().isDaylightSavings(instant),
   4265                                                           TimeZone.SHORT,
   4266                                                           (l == null) ? Locale.US : l));
   4267                         break;
   4268                     }
   4269                     sb.append(zid.getId());
   4270                     break;
   4271                 }
   4272                 // Date
   4273                 case DateTime.NAME_OF_DAY_ABBREV:     // 'a'
   4274                 case DateTime.NAME_OF_DAY:          { // 'A'
   4275                     int i = t.get(ChronoField.DAY_OF_WEEK) % 7 + 1;
   4276                     Locale lt = ((l == null) ? Locale.US : l);
   4277                     DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
   4278                     if (c == DateTime.NAME_OF_DAY)
   4279                         sb.append(dfs.getWeekdays()[i]);
   4280                     else
   4281                         sb.append(dfs.getShortWeekdays()[i]);
   4282                     break;
   4283                 }
   4284                 case DateTime.NAME_OF_MONTH_ABBREV:   // 'b'
   4285                 case DateTime.NAME_OF_MONTH_ABBREV_X: // 'h' -- same b
   4286                 case DateTime.NAME_OF_MONTH:        { // 'B'
   4287                     int i = t.get(ChronoField.MONTH_OF_YEAR) - 1;
   4288                     Locale lt = ((l == null) ? Locale.US : l);
   4289                     DateFormatSymbols dfs = DateFormatSymbols.getInstance(lt);
   4290                     if (c == DateTime.NAME_OF_MONTH)
   4291                         sb.append(dfs.getMonths()[i]);
   4292                     else
   4293                         sb.append(dfs.getShortMonths()[i]);
   4294                     break;
   4295                 }
   4296                 case DateTime.CENTURY:                // 'C' (00 - 99)
   4297                 case DateTime.YEAR_2:                 // 'y' (00 - 99)
   4298                 case DateTime.YEAR_4:               { // 'Y' (0000 - 9999)
   4299                     int i = t.get(ChronoField.YEAR_OF_ERA);
   4300                     int size = 2;
   4301                     switch (c) {
   4302                     case DateTime.CENTURY:
   4303                         i /= 100;
   4304                         break;
   4305                     case DateTime.YEAR_2:
   4306                         i %= 100;
   4307                         break;
   4308                     case DateTime.YEAR_4:
   4309                         size = 4;
   4310                         break;
   4311                     }
   4312                     Flags flags = Flags.ZERO_PAD;
   4313                     sb.append(localizedMagnitude(null, i, flags, size, l));
   4314                     break;
   4315                 }
   4316                 case DateTime.DAY_OF_MONTH_0:         // 'd' (01 - 31)
   4317                 case DateTime.DAY_OF_MONTH:         { // 'e' (1 - 31) -- like d
   4318                     int i = t.get(ChronoField.DAY_OF_MONTH);
   4319                     Flags flags = (c == DateTime.DAY_OF_MONTH_0
   4320                                    ? Flags.ZERO_PAD
   4321                                    : Flags.NONE);
   4322                     sb.append(localizedMagnitude(null, i, flags, 2, l));
   4323                     break;
   4324                 }
   4325                 case DateTime.DAY_OF_YEAR:          { // 'j' (001 - 366)
   4326                     int i = t.get(ChronoField.DAY_OF_YEAR);
   4327                     Flags flags = Flags.ZERO_PAD;
   4328                     sb.append(localizedMagnitude(null, i, flags, 3, l));
   4329                     break;
   4330                 }
   4331                 case DateTime.MONTH:                { // 'm' (01 - 12)
   4332                     int i = t.get(ChronoField.MONTH_OF_YEAR);
   4333                     Flags flags = Flags.ZERO_PAD;
   4334                     sb.append(localizedMagnitude(null, i, flags, 2, l));
   4335                     break;
   4336                 }
   4337 
   4338                 // Composites
   4339                 case DateTime.TIME:         // 'T' (24 hour hh:mm:ss - %tH:%tM:%tS)
   4340                 case DateTime.TIME_24_HOUR:    { // 'R' (hh:mm same as %H:%M)
   4341                     char sep = ':';
   4342                     print(sb, t, DateTime.HOUR_OF_DAY_0, l).append(sep);
   4343                     print(sb, t, DateTime.MINUTE, l);
   4344                     if (c == DateTime.TIME) {
   4345                         sb.append(sep);
   4346                         print(sb, t, DateTime.SECOND, l);
   4347                     }
   4348                     break;
   4349                 }
   4350                 case DateTime.TIME_12_HOUR:    { // 'r' (hh:mm:ss [AP]M)
   4351                     char sep = ':';
   4352                     print(sb, t, DateTime.HOUR_0, l).append(sep);
   4353                     print(sb, t, DateTime.MINUTE, l).append(sep);
   4354                     print(sb, t, DateTime.SECOND, l).append(' ');
   4355                     // this may be in wrong place for some locales
   4356                     StringBuilder tsb = new StringBuilder();
   4357                     print(tsb, t, DateTime.AM_PM, l);
   4358                     sb.append(tsb.toString().toUpperCase(l != null ? l : Locale.US));
   4359                     break;
   4360                 }
   4361                 case DateTime.DATE_TIME:    { // 'c' (Sat Nov 04 12:02:33 EST 1999)
   4362                     char sep = ' ';
   4363                     print(sb, t, DateTime.NAME_OF_DAY_ABBREV, l).append(sep);
   4364                     print(sb, t, DateTime.NAME_OF_MONTH_ABBREV, l).append(sep);
   4365                     print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
   4366                     print(sb, t, DateTime.TIME, l).append(sep);
   4367                     print(sb, t, DateTime.ZONE, l).append(sep);
   4368                     print(sb, t, DateTime.YEAR_4, l);
   4369                     break;
   4370                 }
   4371                 case DateTime.DATE:            { // 'D' (mm/dd/yy)
   4372                     char sep = '/';
   4373                     print(sb, t, DateTime.MONTH, l).append(sep);
   4374                     print(sb, t, DateTime.DAY_OF_MONTH_0, l).append(sep);
   4375                     print(sb, t, DateTime.YEAR_2, l);
   4376                     break;
   4377                 }
   4378                 case DateTime.ISO_STANDARD_DATE: { // 'F' (%Y-%m-%d)
   4379                     char sep = '-';
   4380                     print(sb, t, DateTime.YEAR_4, l).append(sep);
   4381                     print(sb, t, DateTime.MONTH, l).append(sep);
   4382                     print(sb, t, DateTime.DAY_OF_MONTH_0, l);
   4383                     break;
   4384                 }
   4385                 default:
   4386                     assert false;
   4387                 }
   4388             } catch (DateTimeException x) {
   4389                 throw new IllegalFormatConversionException(c, t.getClass());
   4390             }
   4391             return sb;
   4392         }
   4393 
   4394         // -- Methods to support throwing exceptions --
   4395 
   4396         private void failMismatch(Flags f, char c) {
   4397             String fs = f.toString();
   4398             throw new FormatFlagsConversionMismatchException(fs, c);
   4399         }
   4400 
   4401         private void failConversion(char c, Object arg) {
   4402             throw new IllegalFormatConversionException(c, arg.getClass());
   4403         }
   4404 
   4405         private char getZero(Locale l) {
   4406             if ((l != null) &&  !l.equals(locale())) {
   4407                 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
   4408                 return dfs.getZeroDigit();
   4409             }
   4410             return zero;
   4411         }
   4412 
   4413         private StringBuilder
   4414             localizedMagnitude(StringBuilder sb, long value, Flags f,
   4415                                int width, Locale l)
   4416         {
   4417             char[] va = Long.toString(value, 10).toCharArray();
   4418             return localizedMagnitude(sb, va, f, width, l);
   4419         }
   4420 
   4421         private StringBuilder
   4422             localizedMagnitude(StringBuilder sb, char[] value, Flags f,
   4423                                int width, Locale l)
   4424         {
   4425             if (sb == null)
   4426                 sb = new StringBuilder();
   4427             int begin = sb.length();
   4428 
   4429             char zero = getZero(l);
   4430 
   4431             // determine localized grouping separator and size
   4432             char grpSep = '\0';
   4433             int  grpSize = -1;
   4434             char decSep = '\0';
   4435 
   4436             int len = value.length;
   4437             int dot = len;
   4438             for (int j = 0; j < len; j++) {
   4439                 if (value[j] == '.') {
   4440                     dot = j;
   4441                     break;
   4442                 }
   4443             }
   4444 
   4445             if (dot < len) {
   4446                 if (l == null || l.equals(Locale.US)) {
   4447                     decSep  = '.';
   4448                 } else {
   4449                     DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
   4450                     decSep  = dfs.getDecimalSeparator();
   4451                 }
   4452             }
   4453 
   4454             if (f.contains(Flags.GROUP)) {
   4455                 if (l == null || l.equals(Locale.US)) {
   4456                     grpSep = ',';
   4457                     grpSize = 3;
   4458                 } else {
   4459                     DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(l);
   4460                     grpSep = dfs.getGroupingSeparator();
   4461                     DecimalFormat df = (DecimalFormat) NumberFormat.getIntegerInstance(l);
   4462                     grpSize = df.getGroupingSize();
   4463                     // BEGIN Android-changed: http://b/33245708
   4464                     // Some locales have a group separator but also patterns without groups.
   4465                     // If we do not clear the group separator in these cases a divide by zero
   4466                     // is thrown when determining where to place the separators.
   4467                     if (!df.isGroupingUsed() || df.getGroupingSize() == 0) {
   4468                         grpSep = '\0';
   4469                     }
   4470                     // END Android-changed: http://b/33245708.
   4471                 }
   4472             }
   4473 
   4474             // localize the digits inserting group separators as necessary
   4475             for (int j = 0; j < len; j++) {
   4476                 if (j == dot) {
   4477                     sb.append(decSep);
   4478                     // no more group separators after the decimal separator
   4479                     grpSep = '\0';
   4480                     continue;
   4481                 }
   4482 
   4483                 char c = value[j];
   4484                 sb.append((char) ((c - '0') + zero));
   4485                 if (grpSep != '\0' && j != dot - 1 && ((dot - j) % grpSize == 1))
   4486                     sb.append(grpSep);
   4487             }
   4488 
   4489             // apply zero padding
   4490             len = sb.length();
   4491             if (width != -1 && f.contains(Flags.ZERO_PAD))
   4492                 for (int k = 0; k < width - len; k++)
   4493                     sb.insert(begin, zero);
   4494 
   4495             return sb;
   4496         }
   4497     }
   4498 
   4499     private static class Flags {
   4500         private int flags;
   4501 
   4502         static final Flags NONE          = new Flags(0);      // ''
   4503 
   4504         // duplicate declarations from Formattable.java
   4505         static final Flags LEFT_JUSTIFY  = new Flags(1<<0);   // '-'
   4506         static final Flags UPPERCASE     = new Flags(1<<1);   // '^'
   4507         static final Flags ALTERNATE     = new Flags(1<<2);   // '#'
   4508 
   4509         // numerics
   4510         static final Flags PLUS          = new Flags(1<<3);   // '+'
   4511         static final Flags LEADING_SPACE = new Flags(1<<4);   // ' '
   4512         static final Flags ZERO_PAD      = new Flags(1<<5);   // '0'
   4513         static final Flags GROUP         = new Flags(1<<6);   // ','
   4514         static final Flags PARENTHESES   = new Flags(1<<7);   // '('
   4515 
   4516         // indexing
   4517         static final Flags PREVIOUS      = new Flags(1<<8);   // '<'
   4518 
   4519         private Flags(int f) {
   4520             flags = f;
   4521         }
   4522 
   4523         public int valueOf() {
   4524             return flags;
   4525         }
   4526 
   4527         public boolean contains(Flags f) {
   4528             return (flags & f.valueOf()) == f.valueOf();
   4529         }
   4530 
   4531         public Flags dup() {
   4532             return new Flags(flags);
   4533         }
   4534 
   4535         private Flags add(Flags f) {
   4536             flags |= f.valueOf();
   4537             return this;
   4538         }
   4539 
   4540         public Flags remove(Flags f) {
   4541             flags &= ~f.valueOf();
   4542             return this;
   4543         }
   4544 
   4545         public static Flags parse(String s) {
   4546             char[] ca = s.toCharArray();
   4547             Flags f = new Flags(0);
   4548             for (int i = 0; i < ca.length; i++) {
   4549                 Flags v = parse(ca[i]);
   4550                 if (f.contains(v))
   4551                     throw new DuplicateFormatFlagsException(v.toString());
   4552                 f.add(v);
   4553             }
   4554             return f;
   4555         }
   4556 
   4557         // parse those flags which may be provided by users
   4558         private static Flags parse(char c) {
   4559             switch (c) {
   4560             case '-': return LEFT_JUSTIFY;
   4561             case '#': return ALTERNATE;
   4562             case '+': return PLUS;
   4563             case ' ': return LEADING_SPACE;
   4564             case '0': return ZERO_PAD;
   4565             case ',': return GROUP;
   4566             case '(': return PARENTHESES;
   4567             case '<': return PREVIOUS;
   4568             default:
   4569                 throw new UnknownFormatFlagsException(String.valueOf(c));
   4570             }
   4571         }
   4572 
   4573         // Returns a string representation of the current {@code Flags}.
   4574         public static String toString(Flags f) {
   4575             return f.toString();
   4576         }
   4577 
   4578         public String toString() {
   4579             StringBuilder sb = new StringBuilder();
   4580             if (contains(LEFT_JUSTIFY))  sb.append('-');
   4581             if (contains(UPPERCASE))     sb.append('^');
   4582             if (contains(ALTERNATE))     sb.append('#');
   4583             if (contains(PLUS))          sb.append('+');
   4584             if (contains(LEADING_SPACE)) sb.append(' ');
   4585             if (contains(ZERO_PAD))      sb.append('0');
   4586             if (contains(GROUP))         sb.append(',');
   4587             if (contains(PARENTHESES))   sb.append('(');
   4588             if (contains(PREVIOUS))      sb.append('<');
   4589             return sb.toString();
   4590         }
   4591     }
   4592 
   4593     private static class Conversion {
   4594         // Byte, Short, Integer, Long, BigInteger
   4595         // (and associated primitives due to autoboxing)
   4596         static final char DECIMAL_INTEGER     = 'd';
   4597         static final char OCTAL_INTEGER       = 'o';
   4598         static final char HEXADECIMAL_INTEGER = 'x';
   4599         static final char HEXADECIMAL_INTEGER_UPPER = 'X';
   4600 
   4601         // Float, Double, BigDecimal
   4602         // (and associated primitives due to autoboxing)
   4603         static final char SCIENTIFIC          = 'e';
   4604         static final char SCIENTIFIC_UPPER    = 'E';
   4605         static final char GENERAL             = 'g';
   4606         static final char GENERAL_UPPER       = 'G';
   4607         static final char DECIMAL_FLOAT       = 'f';
   4608         static final char HEXADECIMAL_FLOAT   = 'a';
   4609         static final char HEXADECIMAL_FLOAT_UPPER = 'A';
   4610 
   4611         // Character, Byte, Short, Integer
   4612         // (and associated primitives due to autoboxing)
   4613         static final char CHARACTER           = 'c';
   4614         static final char CHARACTER_UPPER     = 'C';
   4615 
   4616         // java.util.Date, java.util.Calendar, long
   4617         static final char DATE_TIME           = 't';
   4618         static final char DATE_TIME_UPPER     = 'T';
   4619 
   4620         // if (arg.TYPE != boolean) return boolean
   4621         // if (arg != null) return true; else return false;
   4622         static final char BOOLEAN             = 'b';
   4623         static final char BOOLEAN_UPPER       = 'B';
   4624         // if (arg instanceof Formattable) arg.formatTo()
   4625         // else arg.toString();
   4626         static final char STRING              = 's';
   4627         static final char STRING_UPPER        = 'S';
   4628         // arg.hashCode()
   4629         static final char HASHCODE            = 'h';
   4630         static final char HASHCODE_UPPER      = 'H';
   4631 
   4632         static final char LINE_SEPARATOR      = 'n';
   4633         static final char PERCENT_SIGN        = '%';
   4634 
   4635         static boolean isValid(char c) {
   4636             return (isGeneral(c) || isInteger(c) || isFloat(c) || isText(c)
   4637                     || c == 't' || isCharacter(c));
   4638         }
   4639 
   4640         // Returns true iff the Conversion is applicable to all objects.
   4641         static boolean isGeneral(char c) {
   4642             switch (c) {
   4643             case BOOLEAN:
   4644             case BOOLEAN_UPPER:
   4645             case STRING:
   4646             case STRING_UPPER:
   4647             case HASHCODE:
   4648             case HASHCODE_UPPER:
   4649                 return true;
   4650             default:
   4651                 return false;
   4652             }
   4653         }
   4654 
   4655         // Returns true iff the Conversion is applicable to character.
   4656         static boolean isCharacter(char c) {
   4657             switch (c) {
   4658             case CHARACTER:
   4659             case CHARACTER_UPPER:
   4660                 return true;
   4661             default:
   4662                 return false;
   4663             }
   4664         }
   4665 
   4666         // Returns true iff the Conversion is an integer type.
   4667         static boolean isInteger(char c) {
   4668             switch (c) {
   4669             case DECIMAL_INTEGER:
   4670             case OCTAL_INTEGER:
   4671             case HEXADECIMAL_INTEGER:
   4672             case HEXADECIMAL_INTEGER_UPPER:
   4673                 return true;
   4674             default:
   4675                 return false;
   4676             }
   4677         }
   4678 
   4679         // Returns true iff the Conversion is a floating-point type.
   4680         static boolean isFloat(char c) {
   4681             switch (c) {
   4682             case SCIENTIFIC:
   4683             case SCIENTIFIC_UPPER:
   4684             case GENERAL:
   4685             case GENERAL_UPPER:
   4686             case DECIMAL_FLOAT:
   4687             case HEXADECIMAL_FLOAT:
   4688             case HEXADECIMAL_FLOAT_UPPER:
   4689                 return true;
   4690             default:
   4691                 return false;
   4692             }
   4693         }
   4694 
   4695         // Returns true iff the Conversion does not require an argument
   4696         static boolean isText(char c) {
   4697             switch (c) {
   4698             case LINE_SEPARATOR:
   4699             case PERCENT_SIGN:
   4700                 return true;
   4701             default:
   4702                 return false;
   4703             }
   4704         }
   4705     }
   4706 
   4707     private static class DateTime {
   4708         static final char HOUR_OF_DAY_0 = 'H'; // (00 - 23)
   4709         static final char HOUR_0        = 'I'; // (01 - 12)
   4710         static final char HOUR_OF_DAY   = 'k'; // (0 - 23) -- like H
   4711         static final char HOUR          = 'l'; // (1 - 12) -- like I
   4712         static final char MINUTE        = 'M'; // (00 - 59)
   4713         static final char NANOSECOND    = 'N'; // (000000000 - 999999999)
   4714         static final char MILLISECOND   = 'L'; // jdk, not in gnu (000 - 999)
   4715         static final char MILLISECOND_SINCE_EPOCH = 'Q'; // (0 - 99...?)
   4716         static final char AM_PM         = 'p'; // (am or pm)
   4717         static final char SECONDS_SINCE_EPOCH = 's'; // (0 - 99...?)
   4718         static final char SECOND        = 'S'; // (00 - 60 - leap second)
   4719         static final char TIME          = 'T'; // (24 hour hh:mm:ss)
   4720         static final char ZONE_NUMERIC  = 'z'; // (-1200 - +1200) - ls minus?
   4721         static final char ZONE          = 'Z'; // (symbol)
   4722 
   4723         // Date
   4724         static final char NAME_OF_DAY_ABBREV    = 'a'; // 'a'
   4725         static final char NAME_OF_DAY           = 'A'; // 'A'
   4726         static final char NAME_OF_MONTH_ABBREV  = 'b'; // 'b'
   4727         static final char NAME_OF_MONTH         = 'B'; // 'B'
   4728         static final char CENTURY               = 'C'; // (00 - 99)
   4729         static final char DAY_OF_MONTH_0        = 'd'; // (01 - 31)
   4730         static final char DAY_OF_MONTH          = 'e'; // (1 - 31) -- like d
   4731 // *    static final char ISO_WEEK_OF_YEAR_2    = 'g'; // cross %y %V
   4732 // *    static final char ISO_WEEK_OF_YEAR_4    = 'G'; // cross %Y %V
   4733         static final char NAME_OF_MONTH_ABBREV_X  = 'h'; // -- same b
   4734         static final char DAY_OF_YEAR           = 'j'; // (001 - 366)
   4735         static final char MONTH                 = 'm'; // (01 - 12)
   4736 // *    static final char DAY_OF_WEEK_1         = 'u'; // (1 - 7) Monday
   4737 // *    static final char WEEK_OF_YEAR_SUNDAY   = 'U'; // (0 - 53) Sunday+
   4738 // *    static final char WEEK_OF_YEAR_MONDAY_01 = 'V'; // (01 - 53) Monday+
   4739 // *    static final char DAY_OF_WEEK_0         = 'w'; // (0 - 6) Sunday
   4740 // *    static final char WEEK_OF_YEAR_MONDAY   = 'W'; // (00 - 53) Monday
   4741         static final char YEAR_2                = 'y'; // (00 - 99)
   4742         static final char YEAR_4                = 'Y'; // (0000 - 9999)
   4743 
   4744         // Composites
   4745         static final char TIME_12_HOUR  = 'r'; // (hh:mm:ss [AP]M)
   4746         static final char TIME_24_HOUR  = 'R'; // (hh:mm same as %H:%M)
   4747 // *    static final char LOCALE_TIME   = 'X'; // (%H:%M:%S) - parse format?
   4748         static final char DATE_TIME             = 'c';
   4749                                             // (Sat Nov 04 12:02:33 EST 1999)
   4750         static final char DATE                  = 'D'; // (mm/dd/yy)
   4751         static final char ISO_STANDARD_DATE     = 'F'; // (%Y-%m-%d)
   4752 // *    static final char LOCALE_DATE           = 'x'; // (mm/dd/yy)
   4753 
   4754         static boolean isValid(char c) {
   4755             switch (c) {
   4756             case HOUR_OF_DAY_0:
   4757             case HOUR_0:
   4758             case HOUR_OF_DAY:
   4759             case HOUR:
   4760             case MINUTE:
   4761             case NANOSECOND:
   4762             case MILLISECOND:
   4763             case MILLISECOND_SINCE_EPOCH:
   4764             case AM_PM:
   4765             case SECONDS_SINCE_EPOCH:
   4766             case SECOND:
   4767             case TIME:
   4768             case ZONE_NUMERIC:
   4769             case ZONE:
   4770 
   4771             // Date
   4772             case NAME_OF_DAY_ABBREV:
   4773             case NAME_OF_DAY:
   4774             case NAME_OF_MONTH_ABBREV:
   4775             case NAME_OF_MONTH:
   4776             case CENTURY:
   4777             case DAY_OF_MONTH_0:
   4778             case DAY_OF_MONTH:
   4779 // *        case ISO_WEEK_OF_YEAR_2:
   4780 // *        case ISO_WEEK_OF_YEAR_4:
   4781             case NAME_OF_MONTH_ABBREV_X:
   4782             case DAY_OF_YEAR:
   4783             case MONTH:
   4784 // *        case DAY_OF_WEEK_1:
   4785 // *        case WEEK_OF_YEAR_SUNDAY:
   4786 // *        case WEEK_OF_YEAR_MONDAY_01:
   4787 // *        case DAY_OF_WEEK_0:
   4788 // *        case WEEK_OF_YEAR_MONDAY:
   4789             case YEAR_2:
   4790             case YEAR_4:
   4791 
   4792             // Composites
   4793             case TIME_12_HOUR:
   4794             case TIME_24_HOUR:
   4795 // *        case LOCALE_TIME:
   4796             case DATE_TIME:
   4797             case DATE:
   4798             case ISO_STANDARD_DATE:
   4799 // *        case LOCALE_DATE:
   4800                 return true;
   4801             default:
   4802                 return false;
   4803             }
   4804         }
   4805     }
   4806 }
   4807