1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Licensed to the Apache Software Foundation (ASF) under one or more 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership. 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License. You may obtain a copy of the License at 72c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 92c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.util; 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.BufferedWriter; 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Closeable; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.File; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FileNotFoundException; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.FileOutputStream; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.Flushable; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.OutputStream; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.OutputStreamWriter; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintStream; 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.UnsupportedEncodingException; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.math.BigDecimal; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.math.BigInteger; 313819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilsonimport java.math.MathContext; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.nio.charset.Charset; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.AccessController; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.PrivilegedAction; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.DateFormatSymbols; 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.DecimalFormat; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.DecimalFormatSymbols; 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.text.NumberFormat; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor// BEGIN android-added 41bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnorimport org.apache.harmony.luni.util.LocaleCache; 42bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor// END android-added 43bb3b16f46964155b9ceead25db1c0e3841ce61a7Dan Egnor 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 45612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Formats arguments according to a format string (like {@code printf} in C). 46612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 47612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * It's relatively rare to use a {@code Formatter} directly. A variety of classes offer convenience 48612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * methods for accessing formatter functionality. 490c7c39cce1c6f052cd2afa4fc1ad99de70b37dd6Elliott Hughes * Of these, {@link String#format} is generally the most useful. 500c7c39cce1c6f052cd2afa4fc1ad99de70b37dd6Elliott Hughes * {@link java.io.PrintStream} and {@link java.io.PrintWriter} both offer 510c7c39cce1c6f052cd2afa4fc1ad99de70b37dd6Elliott Hughes * {@code format} and {@code printf} methods. 52612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 53612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Format strings</i> consist of plain text interspersed with format specifiers, such 54612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * as {@code "name: %s weight: %03dkg\n"}. Being a Java string, the usual Java string literal 55612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * backslash escapes are of course available. 56612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 57612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Format specifiers</i> (such as {@code "%s"} or {@code "%03d"} in the example) start with a 58612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code %} and describe how to format their corresponding argument. It includes an optional 59612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * argument index, optional flags, an optional width, an optional precision, and a mandatory 60612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * conversion type. 61612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * In the example, {@code "%s"} has no flags, no width, and no precision, while 62612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code "%03d"} has the flag {@code 0}, the width 3, and no precision. 63612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 64612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Not all combinations of argument index, flags, width, precision, and conversion type 65612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * are valid. 66612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 67612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Argument index</i>. Normally, each format specifier consumes the next argument to 68612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code format}. 69612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * For convenient localization, it's possible to reorder arguments so that they appear in a 70612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * different order in the output than the order in which they were supplied. 71612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * For example, {@code "%4$s"} formats the fourth argument ({@code 4$}) as a string ({@code s}). 72612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * It's also possible to reuse an argument with {@code <}. For example, 73612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code format("%o %<d %<x", 64)} results in {@code "100 64 40"}. 74612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 75612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Flags</i>. The available flags are: 76612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY=""> 78612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> <TD COLSPAN=4> <B>Flags</B> </TD> </tr> 79612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 80612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code ,}</td> 81612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Use grouping separators for large numbers. (Decimal only.)</td> 82612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%,d", 1024);}</td> 83612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 1,234}</td> 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 86612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code +}</td> 87612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Always show sign. (Decimal only.)</td> 88612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%+d, %+4d", 5, 5);}</td> 89612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"><pre>+5, +5</pre></td> 903819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 92612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code }</td> 93612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">A space indicates that non-negative numbers 94612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * should have a leading space. (Decimal only.)</td> 95612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("x% d% 5d", 4, 4);}</td> 96612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"><pre>x 4 4</pre></td> 973819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 99612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code (}</td> 100612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Put parentheses around negative numbers. (Decimal only.)</td> 101612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%(d, %(d, %(6d", 12, -12, -12);}</td> 102612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"><pre>12, (12), (12)</pre></td> 1033819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 105612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code -}</td> 106612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Left-justify. (Requires width.)</td> 107612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%-6dx", 5);}<br/>{@code format("%-3C, %3C", 'd', 0x65);}</td> 108612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"><pre>5 x</pre><br/><pre>D , E</pre></td> 1093819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 110612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 111612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code 0}</td> 112612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Pad the number with leading zeros. (Requires width.)</td> 113612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%07d, %03d", 4, 5555);}</td> 114612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 0000004, 5555}</td> 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 117612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code #}</td> 118612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Alternate form. (Octal and hex only.) </td> 119612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%o %#o", 010, 010);}<br/>{@code format("%x %#x", 0x12, 0x12);}</td> 120612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 10 010}<br/>{@code 12 0x12}</td> 1213819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 122612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </table> 123612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 124612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Width</i>. The width is a decimal integer specifying the minimum number of characters to be 125612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * used to represent the argument. If the result would otherwise be shorter than the width, padding 126612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * will be added (the exact details of which depend on the flags). Note that you can't use width to 127612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * truncate a field, only to make it wider: see precision for control over the maximum width. 128612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 129612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Precision</i>. The precision is a {@code .} followed by a decimal integer, giving the minimum 130612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * number of digits for {@code d}, {@code o}, {@code x}, or {@code X}; the minimum number of digits 131612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * after the decimal point for {@code a}, {@code A}, {@code e}, {@code E}, {@code f}, or {@code F}; 132612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * the maximum number of significant digits for {@code g} or {@code G}; or the maximum number of 133612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * characters for {@code s} or {@code S}. 134612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 135612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <i>Conversion type</i>. One or two characters describing how to interpret the argument. Most 136612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * conversions are a single character, but date/time conversions all start with {@code t} and 137612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * have a single extra character describing the desired output. 138612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 139612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Many conversion types have a corresponding uppercase variant that converts its result to 140612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * uppercase using the rules of the relevant locale (either the default or the locale set for 141612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * this formatter). 142612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 143612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * This table shows the available single-character (non-date/time) conversion types: 144612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY=""> 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <TD COLSPAN=4> 147612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <B>String conversions</B> 148612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 149612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * All types are acceptable arguments. Values of type {@link Formattable} have their 150612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code formatTo} method invoked; all other types use {@code toString}. 151612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 154612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code s}</td> 155612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">String.</td> 156612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%s %s", "hello", "Hello");}</td> 157612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code hello Hello}</td> 1583819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 160612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code S}</td> 161612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Uppercase string.</td> 162612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%S %S", "hello", "Hello");}</td> 163612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code HELLO HELLO}</td> 1643819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <TD COLSPAN=4> 167612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <B>Character conversions</B> 168612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 169612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Byte, Character, Short, and Integer (and primitives that box to those types) are all acceptable 170612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * as character arguments. Any other type is an error. 171612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 174612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code c}</td> 175612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Character.</td> 176612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%c %c", 'd', 'E');}</td> 177612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code d E}</td> 1783819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 180612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code C}</td> 181612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Uppercase character.</td> 182612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%C %C", 'd', 'E');}</td> 183612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code D E}</td> 1843819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 185612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 186612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <TD COLSPAN=4> 187612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <B>Integer conversions</B> 188612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 189612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Byte, Short, Integer, Long, and BigInteger (and primitives that box to those types) are all 190612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * acceptable as integer arguments. Any other type is an error. 191612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 1923819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 194612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code d}</td> 195612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Decimal.</td> 196612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%d", 26);}</td> 197612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 26}</td> 1983819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 200612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code o}</td> 201612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Octal.</td> 202612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%o", 032);}</td> 203612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 32}</td> 2043819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 206612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code x}, {@code X}</td> 207612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Hexadecimal.</td> 208612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%x %X", 0x1a, 0x1a);}</td> 209612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 1a 1A}</td> 2103819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 212612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <TD COLSPAN=4><B>Floating-point conversions</B> 213612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 214612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Float, Double, and BigDecimal (and primitives that box to those types) are all acceptable as 215612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * floating-point arguments. Any other type is an error. 216612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 2193819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * <td width="5%">{@code f}</td> 220612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Decimal floating point.</td> 221612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"><pre> 222612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%f", 123.456f); 223612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%.1f", 123.456f); 224612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%1.5f", 123.456f); 225612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%10f", 123.456f); 226612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%6.0f", 123.456f);</td> 227612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%" valign="top"><pre> 228612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes123.456001 229612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes123.5 230612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes123.45600 231612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes123.456001 232612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes 123</pre></td> 2333819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 235612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code e}, {@code E}</td> 236612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Engineering/exponential floating point.</td> 237612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"><pre> 238612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%e", 123.456f); 239612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%.1e", 123.456f); 240612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%1.5E", 123.456f); 241612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%10E", 123.456f); 242612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughesformat("%6.0E", 123.456f);</td> 243612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%" valign="top"><pre> 244612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes1.234560e+02 245612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes1.2e+02 246612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes1.23456E+02 247612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes1.234560E+02 248612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes 1E+02</pre></td> 2493819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 251612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%" valign="top">{@code g}, {@code G}</td> 252612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%" valign="top">Decimal or engineering, depending on the magnitude of the value.</td> 253612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%" valign="top">{@code format("%g %g", 0.123, 0.0000123);}</td> 254612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%" valign="top">{@code 0.123000 1.23000e-05}</td> 2553819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 257612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code a}, {@code A}</td> 258612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Hexadecimal floating point.</td> 259612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%a", 123.456f);}</td> 260612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 0x1.edd2f2p6}</td> 2613819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <TD COLSPAN=4> 264612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <B>Boolean conversion</B> 265612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 266612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Accepts Boolean values. {@code null} is considered false, and instances of all other 267612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * types are considered true. 268612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 271612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code b}, {@code B}</td> 272612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Boolean.</td> 273612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%b %b", true, false);}<br>{@code format("%B %B", true, false);}<br>{@code format("%b", null);}<br>{@code format("%b", "hello");}</td> 274612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code true false}<br>{@code TRUE FALSE}<br>{@code false}<br>{@code true}</td> 2753819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <TD COLSPAN=4> 278612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <B>Hash code conversion</B> 279612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 280612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Invokes {@code hashCode} on its argument, which may be of any type. 281612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 284612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code h}, {@code H}</td> 285612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Hexadecimal hash code.</td> 286612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%h", this);}<br>{@code format("%H", this);}<br>{@code format("%h", null);}</td> 287612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 190d11}<br>{@code 190D11}<br>{@code null}</td> 2883819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <TD COLSPAN=4> 291612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <B>Zero-argument conversions</B></TD> 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 294612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code %}</td> 295612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">A literal % character.</td> 296612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%d%%", 50);}</td> 297612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 50%}</td> 2983819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 300612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code n}</td> 301612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Newline. (The value of the system property {@code "line.separator"}.)</td> 302612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("first%nsecond");}</td> 303612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code first\nsecond}</td> 304612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 305612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </table> 306612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 307612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * It's also possible to format dates and times with {@code Formatter}, though you should seriously 30845071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * consider using {@link java.text.SimpleDateFormat} via the factory methods in 30945071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * {@link java.text.DateFormat} instead. 310612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * The facilities offered by {@code Formatter} are low-level and place the burden of localization 31145071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * on the developer. Using {@link java.text.DateFormat#getDateInstance}, 31245071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * {@link java.text.DateFormat#getTimeInstance}, and 31345071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * {@link java.text.DateFormat#getDateTimeInstance} is preferable for dates and times that will be 314612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * presented to a human. Those methods will select the best format strings for the user's locale. 315612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 316612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * The best non-localized form is <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>, 317612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * which you can get with {@code "%tF"} (2010-01-22), {@code "%tF %tR"} (2010-01-22 13:39), 318612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code "%tF %tT"} (2010-01-22 13:39:15), or {@code "%tF %tT%z"} (2010-01-22 13:39:15-0800). 319612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 320612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * As with the other conversions, date/time conversion has an uppercase format. Replacing 321612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * {@code %t} with {@code %T} will uppercase the field according to the rules of the formatter's 322612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * locale. 323612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 324612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * This table shows the date/time conversions: 325612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY=""> 326612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 327612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <TD COLSPAN=4><B>Date/time conversions</B> 328612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <br> 329612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Calendar, Date, and Long (representing milliseconds past the epoch) are all acceptable 330612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * as date/time arguments. Any other type is an error. The epoch is 1970-01-01 00:00:00 UTC. 331612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </TD> 3323819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 334612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code ta}</td> 335612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Localized weekday name (abbreviated).</td> 336612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%ta", cal, cal);}</td> 337612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code Tue}</td> 338612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 339612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 340612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tA}</td> 341612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Localized weekday name (full).</td> 342612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tA", cal, cal);}</td> 343612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code Tuesday}</td> 344612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 345612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 346612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tb}</td> 347612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Localized month name (abbreviated).</td> 348612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tb", cal);}</td> 349612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code Apr}</td> 350612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 351612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 352612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tB}</td> 353612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Localized month name (full).</td> 354612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tB", cal);}</td> 355612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code April}</td> 356612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 357612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 358612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tc}</td> 35945071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * <td width="25%">Locale-preferred date and time representation. (See {@link java.text.DateFormat} for more variations.)</td> 360612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tc", cal);}</td> 361612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code Tue Apr 01 16:19:17 CEST 2008}</td> 362612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 363612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 364612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tC}</td> 365612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">2-digit century.</td> 366612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tC", cal);}</td> 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <td width="30%">{@code 20}</td> 3683819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 370612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code td}</td> 371612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">2-digit day of month (01-31).</td> 372612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%td", cal);}</td> 373612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 01}</td> 374612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 375612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 376612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tD}</td> 377612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Ambiguous US date format (MM/DD/YY). Do not use.</td> 378612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tD", cal);}</td> 379612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 04/01/08}</td> 380612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 381612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 382612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code te}</td> 383612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Day of month (1-31).</td> 384612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%te", cal);}</td> 385612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 1}</td> 3863819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 388612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tF}</td> 389612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Full date in ISO 8601 format (YYYY-MM-DD).</td> 3903819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * <td width="30%">{@code format("%tF", cal);}</td> 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <td width="30%">{@code 2008-04-01}</td> 3923819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 394612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code th}</td> 395612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Synonym for {@code %tb}.</td> 396612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"></td> 397612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%"></td> 3983819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 400612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tH}</td> 401612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">24-hour hour of day (00-23).</td> 402612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tH", cal);}</td> 403612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 16}</td> 404612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 405612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 406612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tI}</td> 407612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">12-hour hour of day (01-12).</td> 408612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tH", cal);}</td> 409612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 04}</td> 410612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 411612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 412612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tj}</td> 413612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">3-digit day of year (001-366).</td> 414612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tj", cal);}</td> 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <td width="30%">{@code 092}</td> 4163819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 418612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tk}</td> 419612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">24-hour hour of day (0-23).</td> 420612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tH", cal);}</td> 421612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 16}</td> 422612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 423612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 424612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tl}</td> 425612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">12-hour hour of day (1-12).</td> 426612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tH", cal);}</td> 427612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 4}</td> 428612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 429612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 430612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tL}</td> 431612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Milliseconds.</td> 432612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tL", cal);}</td> 433612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 359}</td> 434612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * </tr> 435612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 436612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tm}</td> 437612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">2-digit month of year (01-12).</td> 438612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tm", cal);}</td> 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <td width="30%">{@code 04}</td> 4403819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 442612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tM}</td> 443612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">2-digit minute.</td> 444612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tM", cal);}</td> 445612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 08}</td> 4463819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 448612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tN}</td> 449612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Nanoseconds.</td> 450612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tN", cal);}</td> 451612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 359000000}</td> 4523819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 454612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tp}</td> 455612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">a.m. or p.m.</td> 4563819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * <td width="30%">{@code format("%tp %Tp", cal, cal);}</td> 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <td width="30%">{@code pm PM}</td> 4583819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 460612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tQ}</td> 461612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Milliseconds since the epoch.</td> 462612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tQ", cal);}</td> 463612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 1207059412656}</td> 4643819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 466612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tr}</td> 467612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Full 12-hour time ({@code %tI:%tM:%tS %Tp}).</td> 468612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tr", cal);}</td> 469612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 04:15:32 PM}</td> 4703819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 472612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tR}</td> 473612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Short 24-hour time ({@code %tH:%tM}).</td> 474612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tR", cal);}</td> 475612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 16:15}</td> 4763819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 478612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code ts}</td> 479612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Seconds since the epoch.</td> 480612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%ts", cal);}</td> 481612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 1207059412}</td> 4823819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 484612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tS}</td> 485612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">2-digit seconds (00-60).</td> 486612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tS", cal);}</td> 487612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 17}</td> 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 490612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tT}</td> 491612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Full 24-hour time ({@code %tH:%tM:%tS}).</td> 492612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tT", cal);}</td> 493612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 16:15:32}</td> 4943819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 496612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code ty}</td> 497612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">2-digit year (00-99).</td> 498612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%ty", cal);}</td> 499612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 08}</td> 5003819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 502612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tY}</td> 503612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">4-digit year.</td> 504612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tY", cal);}</td> 505612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code 2008}</td> 5063819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 507612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <tr> 508612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tz}</td> 509612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Time zone GMT offset.</td> 510612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tz", cal);}</td> 511612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code +0100}</td> 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * </tr> 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <tr> 514612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="5%">{@code tZ}</td> 515612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="25%">Localized time zone abbreviation.</td> 516612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code format("%tZ", cal);}</td> 517612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <td width="30%">{@code CEST}</td> 5183819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </tr> 5193819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * </table> 520612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * <p> 521612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Formatter is not thread-safe. 5223819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 5233819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * @since 1.5 52445071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * @see java.text.DateFormat 525612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * @see Formattable 52645071dd09330c9399735b13c81f8d75e4c6bfa0dElliott Hughes * @see java.text.SimpleDateFormat 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class Formatter implements Closeable, Flushable { 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The enumeration giving the available styles for formatting very large 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * decimal numbers. 5333819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson */ 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public enum BigDecimalLayoutForm { 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use scientific style for BigDecimals. 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 5383819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson SCIENTIFIC, 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Use normal decimal/float style for BigDecimals. 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DECIMAL_FLOAT 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Appendable out; 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Locale locale; 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private boolean closed = false; 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private IOException lastIOException; 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter}. 5553819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The output is written to a {@code StringBuilder} which can be acquired by invoking 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #out()} and whose content can be obtained by calling 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code toString()}. 5593819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter() { 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new StringBuilder(), Locale.getDefault()); 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5673819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} whose output will be written to the 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified {@code Appendable}. 5693819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The locale for the {@code Formatter} is the default {@code Locale}. 5713819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param a 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the output destination of the {@code Formatter}. If {@code a} is {@code null}, 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then a {@code StringBuilder} will be used. 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(Appendable a) { 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(a, Locale.getDefault()); 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter} with the specified {@code Locale}. 5823819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The output is written to a {@code StringBuilder} which can be acquired by invoking 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@link #out()} and whose content can be obtained by calling 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code toString()}. 5863819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param l 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null}, 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then no localization will be used. 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(Locale l) { 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new StringBuilder(), l); 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5963819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} with the specified {@code Locale} 5973819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * and whose output will be written to the 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * specified {@code Appendable}. 5993819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param a 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the output destination of the {@code Formatter}. If {@code a} is {@code null}, 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then a {@code StringBuilder} will be used. 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param l 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null}, 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then no localization will be used. 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(Appendable a, Locale l) { 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == a) { 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out = new StringBuilder(); 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out = a; 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project locale = l; 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter} whose output is written to the specified file. 6183819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The charset of the {@code Formatter} is the default charset. 6203819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 6223819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param fileName 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the filename of the file that is used as the output 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination for the {@code Formatter}. The file will be truncated to 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * zero size if the file exists, or else a new file will be 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * created. The output of the {@code Formatter} is buffered. 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FileNotFoundException 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the filename does not denote a normal and writable file, 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or if a new file cannot be created, or if any error arises when 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * opening or creating the file. 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SecurityException 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if there is a {@code SecurityManager} in place which denies permission 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to write to the file in {@code checkWrite(file.getPath())}. 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(String fileName) throws FileNotFoundException { 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new File(fileName)); 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter} whose output is written to the specified file. 6433819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 6453819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param fileName 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the filename of the file that is used as the output 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination for the {@code Formatter}. The file will be truncated to 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * zero size if the file exists, or else a new file will be 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * created. The output of the {@code Formatter} is buffered. 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param csn 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the charset for the {@code Formatter}. 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FileNotFoundException 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the filename does not denote a normal and writable file, 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or if a new file cannot be created, or if any error arises when 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * opening or creating the file. 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SecurityException 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if there is a {@code SecurityManager} in place which denies permission 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to write to the file in {@code checkWrite(file.getPath())}. 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws UnsupportedEncodingException 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the charset with the specified name is not supported. 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(String fileName, String csn) throws FileNotFoundException, 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UnsupportedEncodingException { 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new File(fileName), csn); 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 6693819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} with the given {@code Locale} and charset, 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and whose output is written to the specified file. 6713819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param fileName 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the filename of the file that is used as the output 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination for the {@code Formatter}. The file will be truncated to 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * zero size if the file exists, or else a new file will be 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * created. The output of the {@code Formatter} is buffered. 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param csn 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the charset for the {@code Formatter}. 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param l 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null}, 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then no localization will be used. 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FileNotFoundException 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the filename does not denote a normal and writable file, 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * or if a new file cannot be created, or if any error arises when 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * opening or creating the file. 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SecurityException 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if there is a {@code SecurityManager} in place which denies permission 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to write to the file in {@code checkWrite(file.getPath())}. 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws UnsupportedEncodingException 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the charset with the specified name is not supported. 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(String fileName, String csn, Locale l) 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws FileNotFoundException, UnsupportedEncodingException { 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new File(fileName), csn, l); 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter} whose output is written to the specified {@code File}. 7003819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The charset of the {@code Formatter} is the default charset. 7023819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 7043819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param file 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code File} that is used as the output destination for the 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File} 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exists, or else a new {@code File} will be created. The output of the 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter} is buffered. 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FileNotFoundException 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code File} is not a normal and writable {@code File}, or if a 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new {@code File} cannot be created, or if any error rises when opening or 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * creating the {@code File}. 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SecurityException 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if there is a {@code SecurityManager} in place which denies permission 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to write to the {@code File} in {@code checkWrite(file.getPath())}. 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(File file) throws FileNotFoundException { 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(new FileOutputStream(file)); 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 7233819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} with the given charset, 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and whose output is written to the specified {@code File}. 7253819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 7273819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param file 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code File} that is used as the output destination for the 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File} 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exists, or else a new {@code File} will be created. The output of the 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter} is buffered. 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param csn 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the charset for the {@code Formatter}. 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FileNotFoundException 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code File} is not a normal and writable {@code File}, or if a 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new {@code File} cannot be created, or if any error rises when opening or 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * creating the {@code File}. 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SecurityException 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if there is a {@code SecurityManager} in place which denies permission 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to write to the {@code File} in {@code checkWrite(file.getPath())}. 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws UnsupportedEncodingException 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the charset with the specified name is not supported. 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(File file, String csn) throws FileNotFoundException, 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UnsupportedEncodingException { 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(file, csn, Locale.getDefault()); 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 7513819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} with the given {@code Locale} and charset, 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and whose output is written to the specified {@code File}. 7533819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param file 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code File} that is used as the output destination for the 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter}. The {@code File} will be truncated to zero size if the {@code File} 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * exists, or else a new {@code File} will be created. The output of the 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter} is buffered. 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param csn 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the charset for the {@code Formatter}. 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param l 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null}, 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then no localization will be used. 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FileNotFoundException 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code File} is not a normal and writable {@code File}, or if a 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * new {@code File} cannot be created, or if any error rises when opening or 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * creating the {@code File}. 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws SecurityException 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if there is a {@code SecurityManager} in place which denies permission 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to write to the {@code File} in {@code checkWrite(file.getPath())}. 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws UnsupportedEncodingException 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the charset with the specified name is not supported. 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(File file, String csn, Locale l) 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws FileNotFoundException, UnsupportedEncodingException { 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FileOutputStream fout = null; 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fout = new FileOutputStream(file); 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStreamWriter writer = new OutputStreamWriter(fout, csn); 7803819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // BEGIN android-changed 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out = new BufferedWriter(writer, 8192); 7823819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // END android-changed 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (RuntimeException e) { 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closeOutputStream(fout); 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw e; 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (UnsupportedEncodingException e) { 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project closeOutputStream(fout); 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw e; 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project locale = l; 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter} whose output is written to the specified {@code OutputStream}. 7963819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The charset of the {@code Formatter} is the default charset. 7983819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 8003819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param os 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the stream to be used as the destination of the {@code Formatter}. 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(OutputStream os) { 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStreamWriter writer = new OutputStreamWriter(os, Charset 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .defaultCharset()); 8073819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // BEGIN android-changed 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out = new BufferedWriter(writer, 8192); 8093819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // END android-changed 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project locale = Locale.getDefault(); 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 8143819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} with the given charset, 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and whose output is written to the specified {@code OutputStream}. 8163819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 8183819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param os 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the stream to be used as the destination of the {@code Formatter}. 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param csn 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the charset for the {@code Formatter}. 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws UnsupportedEncodingException 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the charset with the specified name is not supported. 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(OutputStream os, String csn) 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws UnsupportedEncodingException { 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this(os, csn, Locale.getDefault()); 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 8333819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * Constructs a {@code Formatter} with the given {@code Locale} and charset, 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and whose output is written to the specified {@code OutputStream}. 8353819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param os 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the stream to be used as the destination of the {@code Formatter}. 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param csn 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the name of the charset for the {@code Formatter}. 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param l 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code Locale} of the {@code Formatter}. If {@code l} is {@code null}, 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then no localization will be used. 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws UnsupportedEncodingException 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the charset with the specified name is not supported. 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(OutputStream os, String csn, Locale l) 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throws UnsupportedEncodingException { 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project OutputStreamWriter writer = new OutputStreamWriter(os, csn); 8503819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // BEGIN android-changed 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out = new BufferedWriter(writer, 8192); 8523819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // END android-changed 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project locale = l; 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a {@code Formatter} whose output is written to the specified {@code PrintStream}. 8593819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The charset of the {@code Formatter} is the default charset. 8613819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The {@code Locale} for the {@code Formatter} is the default {@code Locale}. 8633819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param ps 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code PrintStream} used as destination of the {@code Formatter}. If 8663819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * {@code ps} is {@code null}, then a {@code NullPointerException} will 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be raised. 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter(PrintStream ps) { 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == ps) { 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new NullPointerException(); 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out = ps; 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project locale = Locale.getDefault(); 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void checkClosed() { 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (closed) { 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new FormatterClosedException(); 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the {@code Locale} of the {@code Formatter}. 8853819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the {@code Locale} for the {@code Formatter} or {@code null} for no {@code Locale}. 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FormatterClosedException 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code Formatter} has been closed. 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Locale locale() { 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkClosed(); 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return locale; 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the output destination of the {@code Formatter}. 8973819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the output destination of the {@code Formatter}. 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FormatterClosedException 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code Formatter} has been closed. 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Appendable out() { 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkClosed(); 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return out; 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the content by calling the {@code toString()} method of the output 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination. 9103819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the content by calling the {@code toString()} method of the output 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination. 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FormatterClosedException 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code Formatter} has been closed. 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String toString() { 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkClosed(); 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return out.toString(); 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Flushes the {@code Formatter}. If the output destination is {@link Flushable}, 9243819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * then the method {@code flush()} will be called on that destination. 9253819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FormatterClosedException 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code Formatter} has been closed. 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void flush() { 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkClosed(); 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (out instanceof Flushable) { 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((Flushable) out).flush(); 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastIOException = e; 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Closes the {@code Formatter}. If the output destination is {@link Closeable}, 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then the method {@code close()} will be called on that destination. 9433819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the {@code Formatter} has been closed, then calling the this method will have no 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * effect. 9463819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Any method but the {@link #ioException()} that is called after the 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code Formatter} has been closed will raise a {@code FormatterClosedException}. 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void close() { 9512c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (!closed) { 9522c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes closed = true; 9532c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes try { 9542c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (out instanceof Closeable) { 9552c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes ((Closeable) out).close(); 9562c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 9572c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } catch (IOException e) { 9582c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes lastIOException = e; 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the last {@code IOException} thrown by the {@code Formatter}'s output 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination. If the {@code append()} method of the destination does not throw 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code IOException}s, the {@code ioException()} method will always return {@code null}. 9673819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the last {@code IOException} thrown by the {@code Formatter}'s output 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * destination. 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public IOException ioException() { 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return lastIOException; 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes a formatted string to the output destination of the {@code Formatter}. 9773819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param format 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a format string. 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param args 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the arguments list used in the {@code format()} method. If there are 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * more arguments than those specified by the format string, then 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the additional arguments are ignored. 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this {@code Formatter}. 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalFormatException 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the format string is illegal or incompatible with the 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * arguments, or if fewer arguments are sent than those required by 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the format string, or any other illegal situation. 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FormatterClosedException 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code Formatter} has been closed. 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter format(String format, Object... args) { 993636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes // BEGIN android-changed 994636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes doFormat(format, args); 995636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes return this; 996636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes // END android-changed 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9993819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // BEGIN android-added 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Cached transformer. Improves performance when format() is called multiple 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * times. 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Transformer transformer; 10053819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson // END android-added 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Writes a formatted string to the output destination of the {@code Formatter}. 10093819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson * 1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param l 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the {@code Locale} used in the method. If {@code locale} is 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * {@code null}, then no localization will be applied. This 10132c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * parameter does not change this Formatter's default {@code Locale} 10142c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * as specified during construction, and only applies for the 10152c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * duration of this call. 1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param format 1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a format string. 1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param args 1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the arguments list used in the {@code format()} method. If there are 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * more arguments than those specified by the format string, then 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the additional arguments are ignored. 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return this {@code Formatter}. 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws IllegalFormatException 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the format string is illegal or incompatible with the 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * arguments, or if fewer arguments are sent than those required by 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the format string, or any other illegal situation. 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @throws FormatterClosedException 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if the {@code Formatter} has been closed. 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public Formatter format(Locale l, String format, Object... args) { 10312c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // BEGIN android-changed 10322c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes Locale originalLocale = locale; 10332c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes try { 10342c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes this.locale = l; 10352c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes doFormat(format, args); 10362c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } finally { 10372c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes this.locale = originalLocale; 10382c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 10392c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return this; 10402c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // END android-changed 10412c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 10422c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 10432c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // BEGIN android-changed 10442c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private void doFormat(String format, Object... args) { 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project checkClosed(); 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Reuse the previous transformer if the locale matches. 1048636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes if (transformer == null || !transformer.locale.equals(locale)) { 10492c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes transformer = new Transformer(this, locale); 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1052e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes FormatSpecifierParser fsp = new FormatSpecifierParser(format); 10532c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int currentObjectIndex = 0; 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object lastArgument = null; 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean hasLastArgumentSet = false; 10572c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 1058e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes int length = format.length(); 10592c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int i = 0; 10602c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes while (i < length) { 10612c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // Find the maximal plain-text sequence... 10622c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int plainTextStart = i; 1063e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes int nextPercent = format.indexOf('%', i); 1064e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes int plainTextEnd = (nextPercent == -1) ? length : nextPercent; 10652c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // ...and output it. 10662c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (plainTextEnd > plainTextStart) { 10672c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes outputCharSequence(format, plainTextStart, plainTextEnd); 10682c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 1069e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes i = plainTextEnd; 10702c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // Do we have a format specifier? 10712c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (i < length) { 1072e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes FormatToken token = fsp.parseFormatToken(i + 1); 1073f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object argument = null; 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (token.requireArgument()) { 10762c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int index = token.getArgIndex() == FormatToken.UNSET ? currentObjectIndex++ : token.getArgIndex(); 10772c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes argument = getArgument(args, index, fsp, lastArgument, hasLastArgumentSet); 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastArgument = argument; 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hasLastArgumentSet = true; 1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 10812c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 10822c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes CharSequence substitution = transformer.transform(token, argument); 1083636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes // The substitution is null if we called Formattable.formatTo. 10842c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (substitution != null) { 10852c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes outputCharSequence(substitution, 0, substitution.length()); 10862c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 10872c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes i = fsp.i; 1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 10912c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // END android-changed 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1093f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes // BEGIN android-added 1094f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes // Fixes http://code.google.com/p/android/issues/detail?id=1767. 10952c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private void outputCharSequence(CharSequence cs, int start, int end) { 10962c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes try { 10972c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes out.append(cs, start, end); 10982c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } catch (IOException e) { 10992c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes lastIOException = e; 1100f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes } 1101f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes } 1102f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes // END android-added 1103f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes 11042c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private Object getArgument(Object[] args, int index, FormatSpecifierParser fsp, 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Object lastArgument, boolean hasLastArgumentSet) { 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (index == FormatToken.LAST_ARGUMENT_INDEX && !hasLastArgumentSet) { 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new MissingFormatArgumentException("<"); //$NON-NLS-1$ 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == args) { 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (index >= args.length) { 11152c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes throw new MissingFormatArgumentException(fsp.getFormatSpecifierText()); 1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (index == FormatToken.LAST_ARGUMENT_INDEX) { 1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return lastArgument; 1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return args[index]; 1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static void closeOutputStream(OutputStream os) { 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == os) { 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project os.close(); 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException e) { 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // silently 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 113835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes * Complete details of a single format specifier parsed from a format string. 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class FormatToken { 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final int LAST_ARGUMENT_INDEX = -2; 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final int UNSET = -1; 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final int FLAGS_UNSET = 0; 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final int DEFAULT_PRECISION = 6; 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static final int FLAG_ZERO = 1 << 4; 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int argIndex = UNSET; 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // These have package access for performance. They used to be represented by an int bitmask 115435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // and accessed via methods, but Android's JIT doesn't yet do a good job of such code. 115535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // Direct field access, on the other hand, is fast. 115635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagAdd; 115735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagComma; 115835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagMinus; 115935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagParenthesis; 116035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagSharp; 116135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagSpace; 116235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean flagZero; 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes private char conversionType = (char) UNSET; 116535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes private char dateSuffix; 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int precision = UNSET; 116835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes private int width = UNSET; 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 11702c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private StringBuilder strFlags; 1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1172d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes // Tests whether there were no flags, no width, and no precision specified. 1173d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes boolean isDefault() { 117435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // TODO: call hasDefaultFlags when the JIT can inline it. 117535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return !flagAdd && !flagComma && !flagMinus && !flagParenthesis && !flagSharp && 117635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes !flagSpace && !flagZero && width == UNSET && precision == UNSET; 117735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 117835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes 117935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean hasDefaultFlags() { 118035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return !flagAdd && !flagComma && !flagMinus && !flagParenthesis && !flagSharp && 118135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes !flagSpace && !flagZero; 1182d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes } 1183d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean isPrecisionSet() { 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return precision != UNSET; 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean isWidthSet() { 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return width != UNSET; 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1192636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes boolean hasArg() { 1193636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes return argIndex != UNSET; 1194636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } 1195636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int getArgIndex() { 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return argIndex; 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void setArgIndex(int index) { 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project argIndex = index; 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int getWidth() { 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return width; 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void setWidth(int width) { 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.width = width; 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int getPrecision() { 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return precision; 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void setPrecision(int precise) { 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.precision = precise; 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String getStrFlags() { 12212c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return (strFlags != null) ? strFlags.toString() : ""; 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets qualified char as one of the flags. If the char is qualified, 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sets it as a flag and returns true. Or else returns false. 1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 122835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean setFlag(int ch) { 122935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean dupe = false; 123035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes switch (ch) { 123135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case '+': 123235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagAdd; 123335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagAdd = true; 123435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 123535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case ',': 123635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagComma; 123735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagComma = true; 123835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 123935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case '-': 124035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagMinus; 124135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagMinus = true; 124235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 124335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case '(': 124435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagParenthesis; 124535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagParenthesis = true; 124635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 124735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case '#': 124835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagSharp; 124935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagSharp = true; 125035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 125135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case ' ': 125235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagSpace; 125335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagSpace = true; 125435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 125535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes case '0': 125635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes dupe = flagZero; 125735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes flagZero = true; 125835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes break; 125935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes default: 126035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return false; 126135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 126235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (dupe) { 126335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new DuplicateFormatFlagsException(String.valueOf(ch)); 1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 12652c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (strFlags == null) { 126635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes strFlags = new StringBuilder(7); // There are seven possible flags. 12672c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 1268a3bd410b30ae944d5033537357a0c01a56461e4dElliott Hughes strFlags.append((char) ch); 1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char getConversionType() { 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return conversionType; 1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void setConversionType(char c) { 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project conversionType = c; 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char getDateSuffix() { 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dateSuffix; 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void setDateSuffix(char c) { 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dateSuffix = c; 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean requireArgument() { 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return conversionType != '%' && conversionType != 'n'; 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 129135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes 129235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes void checkMissingWidth() { 129335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (flagMinus && width == UNSET) { 129435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new MissingFormatWidthException("-" + conversionType); 129535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 129635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 129735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes 129835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes void ensureOnlyMinus() { 129935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (flagAdd || flagComma || flagParenthesis || flagSharp || flagSpace || flagZero) { 130035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(getStrFlags(), conversionType); 130135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 130235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 130335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes 130435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes void ensureNoPrecision() { 130535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (isPrecisionSet()) { 130635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new IllegalFormatPrecisionException(precision); 130735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 130835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms the argument to the formatted string according to the format 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * information contained in the format token. 1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class Transformer { 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Formatter formatter; 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private FormatToken formatToken; 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Object arg; 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Locale locale; 1320771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes private DecimalFormatSymbols decimalFormatSymbols; 1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static String lineSeparator; 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 13230dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor // BEGIN android-changed 1324771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes // This object is mutated during use, so can't be cached safely. 13250dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor // private NumberFormat numberFormat; 13260dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor // END android-changed 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private DateTimeUtil dateTimeUtil; 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Transformer(Formatter formatter, Locale locale) { 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.formatter = formatter; 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.locale = (null == locale ? Locale.US : locale); 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private NumberFormat getNumberFormat() { 13360dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor // BEGIN android-changed 13370dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor return LocaleCache.getNumberFormat(locale); 13380dfef7bc223f18a1372b4c44c822b9cdc5d5f741Dan Egnor // END android-changed 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1341771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes // BEGIN android-changed 1342771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes DecimalFormatSymbols getDecimalFormatSymbols() { 1343771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (decimalFormatSymbols == null) { 1344771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes decimalFormatSymbols = new DecimalFormatSymbols(locale); 1345771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes } 1346771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes return decimalFormatSymbols; 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1348771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes // END android-changed 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the formatted string according to the format token and the 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * argument. 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1354f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes CharSequence transform(FormatToken token, Object argument) { 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.formatToken = token; 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.arg = argument; 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1358d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes // There are only two format specifiers that matter: "%d" and "%s". 1359d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes // Nothing else is common in the wild. We fast-path these two to 1360dddc36885260b49e4bbde0f39d281f222f2fe77fElliott Hughes // avoid the heavyweight machinery needed to cope with flags, width, 1361dddc36885260b49e4bbde0f39d281f222f2fe77fElliott Hughes // and precision. 1362d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes if (token.isDefault()) { 1363d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes switch (token.getConversionType()) { 1364d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes case 's': 1365e2036b3a340e0d687d9bbdb500658ef4585545e2Elliott Hughes if (arg == null) { 1366e2036b3a340e0d687d9bbdb500658ef4585545e2Elliott Hughes return "null"; 1367e2036b3a340e0d687d9bbdb500658ef4585545e2Elliott Hughes } else if (!(arg instanceof Formattable)) { 1368d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes return arg.toString(); 1369d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes } 1370d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes break; 1371d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes case 'd': 1372d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes if (arg instanceof Integer || arg instanceof Long || arg instanceof Short || arg instanceof Byte) { 1373d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes // TODO: when we fix the rest of formatter to correctly use locale-specific 1374d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes // digits when getDecimalFormatSymbols().getZeroDigit() != '0', we'll need 1375d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes // to add a special case here too. 1376d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes return arg.toString(); 1377d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes } 1378d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes } 1379d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes } 1380d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes 1381f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes CharSequence result; 1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (token.getConversionType()) { 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'b': { 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromBoolean(); 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'H': 1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'h': { 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromHashCode(); 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 's': { 1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromString(); 1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'c': { 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromCharacter(); 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'd': 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'o': 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'x': 1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'X': { 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == arg || arg instanceof BigInteger) { 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromBigInteger(); 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromInteger(); 1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'e': 1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'E': 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'g': 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'G': 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'f': 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'a': 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'A': { 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromFloat(); 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case '%': { 1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromPercent(); 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'n': { 14293819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson result = transformFromLineSeparator(); 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 't': 1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'T': { 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = transformFromDateTime(); 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: { 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnknownFormatConversionException(String 1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .valueOf(token.getConversionType())); 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (Character.isUpperCase(token.getConversionType())) { 1444d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes if (result != null) { 14458cdf9790e869778b0ed3da7f149cb7c132a0f142Elliott Hughes result = result.toString().toUpperCase(locale); 1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 145135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes private IllegalFormatConversionException badArgumentType() { 145235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new IllegalFormatConversionException(formatToken.getConversionType(), 145335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes arg.getClass()); 145435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 145535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms the Boolean argument to a formatted string. 1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1459f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromBoolean() { 146035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.checkMissingWidth(); 146135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureOnlyMinus(); 14622c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes CharSequence result; 14632c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (arg instanceof Boolean) { 14642c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = arg.toString(); 14652c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else if (arg == null) { 14662c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = "false"; //$NON-NLS-1$ 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 14682c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = "true"; //$NON-NLS-1$ 1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 14702c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding(result, 0); 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1474612ae259a58d460574d21a13a0409c0f6f6f635fElliott Hughes * Transforms the hash code of the argument to a formatted string. 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1476f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromHashCode() { 147735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.checkMissingWidth(); 147835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureOnlyMinus(); 14792c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes CharSequence result; 14802c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (arg == null) { 14812c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = "null"; //$NON-NLS-1$ 1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 14832c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = Integer.toHexString(arg.hashCode()); 1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 14852c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding(result, 0); 1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms the String to a formatted string. 1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1491f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromString() { 149235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.checkMissingWidth(); 1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg instanceof Formattable) { 1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // only minus and sharp flag is valid 149535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd || formatToken.flagComma || formatToken.flagParenthesis || formatToken.flagSpace || formatToken.flagZero) { 1496636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 149835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes int flag = 0; 149935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus) { 1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flag |= FormattableFlags.LEFT_JUSTIFY; 1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 150235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp) { 1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flag |= FormattableFlags.ALTERNATE; 1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (Character.isUpperCase(formatToken.getConversionType())) { 1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project flag |= FormattableFlags.UPPERCASE; 1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 150835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes ((Formattable) arg).formatTo(formatter, flag, formatToken.getWidth(), 150935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.getPrecision()); 1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // all actions have been taken out in the 1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Formattable.formatTo, thus there is nothing to do, just 1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // returns null, which tells the Parser to add nothing to the 1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // output. 1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 151635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // only '-' is valid for flags if the argument is not an instance of Formattable 151735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureOnlyMinus(); 15182c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes CharSequence result = arg != null ? arg.toString() : "null"; 15192c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding(result, 0); 1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms the Character to a formatted string. 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1525f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromCharacter() { 152635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.checkMissingWidth(); 152735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureOnlyMinus(); 152835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureNoPrecision(); 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 15302c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (arg == null) { 153135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return padding("null", 0); 153235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 153335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (arg instanceof Character) { 153435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return padding(String.valueOf(arg), 0); 153535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else if (arg instanceof Byte || arg instanceof Short || arg instanceof Integer) { 153635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes int codePoint = ((Number) arg).intValue(); 153735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (!Character.isValidCodePoint(codePoint)) { 153835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new IllegalFormatCodePointException(codePoint); 153935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 154035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes CharSequence result = (codePoint < Character.MIN_SUPPLEMENTARY_CODE_POINT) 154135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes ? String.valueOf((char) codePoint) 154235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes : String.valueOf(Character.toChars(codePoint)); 154335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return padding(result, 0); 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 154535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw badArgumentType(); 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms percent to a formatted string. Only '-' is legal flag. 1551636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes * Precision and arguments are illegal. 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1553f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromPercent() { 155435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.checkMissingWidth(); 155535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureOnlyMinus(); 155635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureNoPrecision(); 1557636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes if (formatToken.hasArg()) { 1558636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1559636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } 15602c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding("%", 0); 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1564636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes * Transforms line separator to a formatted string. Any flag, width, 1565636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes * precision or argument is illegal. 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1567f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromLineSeparator() { 156835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureNoPrecision(); 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (formatToken.isWidthSet()) { 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatWidthException(formatToken.getWidth()); 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (!formatToken.hasDefaultFlags() || formatToken.hasArg()) { 1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1578636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes if (lineSeparator == null) { 1579636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes lineSeparator = AccessController.doPrivileged(new PrivilegedAction<String>() { 1580636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes public String run() { 1581636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes return System.getProperty("line.separator"); //$NON-NLS-1$ 1582636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } 1583636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes }); 1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return lineSeparator; 1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Pads characters to the formatted string. 1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 15912c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private CharSequence padding(CharSequence source, int startIndex) { 15922c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes boolean sourceIsStringBuilder = (source instanceof StringBuilder); 15932c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int start = startIndex; 1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int width = formatToken.getWidth(); 1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int precision = formatToken.getPrecision(); 1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int length = source.length(); 1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (precision >= 0) { 1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project length = Math.min(length, precision); 16012c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (sourceIsStringBuilder) { 16022c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes ((StringBuilder) source).setLength(length); 16032c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else { 16042c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes source = source.subSequence(0, length); 16052c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (width > 0) { 1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = Math.max(source.length(), width); 1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (length >= width) { 1611f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes return source; 1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 16142c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes char paddingChar = '\u0020'; // space as padding char. 161535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagZero) { 16162c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (formatToken.getConversionType() == 'd') { 16172c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes paddingChar = getDecimalFormatSymbols().getZeroDigit(); 16182c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else { 16192c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes paddingChar = '0'; 16202c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 16212c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else { 16222c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // if padding char is space, always pad from the start. 16232c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes start = 0; 16242c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 16252c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes char[] paddingChars = new char[width - length]; 16262c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes Arrays.fill(paddingChars, paddingChar); 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes boolean paddingRight = formatToken.flagMinus; 16292c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes StringBuilder result = toStringBuilder(source); 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (paddingRight) { 16312c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.append(paddingChars); 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 16332c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.insert(start, paddingChars); 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 16352c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return result; 16362c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 16372c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 16382c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private StringBuilder toStringBuilder(CharSequence cs) { 16392c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return cs instanceof StringBuilder ? (StringBuilder) cs : new StringBuilder(cs); 16402c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 16412c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 16422c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private StringBuilder wrapParentheses(StringBuilder result) { 16432c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.setCharAt(0, '('); // Replace the '-'. 164435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagZero) { 16452c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes formatToken.setWidth(formatToken.getWidth() - 1); 16462c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = (StringBuilder) padding(result, 1); 16472c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.append(')'); 16482c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else { 16492c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.append(')'); 16502c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result = (StringBuilder) padding(result, 0); 16512c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 16522c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return result; 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms the Integer to a formatted string. 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1658f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromInteger() { 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startIndex = 0; 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder result = new StringBuilder(); 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char currentConversionType = formatToken.getConversionType(); 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 166335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus || formatToken.flagZero) { 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!formatToken.isWidthSet()) { 166535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new MissingFormatWidthException(formatToken.getStrFlags()); 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 166835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // Combination of '+' and ' ' is illegal. 166935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd && formatToken.flagSpace) { 1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 167235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureNoPrecision(); 167335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes long value; 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg instanceof Long) { 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project value = ((Long) arg).longValue(); 1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (arg instanceof Integer) { 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project value = ((Integer) arg).longValue(); 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (arg instanceof Short) { 1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project value = ((Short) arg).longValue(); 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (arg instanceof Byte) { 1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project value = ((Byte) arg).longValue(); 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 168335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw badArgumentType(); 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ('d' != currentConversionType) { 168635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd || formatToken.flagSpace || formatToken.flagComma || 168735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.flagParenthesis) { 168835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 168935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.getConversionType()); 1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 169335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp) { 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ('d' == currentConversionType) { 169535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 169635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.getConversionType()); 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if ('o' == currentConversionType) { 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append("0"); //$NON-NLS-1$ 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 1; 1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append("0x"); //$NON-NLS-1$ 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 2; 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 170635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus && formatToken.flagZero) { 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ('d' == currentConversionType) { 171135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagComma) { 17122c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes NumberFormat numberFormat = getNumberFormat(); 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numberFormat.setGroupingUsed(true); 17142c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.append(numberFormat.format(arg)); 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 17162c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.append(value); 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 171835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes 171935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (value < 0) { 172035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagParenthesis) { 172135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes return wrapParentheses(result); 172235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else if (formatToken.flagZero) { 172335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes startIndex++; 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 172535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else { 172635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd) { 172735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes result.insert(0, '+'); 172835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes startIndex += 1; 172935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else if (formatToken.flagSpace) { 173035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes result.insert(0, ' '); 173135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes startIndex += 1; 173235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 173335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } 173435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else { 173535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes // Undo sign-extension, since we'll be using Long.to(Octal|Hex)String. 173635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (arg instanceof Byte) { 173735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes value &= 0xffL; 173835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else if (arg instanceof Short) { 173935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes value &= 0xffffL; 174035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else if (arg instanceof Integer) { 174135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes value &= 0xffffffffL; 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ('o' == currentConversionType) { 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(Long.toOctalString(value)); 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(Long.toHexString(value)); 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return padding(result, startIndex); 1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1753f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromSpecialNumber() { 1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(arg instanceof Number) || arg instanceof BigDecimal) { 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return null; 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Number number = (Number) arg; 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double d = number.doubleValue(); 17602c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes String source = null; 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (Double.isNaN(d)) { 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project source = "NaN"; //$NON-NLS-1$ 1763636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } else if (d == Double.POSITIVE_INFINITY) { 176435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd) { 1765636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes source = "+Infinity"; //$NON-NLS-1$ 176635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes } else if (formatToken.flagSpace) { 1767636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes source = " Infinity"; //$NON-NLS-1$ 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1769636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes source = "Infinity"; //$NON-NLS-1$ 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1771636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } else if (d == Double.NEGATIVE_INFINITY) { 177235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagParenthesis) { 1773636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes source = "(Infinity)"; //$NON-NLS-1$ 1774636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } else { 1775636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes source = "-Infinity"; //$NON-NLS-1$ 1776636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } 1777636bc6174d81cc4017d1659e94e8b33a5e51914aElliott Hughes } else { 17782c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return null; 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 17802c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 17812c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes formatToken.setPrecision(FormatToken.UNSET); 178219c5378901c2facf48f02eedb77eaf24fc225986Elliott Hughes formatToken.flagZero = false; 17832c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding(source, 0); 1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1786f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromNull() { 178719c5378901c2facf48f02eedb77eaf24fc225986Elliott Hughes formatToken.flagZero = false; 17882c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding("null", 0); //$NON-NLS-1$ 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms a BigInteger to a formatted string. 1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1794f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromBigInteger() { 1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startIndex = 0; 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean isNegative = false; 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder result = new StringBuilder(); 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project BigInteger bigInt = (BigInteger) arg; 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char currentConversionType = formatToken.getConversionType(); 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 180135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus || formatToken.flagZero) { 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!formatToken.isWidthSet()) { 180335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new MissingFormatWidthException(formatToken.getStrFlags()); 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Combination of '+' & ' ' is illegal. 180835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd && formatToken.flagSpace) { 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Combination of '-' & '0' is illegal. 181335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagZero && formatToken.flagMinus) { 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureNoPrecision(); 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 181935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if ('d' != currentConversionType && formatToken.flagComma) { 182035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 182135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes currentConversionType); 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 182435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp && 'd' == currentConversionType) { 182535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 182635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes currentConversionType); 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 182935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (bigInt == null) { 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return transformFromNull(); 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project isNegative = (bigInt.compareTo(BigInteger.ZERO) < 0); 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ('d' == currentConversionType) { 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NumberFormat numberFormat = getNumberFormat(); 183735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes numberFormat.setGroupingUsed(formatToken.flagComma); 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(numberFormat.format(bigInt)); 1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if ('o' == currentConversionType) { 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // convert BigInteger to a string presentation using radix 8 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(bigInt.toString(8)); 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // convert BigInteger to a string presentation using radix 16 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(bigInt.toString(16)); 1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 184635138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp) { 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex = isNegative ? 1 : 0; 1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ('o' == currentConversionType) { 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(startIndex, "0"); //$NON-NLS-1$ 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 1; 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if ('x' == currentConversionType 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project || 'X' == currentConversionType) { 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(startIndex, "0x"); //$NON-NLS-1$ 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 2; 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!isNegative) { 185935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd) { 1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(0, '+'); 1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 1; 1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 186335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSpace) { 1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(0, ' '); 1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 1; 1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* pad paddingChar to the output */ 187035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (isNegative && formatToken.flagParenthesis) { 18712c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return wrapParentheses(result); 1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 187335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (isNegative && formatToken.flagZero) { 1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex++; 1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return padding(result, startIndex); 1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms a Float,Double or BigDecimal to a formatted string. 1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1882f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromFloat() { 1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder result = new StringBuilder(); 1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startIndex = 0; 1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char currentConversionType = formatToken.getConversionType(); 1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 188735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus || formatToken.flagZero) { 1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!formatToken.isWidthSet()) { 188935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new MissingFormatWidthException(formatToken.getStrFlags()); 1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 189335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd && formatToken.flagSpace) { 1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 189735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus && formatToken.flagZero) { 1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatFlagsException(formatToken.getStrFlags()); 1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1901771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (currentConversionType == 'e' || currentConversionType == 'E') { 190235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagComma) { 190335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 190435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes currentConversionType); 1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1906771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes } else if (currentConversionType == 'g' || currentConversionType == 'G') { 190735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp) { 190835138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 190935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes currentConversionType); 1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1911771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes } else if (currentConversionType == 'a' || currentConversionType == 'A') { 191235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagComma || formatToken.flagParenthesis) { 191335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 191435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes currentConversionType); 1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == arg) { 1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return transformFromNull(); 1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!(arg instanceof Float || arg instanceof Double || arg instanceof BigDecimal)) { 192335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw badArgumentType(); 1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1926f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes CharSequence specialNumberResult = transformFromSpecialNumber(); 1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null != specialNumberResult) { 1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return specialNumberResult; 1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1931771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (currentConversionType != 'a' && currentConversionType != 'A' && 1932c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes !formatToken.isPrecisionSet()) { 1933c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes formatToken.setPrecision(FormatToken.DEFAULT_PRECISION); 1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1935c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes 1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // output result 1937771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes DecimalFormatSymbols decimalFormatSymbols = getDecimalFormatSymbols(); 1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FloatUtil floatUtil = new FloatUtil(result, formatToken, 1939771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes (DecimalFormat) getNumberFormat(), decimalFormatSymbols, arg); 1940771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes floatUtil.transform(currentConversionType); 1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formatToken.setPrecision(FormatToken.UNSET); 1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1944771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (decimalFormatSymbols.getMinusSign() == result.charAt(0)) { 194535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagParenthesis) { 19462c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return wrapParentheses(result); 1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 194935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSpace) { 1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(0, ' '); 1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex++; 1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 195335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagAdd) { 1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(0, floatUtil.getAddSign()); 1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex++; 1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char firstChar = result.charAt(0); 196035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagZero 1961771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes && (firstChar == floatUtil.getAddSign() || firstChar == decimalFormatSymbols.getMinusSign())) { 1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex = 1; 1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1965771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (currentConversionType == 'a' || currentConversionType == 'A') { 1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex += 2; 1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return padding(result, startIndex); 1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Transforms a Date to a formatted string. 1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1974f69a407c29a01b5e4a228b52fd08505cb7dc1b09Elliott Hughes private CharSequence transformFromDateTime() { 197535138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes formatToken.ensureNoPrecision(); 1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197735138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes char currentConversionType = formatToken.getConversionType(); 1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197935138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp) { 198035138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw new FormatFlagsConversionMismatchException(formatToken.getStrFlags(), 198135138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes currentConversionType); 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 198435138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagMinus && formatToken.getWidth() == FormatToken.UNSET) { 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new MissingFormatWidthException("-" //$NON-NLS-1$ 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + currentConversionType); 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == arg) { 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return transformFromNull(); 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Calendar calendar; 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg instanceof Calendar) { 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calendar = (Calendar) arg; 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Date date = null; 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (arg instanceof Long) { 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project date = new Date(((Long) arg).longValue()); 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (arg instanceof Date) { 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project date = (Date) arg; 2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 200335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes throw badArgumentType(); 2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calendar = Calendar.getInstance(locale); 2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project calendar.setTime(date); 2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == dateTimeUtil) { 2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dateTimeUtil = new DateTimeUtil(locale); 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder result = new StringBuilder(); 2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // output result 2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dateTimeUtil.transform(formatToken, calendar, result); 20152c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return padding(result, 0); 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class FloatUtil { 2020c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes private final StringBuilder result; 2021c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes private final DecimalFormat decimalFormat; 2022771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes private final DecimalFormatSymbols decimalFormatSymbols; 2023c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes private final FormatToken formatToken; 2024c047c11da7d284940bcac9a28c42145628d49fedElliott Hughes private final Object argument; 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2026771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes FloatUtil(StringBuilder result, FormatToken formatToken, DecimalFormat decimalFormat, 2027771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes DecimalFormatSymbols decimalFormatSymbols, Object argument) { 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.result = result; 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.formatToken = formatToken; 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.decimalFormat = decimalFormat; 2031771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes this.decimalFormatSymbols = decimalFormatSymbols; 2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.argument = argument; 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2035771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes void transform(char conversionType) { 2036771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes switch (conversionType) { 2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'e': 2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'E': { 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_e(); 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'f': { 2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_f(); 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'g': 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'G': { 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_g(); 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'a': 2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'A': { 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_a(); 2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: { 2057771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes throw new UnknownFormatConversionException(String.valueOf(conversionType)); 2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char getAddSign() { 2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return '+'; 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void transform_e() { 2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder pattern = new StringBuilder(); 2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pattern.append('0'); 2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (formatToken.getPrecision() > 0) { 2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pattern.append('.'); 2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] zeros = new char[formatToken.getPrecision()]; 2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Arrays.fill(zeros, '0'); 2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pattern.append(zeros); 2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pattern.append('E'); 2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pattern.append("+00"); //$NON-NLS-1$ 2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project decimalFormat.applyPattern(pattern.toString()); 2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String formattedString = decimalFormat.format(argument); 2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(formattedString.replace('E', 'e')); 2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 20812c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // if the flag is sharp and decimal separator is always given 2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // out. 208335138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp && formatToken.getPrecision() == 0) { 2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int indexOfE = result.indexOf("e"); //$NON-NLS-1$ 2085771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes result.insert(indexOfE, decimalFormatSymbols.getDecimalSeparator()); 2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void transform_g() { 2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int precision = formatToken.getPrecision(); 2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision = (0 == precision ? 1 : precision); 2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formatToken.setPrecision(precision); 2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (0.0 == ((Number) argument).doubleValue()) { 2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision--; 2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formatToken.setPrecision(precision); 2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_f(); 2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean requireScientificRepresentation = true; 2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double d = ((Number) argument).doubleValue(); 2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project d = Math.abs(d); 21043819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson if (Double.isInfinite(d)) { 21053819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson precision = formatToken.getPrecision(); 21063819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson precision--; 21073819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson formatToken.setPrecision(precision); 21083819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson transform_e(); 21093819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson return; 21103819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson } 21113819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson BigDecimal b = new BigDecimal(d, new MathContext(precision)); 21123819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson d = b.doubleValue(); 21133819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson long l = b.longValue(); 2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 21153819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson if (d >= 1 && d < Math.pow(10, precision)) { 2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (l < Math.pow(10, precision)) { 2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project requireScientificRepresentation = false; 2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision -= String.valueOf(l).length(); 2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision = precision < 0 ? 0 : precision; 2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project l = Math.round(d * Math.pow(10, precision + 1)); 2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (String.valueOf(l).length() <= formatToken 2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .getPrecision()) { 2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision++; 2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formatToken.setPrecision(precision); 2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 21293819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson l = b.movePointRight(4).longValue(); 21303819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson if (d >= Math.pow(10, -4) && d < 1) { 2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project requireScientificRepresentation = false; 2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision += 4 - String.valueOf(l).length(); 21333819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson l = b.movePointRight(precision + 1).longValue(); 2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (String.valueOf(l).length() <= formatToken 2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .getPrecision()) { 2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision++; 2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 21383819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson l = b.movePointRight(precision).longValue(); 21393819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson if (l >= Math.pow(10, precision - 4)) { 2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formatToken.setPrecision(precision); 2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (requireScientificRepresentation) { 2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision = formatToken.getPrecision(); 2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision--; 2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project formatToken.setPrecision(precision); 2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_e(); 2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_f(); 2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void transform_f() { 2155771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes // TODO: store a default DecimalFormat we can clone? 2156771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes String pattern = "0.000000"; 2157771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (formatToken.flagComma || formatToken.getPrecision() != 6) { 2158771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes StringBuilder patternBuilder = new StringBuilder(); 2159771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (formatToken.flagComma) { 2160771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes patternBuilder.append(','); 2161771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes int groupingSize = decimalFormat.getGroupingSize(); 2162771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (groupingSize > 1) { 2163771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes char[] sharps = new char[groupingSize - 1]; 2164771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes Arrays.fill(sharps, '#'); 2165771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes patternBuilder.append(sharps); 2166771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes } 2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2168771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes patternBuilder.append(0); 2169771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes if (formatToken.getPrecision() > 0) { 2170771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes patternBuilder.append('.'); 2171771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes char[] zeros = new char[formatToken.getPrecision()]; 2172771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes Arrays.fill(zeros, '0'); 2173771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes patternBuilder.append(zeros); 2174771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes } 2175771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes pattern = patternBuilder.toString(); 2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2177771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes // TODO: if DecimalFormat.toPattern was cheap, we could make this cheap (preferably *in* DecimalFormat). 2178771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes decimalFormat.applyPattern(pattern); 2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(decimalFormat.format(argument)); 21802c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // if the flag is sharp and decimal separator is always given 2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // out. 218235138e0566bc395af2f30a3a4354033adb1d0682Elliott Hughes if (formatToken.flagSharp && formatToken.getPrecision() == 0) { 2183771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes result.append(decimalFormatSymbols.getDecimalSeparator()); 2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void transform_a() { 2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (argument instanceof Float) { 2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Float F = (Float) argument; 2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(Float.toHexString(F.floatValue())); 2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (argument instanceof Double) { 2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Double D = (Double) argument; 2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(Double.toHexString(D.doubleValue())); 2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // BigInteger is not supported. 2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new IllegalFormatConversionException( 2198771f3129d213c4725c5a78c6a4ae86ea1b015968Elliott Hughes formatToken.getConversionType(), argument.getClass()); 2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!formatToken.isPrecisionSet()) { 2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int precision = formatToken.getPrecision(); 2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project precision = (0 == precision ? 1 : precision); 22072c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int indexOfFirstFractionalDigit = result.indexOf(".") + 1; //$NON-NLS-1$ 2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int indexOfP = result.indexOf("p"); //$NON-NLS-1$ 22092c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int fractionalLength = indexOfP - indexOfFirstFractionalDigit; 2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fractionalLength == precision) { 2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fractionalLength < precision) { 2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char zeros[] = new char[precision - fractionalLength]; 2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Arrays.fill(zeros, '0'); 2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(indexOfP, zeros); 2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 22212c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes result.delete(indexOfFirstFractionalDigit + precision, indexOfP); 2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static class DateTimeUtil { 2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Calendar calendar; 2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private Locale locale; 2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private StringBuilder result; 2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private DateFormatSymbols dateFormatSymbols; 2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DateTimeUtil(Locale locale) { 2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.locale = locale; 2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project void transform(FormatToken formatToken, Calendar aCalendar, 2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder aResult) { 2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.result = aResult; 2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.calendar = aCalendar; 2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char suffix = formatToken.getDateSuffix(); 2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (suffix) { 2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'H': { 2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_H(); 2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'I': { 2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_I(); 2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'M': { 2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_M(); 2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'S': { 2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_S(); 2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'L': { 2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_L(); 2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'N': { 2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_N(); 2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'k': { 2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_k(); 2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'l': { 2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_l(); 2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'p': { 2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_p(true); 2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 's': { 2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_s(); 2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'z': { 2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_z(); 2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Z': { 2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_Z(); 2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Q': { 2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_Q(); 2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'B': { 2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_B(); 2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'b': 2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'h': { 2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_b(); 2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'A': { 2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_A(); 2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'a': { 2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_a(); 2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'C': { 2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_C(); 2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'Y': { 2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_Y(); 2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'y': { 2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_y(); 2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'j': { 2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_j(); 2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'm': { 2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_m(); 2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'd': { 2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_d(); 2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'e': { 2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_e(); 2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'R': { 2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_R(); 2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'T': { 2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_T(); 2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'r': { 2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_r(); 2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'D': { 2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_D(); 2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'F': { 2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_F(); 2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'c': { 2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_c(); 2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: { 2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new UnknownFormatConversionException(String 2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project .valueOf(formatToken.getConversionType()) 2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project + formatToken.getDateSuffix()); 2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_e() { 2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int day = calendar.get(Calendar.DAY_OF_MONTH); 2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(day); 2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_d() { 2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int day = calendar.get(Calendar.DAY_OF_MONTH); 2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(day, 2)); 2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_m() { 2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int month = calendar.get(Calendar.MONTH); 2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // The returned month starts from zero, which needs to be 2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // incremented by 1. 2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project month++; 2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(month, 2)); 2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_j() { 2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int day = calendar.get(Calendar.DAY_OF_YEAR); 2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(day, 3)); 2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_y() { 2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int year = calendar.get(Calendar.YEAR); 2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project year %= 100; 2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(year, 2)); 2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_Y() { 2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int year = calendar.get(Calendar.YEAR); 2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(year, 4)); 2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_C() { 2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int year = calendar.get(Calendar.YEAR); 2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project year /= 100; 2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(year, 2)); 2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_a() { 2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int day = calendar.get(Calendar.DAY_OF_WEEK); 2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(getDateFormatSymbols().getShortWeekdays()[day]); 2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_A() { 2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int day = calendar.get(Calendar.DAY_OF_WEEK); 2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(getDateFormatSymbols().getWeekdays()[day]); 2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_b() { 2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int month = calendar.get(Calendar.MONTH); 2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(getDateFormatSymbols().getShortMonths()[month]); 2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_B() { 2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int month = calendar.get(Calendar.MONTH); 2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(getDateFormatSymbols().getMonths()[month]); 2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_Q() { 2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long milliSeconds = calendar.getTimeInMillis(); 2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(milliSeconds); 2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_s() { 2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long milliSeconds = calendar.getTimeInMillis(); 2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project milliSeconds /= 1000; 2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(milliSeconds); 2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_Z() { 2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimeZone timeZone = calendar.getTimeZone(); 24483819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson result.append(timeZone 24493819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson .getDisplayName( 24503819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson timeZone.inDaylightTime(calendar.getTime()), 24513819a76e7c1f49253f0e077bd497f149340c02b8Jesse Wilson TimeZone.SHORT, locale)); 2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_z() { 245594a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes long offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET); 245694a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes char sign = '+'; 245794a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes if (offset < 0) { 245894a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes sign = '-'; 245994a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes offset = -offset; 246094a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes } 246194a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes result.append(sign); 246294a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes result.append(paddingZeros(offset / 3600000, 2)); 246394a6dc1d671e6fb619b739a2f1640f416552a881Elliott Hughes result.append(paddingZeros((offset % 3600000) / 60000, 2)); 2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_p(boolean isLowerCase) { 2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = calendar.get(Calendar.AM_PM); 2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String s = getDateFormatSymbols().getAmPmStrings()[i]; 2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (isLowerCase) { 2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project s = s.toLowerCase(locale); 2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(s); 2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_N() { 2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long nanosecond = calendar.get(Calendar.MILLISECOND) * 1000000L; 2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(nanosecond, 9)); 2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_L() { 2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int millisecond = calendar.get(Calendar.MILLISECOND); 2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(millisecond, 3)); 2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_S() { 2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int second = calendar.get(Calendar.SECOND); 2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(second, 2)); 2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_M() { 2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int minute = calendar.get(Calendar.MINUTE); 2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(minute, 2)); 2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_l() { 2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hour = calendar.get(Calendar.HOUR); 2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (0 == hour) { 2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hour = 12; 2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(hour); 2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_k() { 2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hour = calendar.get(Calendar.HOUR_OF_DAY); 2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(hour); 2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_I() { 2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hour = calendar.get(Calendar.HOUR); 2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (0 == hour) { 2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hour = 12; 2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(hour, 2)); 2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_H() { 2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hour = calendar.get(Calendar.HOUR_OF_DAY); 2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(paddingZeros(hour, 2)); 2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_R() { 2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_H(); 2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(':'); 2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_M(); 2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_T() { 2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_H(); 2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(':'); 2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_M(); 2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(':'); 2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_S(); 2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_r() { 2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_I(); 2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(':'); 2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_M(); 2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(':'); 2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_S(); 2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(' '); 2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_p(false); 2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_D() { 2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_m(); 2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append('/'); 2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_d(); 2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append('/'); 2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_y(); 2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_F() { 2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_Y(); 2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append('-'); 2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_m(); 2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append('-'); 2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_d(); 2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private void transform_c() { 2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_a(); 2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(' '); 2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_b(); 2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(' '); 2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_d(); 2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(' '); 2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_T(); 2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(' '); 2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_Z(); 2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(' '); 2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project transform_Y(); 2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 25752c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // TODO: this doesn't need a temporary StringBuilder! 2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private static String paddingZeros(long number, int length) { 2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = length; 2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder result = new StringBuilder(); 2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(number); 2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int startIndex = 0; 2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (number < 0) { 2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len++; 2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project startIndex = 1; 2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= result.length(); 2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len > 0) { 2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char[] zeros = new char[len]; 2588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Arrays.fill(zeros, '0'); 2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.insert(startIndex, zeros); 2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result.toString(); 2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private DateFormatSymbols getDateFormatSymbols() { 2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null == dateFormatSymbols) { 2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dateFormatSymbols = new DateFormatSymbols(locale); 2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dateFormatSymbols; 2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26022c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private static class FormatSpecifierParser { 2603e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes private String format; 2604e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes private int length; 2605e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes 26062c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private int startIndex; 26072c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private int i; 2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26092c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes /** 2610e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes * Constructs a new parser for the given format string. 2611e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes */ 2612e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes FormatSpecifierParser(String format) { 2613e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes this.format = format; 2614e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes this.length = format.length(); 2615e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes } 2616e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes 2617e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes /** 2618e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes * Returns a FormatToken representing the format specifier starting at 'offset'. 26192c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * @param offset the first character after the '%' 2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2621e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes FormatToken parseFormatToken(int offset) { 26222c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes this.startIndex = offset; 26232c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes this.i = offset; 26242c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parseArgumentIndexAndFlags(new FormatToken()); 2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26272c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes /** 26282c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * Returns a string corresponding to the last format specifier that was parsed. 26292c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes * Used to construct error messages. 2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 26312c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes String getFormatSpecifierText() { 2632e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes return format.substring(startIndex, i); 2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26352c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private int peek() { 2636e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes return (i < length) ? format.charAt(i) : -1; 2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26392c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private char advance() { 2640e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes if (i >= length) { 26412c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes throw new UnknownFormatConversionException(getFormatSpecifierText()); 2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2643e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes return format.charAt(i++); 2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26462c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private FormatToken parseArgumentIndexAndFlags(FormatToken token) { 26472c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // Parse the argument index, if there is one. 26482c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int position = i; 26492c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int ch = peek(); 26502c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (Character.isDigit(ch)) { 26512c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int number = nextInt(); 26522c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (peek() == '$') { 26532c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // The number was an argument index. 26542c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes advance(); // Swallow the '$'. 26552c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (number == FormatToken.UNSET) { 26562c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes throw new MissingFormatArgumentException(getFormatSpecifierText()); 2657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 26582c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // k$ stands for the argument whose index is k-1 except that 26592c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // 0$ and 1$ both stand for the first element. 26602c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes token.setArgIndex(Math.max(0, number - 1)); 2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 26622c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (ch == '0') { 26632c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // The digit zero is a format flag, so reparse it as such. 26642c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes i = position; 2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 26662c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // The number was a width. This means there are no flags to parse. 26672c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parseWidth(token, number); 2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 26702c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else if (ch == '<') { 2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project token.setArgIndex(FormatToken.LAST_ARGUMENT_INDEX); 26722c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes advance(); 2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26752c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // Parse the flags. 26762c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes while (token.setFlag(peek())) { 26772c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes advance(); 2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26802c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // What comes next? 26812c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes ch = peek(); 26822c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (Character.isDigit(ch)) { 26832c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parseWidth(token, nextInt()); 26842c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } else if (ch == '.') { 26852c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parsePrecision(token); 2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 26872c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parseConversionType(token); 2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26912c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // We pass the width in because in some cases we've already parsed it. 26922c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // (Because of the ambiguity between argument indexes and widths.) 26932c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private FormatToken parseWidth(FormatToken token, int width) { 26942c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes token.setWidth(width); 26952c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int ch = peek(); 26962c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (ch == '.') { 26972c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parsePrecision(token); 2698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 26992c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parseConversionType(token); 2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27032c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private FormatToken parsePrecision(FormatToken token) { 27042c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes advance(); // Swallow the '.'. 27052c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes int ch = peek(); 27062c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (Character.isDigit(ch)) { 27072c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes token.setPrecision(nextInt()); 27082c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return parseConversionType(token); 2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 27102c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // The precision is required but not given by the format string. 27112c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes throw new UnknownFormatConversionException(getFormatSpecifierText()); 2712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27152c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private FormatToken parseConversionType(FormatToken token) { 2716d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes char conversionType = advance(); // A conversion type is mandatory. 2717d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes token.setConversionType(conversionType); 2718d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes if (conversionType == 't' || conversionType == 'T') { 2719d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes char dateSuffix = advance(); // A date suffix is mandatory for 't' or 'T'. 2720d028bd15d5c5dfe2b4cbc66e7c4d6d4c716795deElliott Hughes token.setDateSuffix(dateSuffix); 27212c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 27222c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return token; 2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27252c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // Parses an integer (of arbitrary length, but typically just one digit). 27262c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private int nextInt() { 27272c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes long value = 0; 2728e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes while (i < length && Character.isDigit(format.charAt(i))) { 2729e25b3c255c19693b9aa5bb16e90e007766246595Elliott Hughes value = 10 * value + (format.charAt(i++) - '0'); 27302c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes if (value > Integer.MAX_VALUE) { 27312c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return failNextInt(); 2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 27342c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return (int) value; 27352c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes } 27362c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes 27372c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes // Swallow remaining digits to resync our attempted parse, but return failure. 27382c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes private int failNextInt() { 27392c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes while (Character.isDigit(peek())) { 27402c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes advance(); 2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 27422c5e73632c4bb75004fd3858b2bba30857e82598Elliott Hughes return FormatToken.UNSET; 2743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2746