Clover coverage report - Maven Clover report
Coverage timestamp: Thu Jan 5 2006 14:51:54 ART
file stats: LOC: 3,075   Methods: 62
NCLOC: 1,986   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
PrintfFormat.java 13.9% 14.7% 33.9% 14.9%
coverage coverage
 1    /*
 2    * Created on Dec 21, 2005
 3    *
 4    */
 5    package net.sf.ffo;
 6   
 7    // Bajado de:
 8    // http://developer.java.sun.com/developer/technicalArticles/Programming/sprintf/
 9    //
 10    // (c) 2000 Sun Microsystems, Inc.
 11    // ALL RIGHTS RESERVED
 12    //
 13    // License Grant-
 14    //
 15    //
 16    // Permission to use, copy, modify, and distribute this Software and its
 17    // documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is
 18    // hereby granted.
 19    //
 20    // This Software is provided "AS IS". All express warranties, including any
 21    // implied warranty of merchantability, satisfactory quality, fitness for a
 22    // particular purpose, or non-infringement, are disclaimed, except to the extent
 23    // that such disclaimers are held to be legally invalid.
 24    //
 25    // You acknowledge that Software is not designed, licensed or intended for use
 26    // in
 27    // the design, construction, operation or maintenance of any nuclear facility
 28    // ("High Risk Activities"). Sun disclaims any express or implied warranty of
 29    // fitness for such uses.
 30    //
 31    // Please refer to the file http://www.sun.com/policies/trademarks/ for further
 32    // important trademark information and to
 33    // http://java.sun.com/nav/business/index.html for further important licensing
 34    // information for the Java Technology.
 35    //
 36   
 37    import java.text.DecimalFormatSymbols;
 38    import java.util.Enumeration;
 39    import java.util.Locale;
 40    import java.util.Vector;
 41   
 42    /**
 43    * PrintfFormat allows the formatting of an array of objects embedded within a
 44    * string. Primitive types must be passed using wrapper types. The formatting is
 45    * controlled by a control string.
 46    * <p>
 47    * A control string is a Java string that contains a control specification. The
 48    * control specification starts at the first percent sign (%) in the string,
 49    * provided that this percent sign
 50    * <ol>
 51    * <li>is not escaped protected by a matching % or is not an escape %
 52    * character,
 53    * <li>is not at the end of the format string, and
 54    * <li>precedes a sequence of characters that parses as a valid control
 55    * specification.
 56    * </ol>
 57    * </p>
 58    * <p>
 59    * A control specification usually takes the form:
 60    *
 61    * <pre>
 62    * % ['-+ #0]* [0..9]* { . [0..9]* }+
 63    * { [hlL] }+ [idfgGoxXeEcs]
 64    * </pre>
 65    *
 66    * There are variants of this basic form that are discussed below.
 67    * </p>
 68    * <p>
 69    * The format is composed of zero or more directives defined as follows:
 70    * <ul>
 71    * <li>ordinary characters, which are simply copied to the output stream;
 72    * <li>escape sequences, which represent non-graphic characters; and
 73    * <li>conversion specifications, each of which results in the fetching of zero
 74    * or more arguments.
 75    * </ul>
 76    * </p>
 77    * <p>
 78    * The results are undefined if there are insufficient arguments for the format.
 79    * Usually an unchecked exception will be thrown. If the format is exhausted
 80    * while arguments remain, the excess arguments are evaluated but are otherwise
 81    * ignored. In format strings containing the % form of conversion
 82    * specifications, each argument in the argument list is used exactly once.
 83    * </p>
 84    * <p>
 85    * Conversions can be applied to the <code>n</code>th argument after the
 86    * format in the argument list, rather than to the next unused argument. In this
 87    * case, the conversion characer % is replaced by the sequence %<code>n</code>$,
 88    * where <code>n</code> is a decimal integer giving the position of the
 89    * argument in the argument list.
 90    * </p>
 91    * <p>
 92    * In format strings containing the %<code>n</code>$ form of conversion
 93    * specifications, each argument in the argument list is used exactly once.
 94    * </p>
 95    * <h4>Escape Sequences</h4>
 96    * <p>
 97    * The following table lists escape sequences and associated actions on display
 98    * devices capable of the action. <table>
 99    * <tr>
 100    * <th align=left>Sequence</th>
 101    * <th align=left>Name</th>
 102    * <th align=left>Description</th>
 103    * </tr>
 104    * <tr>
 105    * <td>\\</td>
 106    * <td>backlash</td>
 107    * <td>None. </td>
 108    * </tr>
 109    * <tr>
 110    * <td>\a</td>
 111    * <td>alert</td>
 112    * <td>Attempts to alert the user through audible or visible notification.
 113    * </td>
 114    * </tr>
 115    * <tr>
 116    * <td>\b</td>
 117    * <td>backspace</td>
 118    * <td>Moves the printing position to one column before the current position,
 119    * unless the current position is the start of a line. </td>
 120    * </tr>
 121    * <tr>
 122    * <td>\f</td>
 123    * <td>form-feed</td>
 124    * <td>Moves the printing position to the initial printing position of the next
 125    * logical page. </td>
 126    * </tr>
 127    * <tr>
 128    * <td>\n</td>
 129    * <td>newline</td>
 130    * <td>Moves the printing position to the start of the next line. </td>
 131    * </tr>
 132    * <tr>
 133    * <td>\r</td>
 134    * <td>carriage-return</td>
 135    * <td>Moves the printing position to the start of the current line. </td>
 136    * </tr>
 137    * <tr>
 138    * <td>\t</td>
 139    * <td>tab</td>
 140    * <td>Moves the printing position to the next implementation- defined
 141    * horizontal tab position. </td>
 142    * </tr>
 143    * <tr>
 144    * <td>\v</td>
 145    * <td>vertical-tab</td>
 146    * <td>Moves the printing position to the start of the next
 147    * implementation-defined vertical tab position. </td>
 148    * </tr>
 149    * </table>
 150    * </p>
 151    * <h4>Conversion Specifications</h4>
 152    * <p>
 153    * Each conversion specification is introduced by the percent sign character
 154    * (%). After the character %, the following appear in sequence:
 155    * </p>
 156    * <p>
 157    * Zero or more flags (in any order), which modify the meaning of the conversion
 158    * specification.
 159    * </p>
 160    * <p>
 161    * An optional minimum field width. If the converted value has fewer characters
 162    * than the field width, it will be padded with spaces by default on the left; t
 163    * will be padded on the right, if the left- adjustment flag (-), described
 164    * below, is given to the field width. The field width takes the form of a
 165    * decimal integer. If the conversion character is s, the field width is the the
 166    * minimum number of characters to be printed.
 167    * </p>
 168    * <p>
 169    * An optional precision that gives the minumum number of digits to appear for
 170    * the d, i, o, x or X conversions (the field is padded with leading zeros); the
 171    * number of digits to appear after the radix character for the e, E, and f
 172    * conversions, the maximum number of significant digits for the g and G
 173    * conversions; or the maximum number of characters to be written from a string
 174    * is s and S conversions. The precision takes the form of an optional decimal
 175    * digit string, where a null digit string is treated as 0. If a precision
 176    * appears with a c conversion character the precision is ignored.
 177    * </p>
 178    * <p>
 179    * An optional h specifies that a following d, i, o, x, or X conversion
 180    * character applies to a type short argument (the argument will be promoted
 181    * according to the integral promotions and its value converted to type short
 182    * before printing).
 183    * </p>
 184    * <p>
 185    * An optional l (ell) specifies that a following d, i, o, x, or X conversion
 186    * character applies to a type long argument.
 187    * </p>
 188    * <p>
 189    * A field width or precision may be indicated by an asterisk (*) instead of a
 190    * digit string. In this case, an integer argument supplised the field width
 191    * precision. The argument that is actually converted is not fetched until the
 192    * conversion letter is seen, so the the arguments specifying field width or
 193    * precision must appear before the argument (if any) to be converted. If the
 194    * precision argument is negative, it will be changed to zero. A negative field
 195    * width argument is taken as a - flag, followed by a positive field width.
 196    * </p>
 197    * <p>
 198    * In format strings containing the %<code>n</code>$ form of a conversion
 199    * specification, a field width or precision may be indicated by the sequence *<code>m</code>$,
 200    * where m is a decimal integer giving the position in the argument list (after
 201    * the format argument) of an integer argument containing the field width or
 202    * precision.
 203    * </p>
 204    * <p>
 205    * The format can contain either numbered argument specifications (that is, %<code>n</code>$
 206    * and *<code>m</code>$), or unnumbered argument specifications (that is %
 207    * and *), but normally not both. The only exception to this is that %% can be
 208    * mixed with the %<code>n</code>$ form. The results of mixing numbered and
 209    * unnumbered argument specifications in a format string are undefined.
 210    * </p>
 211    * <h4>Flag Characters</h4>
 212    * <p>
 213    * The flags and their meanings are:
 214    * </p>
 215    * <dl>
 216    * <dt>'
 217    * <dd> integer portion of the result of a decimal conversion (%i, %d, %f, %g,
 218    * or %G) will be formatted with thousands' grouping characters. For other
 219    * conversions the flag is ignored. The non-monetary grouping character is used.
 220    * <dt>-
 221    * <dd> result of the conversion is left-justified within the field. (It will be
 222    * right-justified if this flag is not specified).</td>
 223    * </tr>
 224    * <dt>+
 225    * <dd> result of a signed conversion always begins with a sign (+ or -). (It
 226    * will begin with a sign only when a negative value is converted if this flag
 227    * is not specified.)
 228    * <dt>&lt;space&gt;
 229    * <dd> If the first character of a signed conversion is not a sign, a space
 230    * character will be placed before the result. This means that if the space
 231    * character and + flags both appear, the space flag will be ignored.
 232    * <dt>#
 233    * <dd> value is to be converted to an alternative form. For c, d, i, and s
 234    * conversions, the flag has no effect. For o conversion, it increases the
 235    * precision to force the first digit of the result to be a zero. For x or X
 236    * conversion, a non-zero result has 0x or 0X prefixed to it, respectively. For
 237    * e, E, f, g, and G conversions, the result always contains a radix character,
 238    * even if no digits follow the radix character (normally, a decimal point
 239    * appears in the result of these conversions only if a digit follows it). For g
 240    * and G conversions, trailing zeros will not be removed from the result as they
 241    * normally are.
 242    * <dt>0
 243    * <dd> d, i, o, x, X, e, E, f, g, and G conversions, leading zeros (following
 244    * any indication of sign or base) are used to pad to the field width; no space
 245    * padding is performed. If the 0 and - flags both appear, the 0 flag is
 246    * ignored. For d, i, o, x, and X conversions, if a precision is specified, the
 247    * 0 flag will be ignored. For c conversions, the flag is ignored.
 248    * </dl>
 249    * <h4>Conversion Characters</h4>
 250    * <p>
 251    * Each conversion character results in fetching zero or more arguments. The
 252    * results are undefined if there are insufficient arguments for the format.
 253    * Usually, an unchecked exception will be thrown. If the format is exhausted
 254    * while arguments remain, the excess arguments are ignored.
 255    * </p>
 256    * <p>
 257    * The conversion characters and their meanings are:
 258    * </p>
 259    * <dl>
 260    * <dt>d,i
 261    * <dd>The int argument is converted to a signed decimal in the style [-]dddd.
 262    * The precision specifies the minimum number of digits to appear; if the value
 263    * being converted can be represented in fewer digits, it will be expanded with
 264    * leading zeros. The default precision is 1. The result of converting 0 with an
 265    * explicit precision of 0 is no characters.
 266    * <dt>o
 267    * <dd> The int argument is converted to unsigned octal format in the style
 268    * ddddd. The precision specifies the minimum number of digits to appear; if the
 269    * value being converted can be represented in fewer digits, it will be expanded
 270    * with leading zeros. The default precision is 1. The result of converting 0
 271    * with an explicit precision of 0 is no characters.
 272    * <dt>x
 273    * <dd> The int argument is converted to unsigned hexadecimal format in the
 274    * style dddd; the letters abcdef are used. The precision specifies the minimum
 275    * numberof digits to appear; if the value being converted can be represented in
 276    * fewer digits, it will be expanded with leading zeros. The default precision
 277    * is 1. The result of converting 0 with an explicit precision of 0 is no
 278    * characters.
 279    * <dt>X
 280    * <dd> Behaves the same as the x conversion character except that letters
 281    * ABCDEF are used instead of abcdef.
 282    * <dt>f
 283    * <dd> The floating point number argument is written in decimal notation in the
 284    * style [-]ddd.ddd, where the number of digits after the radix character (shown
 285    * here as a decimal point) is equal to the precision specification. A Locale is
 286    * used to determine the radix character to use in this format. If the precision
 287    * is omitted from the argument, six digits are written after the radix
 288    * character; if the precision is explicitly 0 and the # flag is not specified,
 289    * no radix character appears. If a radix character appears, at least 1 digit
 290    * appears before it. The value is rounded to the appropriate number of digits.
 291    * <dt>e,E
 292    * <dd>The floating point number argument is written in the style
 293    * [-]d.ddde{+-}dd (the symbols {+-} indicate either a plus or minus sign),
 294    * where there is one digit before the radix character (shown here as a decimal
 295    * point) and the number of digits after it is equal to the precision. A Locale
 296    * is used to determine the radix character to use in this format. When the
 297    * precision is missing, six digits are written after the radix character; if
 298    * the precision is 0 and the # flag is not specified, no radix character
 299    * appears. The E conversion will produce a number with E instead of e
 300    * introducing the exponent. The exponent always contains at least two digits.
 301    * However, if the value to be written requires an exponent greater than two
 302    * digits, additional exponent digits are written as necessary. The value is
 303    * rounded to the appropriate number of digits.
 304    * <dt>g,G
 305    * <dd>The floating point number argument is written in style f or e (or in
 306    * sytle E in the case of a G conversion character), with the precision
 307    * specifying the number of significant digits. If the precision is zero, it is
 308    * taken as one. The style used depends on the value converted: style e (or E)
 309    * will be used only if the exponent resulting from the conversion is less than
 310    * -4 or greater than or equal to the precision. Trailing zeros are removed from
 311    * the result. A radix character appears only if it is followed by a digit.
 312    * <dt>c,C
 313    * <dd>The integer argument is converted to a char and the result is written.
 314    * <dt>s,S
 315    * <dd>The argument is taken to be a string and bytes from the string are
 316    * written until the end of the string or the number of bytes indicated by the
 317    * precision specification of the argument is reached. If the precision is
 318    * omitted from the argument, it is taken to be infinite, so all characters up
 319    * to the end of the string are written.
 320    * <dt>%
 321    * <dd>Write a % character; no argument is converted.
 322    * </dl>
 323    * <p>
 324    * If a conversion specification does not match one of the above forms, an
 325    * IllegalArgumentException is thrown and the instance of PrintfFormat is not
 326    * created.
 327    * </p>
 328    * <p>
 329    * If a floating point value is the internal representation for infinity, the
 330    * output is [+]Infinity, where Infinity is either Infinity or Inf, depending on
 331    * the desired output string length. Printing of the sign follows the rules
 332    * described above.
 333    * </p>
 334    * <p>
 335    * If a floating point value is the internal representation for "not-a-number,"
 336    * the output is [+]NaN. Printing of the sign follows the rules described above.
 337    * </p>
 338    * <p>
 339    * In no case does a non-existent or small field width cause truncation of a
 340    * field; if the result of a conversion is wider than the field width, the field
 341    * is simply expanded to contain the conversion result.
 342    * </p>
 343    * <p>
 344    * The behavior is like printf. One exception is that the minimum number of
 345    * exponent digits is 3 instead of 2 for e and E formats when the optional L is
 346    * used before the e, E, g, or G conversion character. The optional L does not
 347    * imply conversion to a long long double.
 348    * </p>
 349    * <p>
 350    * The biggest divergence from the C printf specification is in the use of 16
 351    * bit characters. This allows the handling of characters beyond the small ASCII
 352    * character set and allows the utility to interoperate correctly with the rest
 353    * of the Java runtime environment.
 354    * </p>
 355    * <p>
 356    * Omissions from the C printf specification are numerous. All the known
 357    * omissions are present because Java never uses bytes to represent characters
 358    * and does not have pointers:
 359    * </p>
 360    * <ul>
 361    * <li>%c is the same as %C.
 362    * <li>%s is the same as %S.
 363    * <li>u, p, and n conversion characters.
 364    * <li>%ws format.
 365    * <li>h modifier applied to an n conversion character.
 366    * <li>l (ell) modifier applied to the c, n, or s conversion characters.
 367    * <li>ll (ell ell) modifier to d, i, o, u, x, or X conversion characters.
 368    * <li>ll (ell ell) modifier to an n conversion character.
 369    * <li>c, C, d,i,o,u,x, and X conversion characters apply to Byte, Character,
 370    * Short, Integer, Long types.
 371    * <li>f, e, E, g, and G conversion characters apply to Float and Double types.
 372    * <li>s and S conversion characters apply to String types.
 373    * <li>All other reference types can be formatted using the s or S conversion
 374    * characters only.
 375    * </ul>
 376    * <p>
 377    * Most of this specification is quoted from the Unix man page for the sprintf
 378    * utility.
 379    * </p>
 380    *
 381    * @version 1 Release 1: Initial release. Release 2: Asterisk field widths and
 382    * precisions %n$ and *m$ Bug fixes g format fix (2 digits in e form
 383    * corrupt) rounding in f format implemented round up when digit not
 384    * printed is 5 formatting of -0.0f round up/down when last digits are
 385    * 50000...
 386    */
 387    public class PrintfFormat {
 388    /**
 389    * Constructs an array of control specifications possibly preceded,
 390    * separated, or followed by ordinary strings. Control strings begin with
 391    * unpaired percent signs. A pair of successive percent signs designates a
 392    * single percent sign in the format.
 393    *
 394    * @param fmtArg Control string.
 395    * @exception IllegalArgumentException if the control string is null, zero
 396    * length, or otherwise malformed.
 397    */
 398  11 public PrintfFormat(String fmtArg) throws IllegalArgumentException {
 399  11 this(Locale.getDefault(), fmtArg);
 400    }
 401   
 402    /**
 403    * Constructs an array of control specifications possibly preceded,
 404    * separated, or followed by ordinary strings. Control strings begin with
 405    * unpaired percent signs. A pair of successive percent signs designates a
 406    * single percent sign in the format.
 407    *
 408    * @param fmtArg Control string.
 409    * @exception IllegalArgumentException if the control string is null, zero
 410    * length, or otherwise malformed.
 411    */
 412  11 public PrintfFormat(Locale locale, String fmtArg) throws IllegalArgumentException {
 413  11 dfs = new DecimalFormatSymbols(locale);
 414  11 int ePos = 0;
 415  11 ConversionSpecification sFmt = null;
 416  11 String unCS = this.nonControl(fmtArg, 0);
 417  11 if (unCS != null) {
 418  11 sFmt = new ConversionSpecification();
 419  11 sFmt.setLiteral(unCS);
 420  11 vFmt.addElement(sFmt);
 421    }
 422  11 while (cPos != -1 && cPos < fmtArg.length()) {
 423  44 for (ePos = cPos + 1; ePos < fmtArg.length(); ePos++) {
 424  44 char c = 0;
 425  44 c = fmtArg.charAt(ePos);
 426  44 if (c == 'i')
 427  0 break;
 428  44 if (c == 'd')
 429  0 break;
 430  44 if (c == 'f')
 431  11 break;
 432  33 if (c == 'g')
 433  0 break;
 434  33 if (c == 'G')
 435  0 break;
 436  33 if (c == 'o')
 437  0 break;
 438  33 if (c == 'x')
 439  0 break;
 440  33 if (c == 'X')
 441  0 break;
 442  33 if (c == 'e')
 443  0 break;
 444  33 if (c == 'E')
 445  0 break;
 446  33 if (c == 'c')
 447  0 break;
 448  33 if (c == 's')
 449  0 break;
 450  33 if (c == '%')
 451  0 break;
 452    }
 453  11 ePos = Math.min(ePos + 1, fmtArg.length());
 454  11 sFmt = new ConversionSpecification(fmtArg.substring(cPos, ePos));
 455  11 vFmt.addElement(sFmt);
 456  11 unCS = this.nonControl(fmtArg, ePos);
 457  11 if (unCS != null) {
 458  11 sFmt = new ConversionSpecification();
 459  11 sFmt.setLiteral(unCS);
 460  11 vFmt.addElement(sFmt);
 461    }
 462    }
 463    }
 464   
 465    /**
 466    * Return a substring starting at <code>start</code> and ending at either
 467    * the end of the String <code>s</code>, the next unpaired percent sign,
 468    * or at the end of the String if the last character is a percent sign.
 469    *
 470    * @param s Control string.
 471    * @param start Position in the string <code>s</code> to begin looking for
 472    * the start of a control string.
 473    * @return the substring from the start position to the beginning of the
 474    * control string.
 475    */
 476  22 private String nonControl(String s, int start) {
 477  22 String ret = "";
 478  22 cPos = s.indexOf("%", start);
 479  22 if (cPos == -1)
 480  11 cPos = s.length();
 481  22 return s.substring(start, cPos);
 482    }
 483   
 484    /**
 485    * Format an array of objects. Byte, Short, Integer, Long, Float, Double,
 486    * and Character arguments are treated as wrappers for primitive types.
 487    *
 488    * @param o The array of objects to format.
 489    * @return The formatted String.
 490    */
 491  0 public String sprintf(Object[] o) {
 492  0 Enumeration e = vFmt.elements();
 493  0 ConversionSpecification cs = null;
 494  0 char c = 0;
 495  0 int i = 0;
 496  0 StringBuffer sb = new StringBuffer();
 497  0 while (e.hasMoreElements()) {
 498  0 cs = (ConversionSpecification) e.nextElement();
 499  0 c = cs.getConversionCharacter();
 500  0 if (c == '\0')
 501  0 sb.append(cs.getLiteral());
 502  0 else if (c == '%')
 503  0 sb.append("%");
 504    else {
 505  0 if (cs.isPositionalSpecification()) {
 506  0 i = cs.getArgumentPosition() - 1;
 507  0 if (cs.isPositionalFieldWidth()) {
 508  0 int ifw = cs.getArgumentPositionForFieldWidth() - 1;
 509  0 cs.setFieldWidthWithArg(((Integer) o[ifw]).intValue());
 510    }
 511  0 if (cs.isPositionalPrecision()) {
 512  0 int ipr = cs.getArgumentPositionForPrecision() - 1;
 513  0 cs.setPrecisionWithArg(((Integer) o[ipr]).intValue());
 514    }
 515    } else {
 516  0 if (cs.isVariableFieldWidth()) {
 517  0 cs.setFieldWidthWithArg(((Integer) o[i]).intValue());
 518  0 i++;
 519    }
 520  0 if (cs.isVariablePrecision()) {
 521  0 cs.setPrecisionWithArg(((Integer) o[i]).intValue());
 522  0 i++;
 523    }
 524    }
 525  0 if (o[i] instanceof Byte)
 526  0 sb.append(cs.internalsprintf(((Byte) o[i]).byteValue()));
 527  0 else if (o[i] instanceof Short)
 528  0 sb.append(cs.internalsprintf(((Short) o[i]).shortValue()));
 529  0 else if (o[i] instanceof Integer)
 530  0 sb.append(cs.internalsprintf(((Integer) o[i]).intValue()));
 531  0 else if (o[i] instanceof Long)
 532  0 sb.append(cs.internalsprintf(((Long) o[i]).longValue()));
 533  0 else if (o[i] instanceof Float)
 534  0 sb.append(cs.internalsprintf(((Float) o[i]).floatValue()));
 535  0 else if (o[i] instanceof Double)
 536  0 sb.append(cs.internalsprintf(((Double) o[i]).doubleValue()));
 537  0 else if (o[i] instanceof Character)
 538  0 sb.append(cs.internalsprintf(((Character) o[i]).charValue()));
 539  0 else if (o[i] instanceof String)
 540  0 sb.append(cs.internalsprintf((String) o[i]));
 541    else
 542  0 sb.append(cs.internalsprintf(o[i]));
 543  0 if (!cs.isPositionalSpecification())
 544  0 i++;
 545    }
 546    }
 547  0 return sb.toString();
 548    }
 549   
 550    /**
 551    * Format nothing. Just use the control string.
 552    *
 553    * @return the formatted String.
 554    */
 555  0 public String sprintf() {
 556  0 Enumeration e = vFmt.elements();
 557  0 ConversionSpecification cs = null;
 558  0 char c = 0;
 559  0 StringBuffer sb = new StringBuffer();
 560  0 while (e.hasMoreElements()) {
 561  0 cs = (ConversionSpecification) e.nextElement();
 562  0 c = cs.getConversionCharacter();
 563  0 if (c == '\0')
 564  0 sb.append(cs.getLiteral());
 565  0 else if (c == '%')
 566  0 sb.append("%");
 567    }
 568  0 return sb.toString();
 569    }
 570   
 571    /**
 572    * Format an int.
 573    *
 574    * @param x The int to format.
 575    * @return The formatted String.
 576    * @exception IllegalArgumentException if the conversion character is f, e,
 577    * E, g, G, s, or S.
 578    */
 579  0 public String sprintf(int x) throws IllegalArgumentException {
 580  0 Enumeration e = vFmt.elements();
 581  0 ConversionSpecification cs = null;
 582  0 char c = 0;
 583  0 StringBuffer sb = new StringBuffer();
 584  0 while (e.hasMoreElements()) {
 585  0 cs = (ConversionSpecification) e.nextElement();
 586  0 c = cs.getConversionCharacter();
 587  0 if (c == '\0')
 588  0 sb.append(cs.getLiteral());
 589  0 else if (c == '%')
 590  0 sb.append("%");
 591    else
 592  0 sb.append(cs.internalsprintf(x));
 593    }
 594  0 return sb.toString();
 595    }
 596   
 597    /**
 598    * Format an long.
 599    *
 600    * @param x The long to format.
 601    * @return The formatted String.
 602    * @exception IllegalArgumentException if the conversion character is f, e,
 603    * E, g, G, s, or S.
 604    */
 605  0 public String sprintf(long x) throws IllegalArgumentException {
 606  0 Enumeration e = vFmt.elements();
 607  0 ConversionSpecification cs = null;
 608  0 char c = 0;
 609  0 StringBuffer sb = new StringBuffer();
 610  0 while (e.hasMoreElements()) {
 611  0 cs = (ConversionSpecification) e.nextElement();
 612  0 c = cs.getConversionCharacter();
 613  0 if (c == '\0')
 614  0 sb.append(cs.getLiteral());
 615  0 else if (c == '%')
 616  0 sb.append("%");
 617    else
 618  0 sb.append(cs.internalsprintf(x));
 619    }
 620  0 return sb.toString();
 621    }
 622   
 623    /**
 624    * Format a double.
 625    *
 626    * @param x The double to format.
 627    * @return The formatted String.
 628    * @exception IllegalArgumentException if the conversion character is c, C,
 629    * s, S, d, d, x, X, or o.
 630    */
 631  11 public String sprintf(double x) throws IllegalArgumentException {
 632  11 Enumeration e = vFmt.elements();
 633  11 ConversionSpecification cs = null;
 634  11 char c = 0;
 635  11 StringBuffer sb = new StringBuffer();
 636  11 while (e.hasMoreElements()) {
 637  33 cs = (ConversionSpecification) e.nextElement();
 638  33 c = cs.getConversionCharacter();
 639  33 if (c == '\0')
 640  22 sb.append(cs.getLiteral());
 641  11 else if (c == '%')
 642  0 sb.append("%");
 643    else
 644  11 sb.append(cs.internalsprintf(x));
 645    }
 646  11 return sb.toString();
 647    }
 648   
 649    /**
 650    * Format a String.
 651    *
 652    * @param x The String to format.
 653    * @return The formatted String.
 654    * @exception IllegalArgumentException if the conversion character is
 655    * neither s nor S.
 656    */
 657  0 public String sprintf(String x) throws IllegalArgumentException {
 658  0 Enumeration e = vFmt.elements();
 659  0 ConversionSpecification cs = null;
 660  0 char c = 0;
 661  0 StringBuffer sb = new StringBuffer();
 662  0 while (e.hasMoreElements()) {
 663  0 cs = (ConversionSpecification) e.nextElement();
 664  0 c = cs.getConversionCharacter();
 665  0 if (c == '\0')
 666  0 sb.append(cs.getLiteral());
 667  0 else if (c == '%')
 668  0 sb.append("%");
 669    else
 670  0 sb.append(cs.internalsprintf(x));
 671    }
 672  0 return sb.toString();
 673    }
 674   
 675    /**
 676    * Format an Object. Convert wrapper types to their primitive equivalents
 677    * and call the appropriate internal formatting method. Convert Strings
 678    * using an internal formatting method for Strings. Otherwise use the
 679    * default formatter (use toString).
 680    *
 681    * @param x the Object to format.
 682    * @return the formatted String.
 683    * @exception IllegalArgumentException if the conversion character is
 684    * inappropriate for formatting an unwrapped value.
 685    */
 686  0 public String sprintf(Object x) throws IllegalArgumentException {
 687  0 Enumeration e = vFmt.elements();
 688  0 ConversionSpecification cs = null;
 689  0 char c = 0;
 690  0 StringBuffer sb = new StringBuffer();
 691  0 while (e.hasMoreElements()) {
 692  0 cs = (ConversionSpecification) e.nextElement();
 693  0 c = cs.getConversionCharacter();
 694  0 if (c == '\0')
 695  0 sb.append(cs.getLiteral());
 696  0 else if (c == '%')
 697  0 sb.append("%");
 698    else {
 699  0 if (x instanceof Byte)
 700  0 sb.append(cs.internalsprintf(((Byte) x).byteValue()));
 701  0 else if (x instanceof Short)
 702  0 sb.append(cs.internalsprintf(((Short) x).shortValue()));
 703  0 else if (x instanceof Integer)
 704  0 sb.append(cs.internalsprintf(((Integer) x).intValue()));
 705  0 else if (x instanceof Long)
 706  0 sb.append(cs.internalsprintf(((Long) x).longValue()));
 707  0 else if (x instanceof Float)
 708  0 sb.append(cs.internalsprintf(((Float) x).floatValue()));
 709  0 else if (x instanceof Double)
 710  0 sb.append(cs.internalsprintf(((Double) x).doubleValue()));
 711  0 else if (x instanceof Character)
 712  0 sb.append(cs.internalsprintf(((Character) x).charValue()));
 713  0 else if (x instanceof String)
 714  0 sb.append(cs.internalsprintf((String) x));
 715    else
 716  0 sb.append(cs.internalsprintf(x));
 717    }
 718    }
 719  0 return sb.toString();
 720    }
 721   
 722    /**
 723    * <p>
 724    * ConversionSpecification allows the formatting of a single primitive or
 725    * object embedded within a string. The formatting is controlled by a format
 726    * string. Only one Java primitive or object can be formatted at a time.
 727    * <p>
 728    * A format string is a Java string that contains a control string. The
 729    * control string starts at the first percent sign (%) in the string,
 730    * provided that this percent sign
 731    * <ol>
 732    * <li>is not escaped protected by a matching % or is not an escape %
 733    * character,
 734    * <li>is not at the end of the format string, and
 735    * <li>precedes a sequence of characters that parses as a valid control
 736    * string.
 737    * </ol>
 738    * <p>
 739    * A control string takes the form:
 740    *
 741    * <pre>
 742    * % ['-+ #0]* [0..9]* { . [0..9]* }+
 743    * { [hlL] }+ [idfgGoxXeEcs]
 744    * </pre>
 745    *
 746    * <p>
 747    * The behavior is like printf. One (hopefully the only) exception is that
 748    * the minimum number of exponent digits is 3 instead of 2 for e and E
 749    * formats when the optional L is used before the e, E, g, or G conversion
 750    * character. The optional L does not imply conversion to a long long
 751    * double.
 752    */
 753    private class ConversionSpecification {
 754    /**
 755    * Constructor. Used to prepare an instance to hold a literal, not a
 756    * control string.
 757    */
 758  22 ConversionSpecification() {
 759    }
 760   
 761    /**
 762    * Constructor for a conversion specification. The argument must begin
 763    * with a % and end with the conversion character for the conversion
 764    * specification.
 765    *
 766    * @param fmtArg String specifying the conversion specification.
 767    * @exception IllegalArgumentException if the input string is null, zero
 768    * length, or otherwise malformed.
 769    */
 770  11 ConversionSpecification(String fmtArg) throws IllegalArgumentException {
 771  11 if (fmtArg == null)
 772  0 throw new NullPointerException();
 773  11 if (fmtArg.length() == 0)
 774  0 throw new IllegalArgumentException("Control strings must have positive" + " lengths.");
 775  11 if (fmtArg.charAt(0) == '%') {
 776  11 fmt = fmtArg;
 777  11 pos = 1;
 778  11 setArgPosition();
 779  11 setFlagCharacters();
 780  11 setFieldWidth();
 781  11 setPrecision();
 782  11 setOptionalHL();
 783  11 if (setConversionCharacter()) {
 784  11 if (pos == fmtArg.length()) {
 785  11 if (leadingZeros && leftJustify)
 786  0 leadingZeros = false;
 787  11 if (precisionSet && leadingZeros) {
 788  0 if (conversionCharacter == 'd' || conversionCharacter == 'i' || conversionCharacter == 'o' || conversionCharacter == 'x') {
 789  0 leadingZeros = false;
 790    }
 791    }
 792    } else
 793  0 throw new IllegalArgumentException("Malformed conversion specification=" + fmtArg);
 794    } else
 795  0 throw new IllegalArgumentException("Malformed conversion specification=" + fmtArg);
 796    } else
 797  0 throw new IllegalArgumentException("Control strings must begin with %.");
 798    }
 799   
 800    /**
 801    * Set the String for this instance.
 802    *
 803    * @param s the String to store.
 804    */
 805  22 void setLiteral(String s) {
 806  22 fmt = s;
 807    }
 808   
 809    /**
 810    * Get the String for this instance. Translate any escape sequences.
 811    *
 812    * @return s the stored String.
 813    */
 814  22 String getLiteral() {
 815  22 StringBuffer sb = new StringBuffer();
 816  22 int i = 0;
 817  22 while (i < fmt.length()) {
 818  0 if (fmt.charAt(i) == '\\') {
 819  0 i++;
 820  0 if (i < fmt.length()) {
 821  0 char c = fmt.charAt(i);
 822  0 switch (c) {
 823  0 case 'a':
 824  0 sb.append((char) 0x07);
 825  0 break;
 826  0 case 'b':
 827  0 sb.append('\b');
 828  0 break;
 829  0 case 'f':
 830  0 sb.append('\f');
 831  0 break;
 832  0 case 'n':
 833  0 sb.append(System.getProperty("line.separator"));
 834  0 break;
 835  0 case 'r':
 836  0 sb.append('\r');
 837  0 break;
 838  0 case 't':
 839  0 sb.append('\t');
 840  0 break;
 841  0 case 'v':
 842  0 sb.append((char) 0x0b);
 843  0 break;
 844  0 case '\\':
 845  0 sb.append('\\');
 846  0 break;
 847    }
 848  0 i++;
 849    } else
 850  0 sb.append('\\');
 851    } else
 852  0 i++;
 853    }
 854  22 return fmt;
 855    }
 856   
 857    /**
 858    * Get the conversion character that tells what type of control
 859    * character this instance has.
 860    *
 861    * @return the conversion character.
 862    */
 863  33 char getConversionCharacter() {
 864  33 return conversionCharacter;
 865    }
 866   
 867    /**
 868    * Check whether the specifier has a variable field width that is going
 869    * to be set by an argument.
 870    *
 871    * @return <code>true</code> if the conversion uses an * field width;
 872    * otherwise <code>false</code>.
 873    */
 874  0 boolean isVariableFieldWidth() {
 875  0 return variableFieldWidth;
 876    }
 877   
 878    /**
 879    * Set the field width with an argument. A negative field width is taken
 880    * as a - flag followed by a positive field width.
 881    *
 882    * @param fw the field width.
 883    */
 884  0 void setFieldWidthWithArg(int fw) {
 885  0 if (fw < 0)
 886  0 leftJustify = true;
 887  0 fieldWidthSet = true;
 888  0 fieldWidth = Math.abs(fw);
 889    }
 890   
 891    /**
 892    * Check whether the specifier has a variable precision that is going to
 893    * be set by an argument.
 894    *
 895    * @return <code>true</code> if the conversion uses an * precision;
 896    * otherwise <code>false</code>.
 897    */
 898  0 boolean isVariablePrecision() {
 899  0 return variablePrecision;
 900    }
 901   
 902    /**
 903    * Set the precision with an argument. A negative precision will be
 904    * changed to zero.
 905    *
 906    * @param pr the precision.
 907    */
 908  0 void setPrecisionWithArg(int pr) {
 909  0 precisionSet = true;
 910  0 precision = Math.max(pr, 0);
 911    }
 912   
 913    /**
 914    * Format an int argument using this conversion specification.
 915    *
 916    * @param s the int to format.
 917    * @return the formatted String.
 918    * @exception IllegalArgumentException if the conversion character is f,
 919    * e, E, g, or G.
 920    */
 921  0 String internalsprintf(int s) throws IllegalArgumentException {
 922  0 String s2 = "";
 923  0 switch (conversionCharacter) {
 924  0 case 'd':
 925  0 case 'i':
 926  0 if (optionalh)
 927  0 s2 = printDFormat((short) s);
 928  0 else if (optionall)
 929  0 s2 = printDFormat((long) s);
 930    else
 931  0 s2 = printDFormat(s);
 932  0 break;
 933  0 case 'x':
 934  0 case 'X':
 935  0 if (optionalh)
 936  0 s2 = printXFormat((short) s);
 937  0 else if (optionall)
 938  0 s2 = printXFormat((long) s);
 939    else
 940  0 s2 = printXFormat(s);
 941  0 break;
 942  0 case 'o':
 943  0 if (optionalh)
 944  0 s2 = printOFormat((short) s);
 945  0 else if (optionall)
 946  0 s2 = printOFormat((long) s);
 947    else
 948  0 s2 = printOFormat(s);
 949  0 break;
 950  0 case 'c':
 951  0 case 'C':
 952  0 s2 = printCFormat((char) s);
 953  0 break;
 954  0 default:
 955  0 throw new IllegalArgumentException("Cannot format a int with a format using a " + conversionCharacter + " conversion character.");
 956    }
 957  0 return s2;
 958    }
 959   
 960    /**
 961    * Format a long argument using this conversion specification.
 962    *
 963    * @param s the long to format.
 964    * @return the formatted String.
 965    * @exception IllegalArgumentException if the conversion character is f,
 966    * e, E, g, or G.
 967    */
 968  0 String internalsprintf(long s) throws IllegalArgumentException {
 969  0 String s2 = "";
 970  0 switch (conversionCharacter) {
 971  0 case 'd':
 972  0 case 'i':
 973  0 if (optionalh)
 974  0 s2 = printDFormat((short) s);
 975  0 else if (optionall)
 976  0 s2 = printDFormat(s);
 977    else
 978  0 s2 = printDFormat((int) s);
 979  0 break;
 980  0 case 'x':
 981  0 case 'X':
 982  0 if (optionalh)
 983  0 s2 = printXFormat((short) s);
 984  0 else if (optionall)
 985  0 s2 = printXFormat(s);
 986    else
 987  0 s2 = printXFormat((int) s);
 988  0 break;
 989  0 case 'o':
 990  0 if (optionalh)
 991  0 s2 = printOFormat((short) s);
 992  0 else if (optionall)
 993  0 s2 = printOFormat(s);
 994    else
 995  0 s2 = printOFormat((int) s);
 996  0 break;
 997  0 case 'c':
 998  0 case 'C':
 999  0 s2 = printCFormat((char) s);
 1000  0 break;
 1001  0 default:
 1002  0 throw new IllegalArgumentException("Cannot format a long with a format using a " + conversionCharacter + " conversion character.");
 1003    }
 1004  0 return s2;
 1005    }
 1006   
 1007    /**
 1008    * Format a double argument using this conversion specification.
 1009    *
 1010    * @param s the double to format.
 1011    * @return the formatted String.
 1012    * @exception IllegalArgumentException if the conversion character is c,
 1013    * C, s, S, i, d, x, X, or o.
 1014    */
 1015  11 String internalsprintf(double s) throws IllegalArgumentException {
 1016  11 String s2 = "";
 1017  11 switch (conversionCharacter) {
 1018  11 case 'f':
 1019  11 s2 = printFFormat(s);
 1020  11 break;
 1021  0 case 'E':
 1022  0 case 'e':
 1023  0 s2 = printEFormat(s);
 1024  0 break;
 1025  0 case 'G':
 1026  0 case 'g':
 1027  0 s2 = printGFormat(s);
 1028  0 break;
 1029  0 default:
 1030  0 throw new IllegalArgumentException("Cannot " + "format a double with a format using a " + conversionCharacter + " conversion character.");
 1031    }
 1032  11 return s2;
 1033    }
 1034   
 1035    /**
 1036    * Format a String argument using this conversion specification.
 1037    *
 1038    * @param s the String to format.
 1039    * @return the formatted String.
 1040    * @exception IllegalArgumentException if the conversion character is
 1041    * neither s nor S.
 1042    */
 1043  0 String internalsprintf(String s) throws IllegalArgumentException {
 1044  0 String s2 = "";
 1045  0 if (conversionCharacter == 's' || conversionCharacter == 'S')
 1046  0 s2 = printSFormat(s);
 1047    else
 1048  0 throw new IllegalArgumentException("Cannot " + "format a String with a format using a " + conversionCharacter + " conversion character.");
 1049  0 return s2;
 1050    }
 1051   
 1052    /**
 1053    * Format an Object argument using this conversion specification.
 1054    *
 1055    * @param s the Object to format.
 1056    * @return the formatted String.
 1057    * @exception IllegalArgumentException if the conversion character is
 1058    * neither s nor S.
 1059    */
 1060  0 String internalsprintf(Object s) {
 1061  0 String s2 = "";
 1062  0 if (conversionCharacter == 's' || conversionCharacter == 'S')
 1063  0 s2 = printSFormat(s.toString());
 1064    else
 1065  0 throw new IllegalArgumentException("Cannot format a String with a format using" + " a " + conversionCharacter + " conversion character.");
 1066  0 return s2;
 1067    }
 1068   
 1069    /**
 1070    * For f format, the flag character '-', means that the output should be
 1071    * left justified within the field. The default is to pad with blanks on
 1072    * the left. '+' character means that the conversion will always begin
 1073    * with a sign (+ or -). The blank flag character means that a
 1074    * non-negative input will be preceded with a blank. If both a '+' and a ' '
 1075    * are specified, the blank flag is ignored. The '0' flag character
 1076    * implies that padding to the field width will be done with zeros
 1077    * instead of blanks. The field width is treated as the minimum number
 1078    * of characters to be printed. The default is to add no padding.
 1079    * Padding is with blanks by default. The precision, if set, is the
 1080    * number of digits to appear after the radix character. Padding is with
 1081    * trailing 0s.
 1082    */
 1083  11 private char[] fFormatDigits(double x) {
 1084    // int defaultDigits=6;
 1085  11 String sx, sxOut;
 1086  11 int i, j, k;
 1087  11 int n1In, n2In;
 1088  11 int expon = 0;
 1089  11 boolean minusSign = false;
 1090  11 if (x > 0.0)
 1091  11 sx = Double.toString(x);
 1092  0 else if (x < 0.0) {
 1093  0 sx = Double.toString(-x);
 1094  0 minusSign = true;
 1095    } else {
 1096  0 sx = Double.toString(x);
 1097  0 if (sx.charAt(0) == '-') {
 1098  0 minusSign = true;
 1099  0 sx = sx.substring(1);
 1100    }
 1101    }
 1102  11 int ePos = sx.indexOf('E');
 1103  11 int rPos = sx.indexOf('.');
 1104  11 if (rPos != -1)
 1105  11 n1In = rPos;
 1106  0 else if (ePos != -1)
 1107  0 n1In = ePos;
 1108    else
 1109  0 n1In = sx.length();
 1110  11 if (rPos != -1) {
 1111  11 if (ePos != -1)
 1112  2 n2In = ePos - rPos - 1;
 1113    else
 1114  9 n2In = sx.length() - rPos - 1;
 1115    } else
 1116  0 n2In = 0;
 1117  11 if (ePos != -1) {
 1118  2 int ie = ePos + 1;
 1119  2 expon = 0;
 1120  2 if (sx.charAt(ie) == '-') {
 1121  0 for (++ie; ie < sx.length(); ie++)
 1122  0 if (sx.charAt(ie) != '0')
 1123  0 break;
 1124  0 if (ie < sx.length())
 1125  0 expon = -Integer.parseInt(sx.substring(ie));
 1126    } else {
 1127  2 if (sx.charAt(ie) == '+')
 1128  0 ++ie;
 1129  2 for (; ie < sx.length(); ie++)
 1130  2 if (sx.charAt(ie) != '0')
 1131  2 break;
 1132  2 if (ie < sx.length())
 1133  2 expon = Integer.parseInt(sx.substring(ie));
 1134    }
 1135    }
 1136  11 int p;
 1137  11 if (precisionSet)
 1138  11 p = precision;
 1139    else
 1140  0 p = defaultDigits - 1;
 1141  11 char[] ca1 = sx.toCharArray();
 1142  11 char[] ca2 = new char[n1In + n2In];
 1143  11 char[] ca3, ca4, ca5;
 1144  11 for (j = 0; j < n1In; j++)
 1145  46 ca2[j] = ca1[j];
 1146  11 i = j + 1;
 1147  11 for (k = 0; k < n2In; j++, i++, k++)
 1148  27 ca2[j] = ca1[i];
 1149  11 if (n1In + expon <= 0) {
 1150  0 ca3 = new char[-expon + n2In];
 1151  0 for (j = 0, k = 0; k < (-n1In - expon); k++, j++)
 1152  0 ca3[j] = '0';
 1153  0 for (i = 0; i < (n1In + n2In); i++, j++)
 1154  0 ca3[j] = ca2[i];
 1155    } else
 1156  11 ca3 = ca2;
 1157  11 boolean carry = false;
 1158  11 if (p < -expon + n2In) {
 1159  2 if (expon < 0)
 1160  0 i = p;
 1161    else
 1162  2 i = p + n1In;
 1163  2 carry = checkForCarry(ca3, i);
 1164  2 if (carry)
 1165  0 carry = startSymbolicCarry(ca3, i - 1, 0);
 1166    }
 1167  11 if (n1In + expon <= 0) {
 1168  0 ca4 = new char[2 + p];
 1169  0 if (!carry)
 1170  0 ca4[0] = '0';
 1171    else
 1172  0 ca4[0] = '1';
 1173  0 if (alternateForm || !precisionSet || precision != 0) {
 1174  0 ca4[1] = '.';
 1175  0 for (i = 0, j = 2; i < Math.min(p, ca3.length); i++, j++)
 1176  0 ca4[j] = ca3[i];
 1177  0 for (; j < ca4.length; j++)
 1178  0 ca4[j] = '0';
 1179    }
 1180    } else {
 1181  11 if (!carry) {
 1182  11 if (alternateForm || !precisionSet || precision != 0)
 1183  11 ca4 = new char[n1In + expon + p + 1];
 1184    else
 1185  0 ca4 = new char[n1In + expon];
 1186  11 j = 0;
 1187    } else {
 1188  0 if (alternateForm || !precisionSet || precision != 0)
 1189  0 ca4 = new char[n1In + expon + p + 2];
 1190    else
 1191  0 ca4 = new char[n1In + expon + 1];
 1192  0 ca4[0] = '1';
 1193  0 j = 1;
 1194    }
 1195  11 for (i = 0; i < Math.min(n1In + expon, ca3.length); i++, j++)
 1196  55 ca4[j] = ca3[i];
 1197  11 for (; i < n1In + expon; i++, j++)
 1198  5 ca4[j] = '0';
 1199  11 if (alternateForm || !precisionSet || precision != 0) {
 1200  11 ca4[j] = '.';
 1201  11 j++;
 1202  11 for (k = 0; i < ca3.length && k < p; i++, j++, k++)
 1203  16 ca4[j] = ca3[i];
 1204  11 for (; j < ca4.length; j++)
 1205  9 ca4[j] = '0';
 1206    }
 1207    }
 1208  11 int nZeros = 0;
 1209  11 if (!leftJustify && leadingZeros) {
 1210  0 int xThousands = 0;
 1211  0 if (thousands) {
 1212  0 int xlead = 0;
 1213  0 if (ca4[0] == '+' || ca4[0] == '-' || ca4[0] == ' ')
 1214  0 xlead = 1;
 1215  0 int xdp = xlead;
 1216  0 for (; xdp < ca4.length; xdp++)
 1217  0 if (ca4[xdp] == '.')
 1218  0 break;
 1219  0 xThousands = (xdp - xlead) / 3;
 1220    }
 1221  0 if (fieldWidthSet)
 1222  0 nZeros = fieldWidth - ca4.length;
 1223  0 if ((!minusSign && (leadingSign || leadingSpace)) || minusSign)
 1224  0 nZeros--;
 1225  0 nZeros -= xThousands;
 1226  0 if (nZeros < 0)
 1227  0 nZeros = 0;
 1228    }
 1229  11 j = 0;
 1230  11 if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
 1231  0 ca5 = new char[ca4.length + nZeros + 1];
 1232  0 j++;
 1233    } else
 1234  11 ca5 = new char[ca4.length + nZeros];
 1235  11 if (!minusSign) {
 1236  11 if (leadingSign)
 1237  0 ca5[0] = '+';
 1238  11 if (leadingSpace)
 1239  0 ca5[0] = ' ';
 1240    } else
 1241  0 ca5[0] = '-';
 1242  11 for (i = 0; i < nZeros; i++, j++)
 1243  0 ca5[j] = '0';
 1244  11 for (i = 0; i < ca4.length; i++, j++)
 1245  96 ca5[j] = ca4[i];
 1246   
 1247  11 int lead = 0;
 1248  11 if (ca5[0] == '+' || ca5[0] == '-' || ca5[0] == ' ')
 1249  0 lead = 1;
 1250  11 int dp = lead;
 1251  71 for (; dp < ca5.length; dp++)
 1252  71 if (ca5[dp] == '.')
 1253  11 break;
 1254  11 int nThousands = (dp - lead) / 3;
 1255    // Localize the decimal point.
 1256  11 if (dp < ca5.length)
 1257  11 ca5[dp] = dfs.getDecimalSeparator();
 1258  11 char[] ca6 = ca5;
 1259  11 if (thousands && nThousands > 0) {
 1260  0 ca6 = new char[ca5.length + nThousands + lead];
 1261  0 ca6[0] = ca5[0];
 1262  0 for (i = lead, k = lead; i < dp; i++) {
 1263  0 if (i > 0 && (dp - i) % 3 == 0) {
 1264    // ca6[k]=',';
 1265  0 ca6[k] = dfs.getGroupingSeparator();
 1266  0 ca6[k + 1] = ca5[i];
 1267  0 k += 2;
 1268    } else {
 1269  0 ca6[k] = ca5[i];
 1270  0 k++;
 1271    }
 1272    }
 1273  0 for (; i < ca5.length; i++, k++) {
 1274  0 ca6[k] = ca5[i];
 1275    }
 1276    }
 1277  11 return ca6;
 1278    }
 1279   
 1280    /**
 1281    * An intermediate routine on the way to creating an f format String.
 1282    * The method decides whether the input double value is an infinity,
 1283    * not-a-number, or a finite double and formats each type of input
 1284    * appropriately.
 1285    *
 1286    * @param x the double value to be formatted.
 1287    * @return the converted double value.
 1288    */
 1289  11 private String fFormatString(double x) {
 1290  11 boolean noDigits = false;
 1291  11 char[] ca6, ca7;
 1292  11 if (Double.isInfinite(x)) {
 1293  0 if (x == Double.POSITIVE_INFINITY) {
 1294  0 if (leadingSign)
 1295  0 ca6 = "+Inf".toCharArray();
 1296  0 else if (leadingSpace)
 1297  0 ca6 = " Inf".toCharArray();
 1298    else
 1299  0 ca6 = "Inf".toCharArray();
 1300    } else
 1301  0 ca6 = "-Inf".toCharArray();
 1302  0 noDigits = true;
 1303  11 } else if (Double.isNaN(x)) {
 1304  0 if (leadingSign)
 1305  0 ca6 = "+NaN".toCharArray();
 1306  0 else if (leadingSpace)
 1307  0 ca6 = " NaN".toCharArray();
 1308    else
 1309  0 ca6 = "NaN".toCharArray();
 1310  0 noDigits = true;
 1311    } else
 1312  11 ca6 = fFormatDigits(x);
 1313  11 ca7 = applyFloatPadding(ca6, false);
 1314  11 return new String(ca7);
 1315    }
 1316   
 1317    /**
 1318    * For e format, the flag character '-', means that the output should be
 1319    * left justified within the field. The default is to pad with blanks on
 1320    * the left. '+' character means that the conversion will always begin
 1321    * with a sign (+ or -). The blank flag character means that a
 1322    * non-negative input will be preceded with a blank. If both a '+' and a ' '
 1323    * are specified, the blank flag is ignored. The '0' flag character
 1324    * implies that padding to the field width will be done with zeros
 1325    * instead of blanks. The field width is treated as the minimum number
 1326    * of characters to be printed. The default is to add no padding.
 1327    * Padding is with blanks by default. The precision, if set, is the
 1328    * minimum number of digits to appear after the radix character. Padding
 1329    * is with trailing 0s. The behavior is like printf. One (hopefully the
 1330    * only) exception is that the minimum number of exponent digits is 3
 1331    * instead of 2 for e and E formats when the optional L is used before
 1332    * the e, E, g, or G conversion character. The optional L does not imply
 1333    * conversion to a long long double.
 1334    */
 1335  0 private char[] eFormatDigits(double x, char eChar) {
 1336  0 char[] ca1, ca2, ca3;
 1337    // int defaultDigits=6;
 1338  0 String sx, sxOut;
 1339  0 int i, j, k, p;
 1340  0 int n1In, n2In;
 1341  0 int expon = 0;
 1342  0 int ePos, rPos, eSize;
 1343  0 boolean minusSign = false;
 1344  0 if (x > 0.0)
 1345  0 sx = Double.toString(x);
 1346  0 else if (x < 0.0) {
 1347  0 sx = Double.toString(-x);
 1348  0 minusSign = true;
 1349    } else {
 1350  0 sx = Double.toString(x);
 1351  0 if (sx.charAt(0) == '-') {
 1352  0 minusSign = true;
 1353  0 sx = sx.substring(1);
 1354    }
 1355    }
 1356  0 ePos = sx.indexOf('E');
 1357  0 if (ePos == -1)
 1358  0 ePos = sx.indexOf('e');
 1359  0 rPos = sx.indexOf('.');
 1360  0 if (rPos != -1)
 1361  0 n1In = rPos;
 1362  0 else if (ePos != -1)
 1363  0 n1In = ePos;
 1364    else
 1365  0 n1In = sx.length();
 1366  0 if (rPos != -1) {
 1367  0 if (ePos != -1)
 1368  0 n2In = ePos - rPos - 1;
 1369    else
 1370  0 n2In = sx.length() - rPos - 1;
 1371    } else
 1372  0 n2In = 0;
 1373  0 if (ePos != -1) {
 1374  0 int ie = ePos + 1;
 1375  0 expon = 0;
 1376  0 if (sx.charAt(ie) == '-') {
 1377  0 for (++ie; ie < sx.length(); ie++)
 1378  0 if (sx.charAt(ie) != '0')
 1379  0 break;
 1380  0 if (ie < sx.length())
 1381  0 expon = -Integer.parseInt(sx.substring(ie));
 1382    } else {
 1383  0 if (sx.charAt(ie) == '+')
 1384  0 ++ie;
 1385  0 for (; ie < sx.length(); ie++)
 1386  0 if (sx.charAt(ie) != '0')
 1387  0 break;
 1388  0 if (ie < sx.length())
 1389  0 expon = Integer.parseInt(sx.substring(ie));
 1390    }
 1391    }
 1392  0 if (rPos != -1)
 1393  0 expon += rPos - 1;
 1394  0 if (precisionSet)
 1395  0 p = precision;
 1396    else
 1397  0 p = defaultDigits - 1;
 1398  0 if (rPos != -1 && ePos != -1)
 1399  0 ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1, ePos)).toCharArray();
 1400  0 else if (rPos != -1)
 1401  0 ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1)).toCharArray();
 1402  0 else if (ePos != -1)
 1403  0 ca1 = sx.substring(0, ePos).toCharArray();
 1404    else
 1405  0 ca1 = sx.toCharArray();
 1406  0 boolean carry = false;
 1407  0 int i0 = 0;
 1408  0 if (ca1[0] != '0')
 1409  0 i0 = 0;
 1410    else
 1411  0 for (i0 = 0; i0 < ca1.length; i0++)
 1412  0 if (ca1[i0] != '0')
 1413  0 break;
 1414  0 if (i0 + p < ca1.length - 1) {
 1415  0 carry = checkForCarry(ca1, i0 + p + 1);
 1416  0 if (carry)
 1417  0 carry = startSymbolicCarry(ca1, i0 + p, i0);
 1418  0 if (carry) {
 1419  0 ca2 = new char[i0 + p + 1];
 1420  0 ca2[i0] = '1';
 1421  0 for (j = 0; j < i0; j++)
 1422  0 ca2[j] = '0';
 1423  0 for (i = i0, j = i0 + 1; j < p + 1; i++, j++)
 1424  0 ca2[j] = ca1[i];
 1425  0 expon++;
 1426  0 ca1 = ca2;
 1427    }
 1428    }
 1429  0 if (Math.abs(expon) < 100 && !optionalL)
 1430  0 eSize = 4;
 1431    else
 1432  0 eSize = 5;
 1433  0 if (alternateForm || !precisionSet || precision != 0)
 1434  0 ca2 = new char[2 + p + eSize];
 1435    else
 1436  0 ca2 = new char[1 + eSize];
 1437  0 if (ca1[0] != '0') {
 1438  0 ca2[0] = ca1[0];
 1439  0 j = 1;
 1440    } else {
 1441  0 for (j = 1; j < (ePos == -1 ? ca1.length : ePos); j++)
 1442  0 if (ca1[j] != '0')
 1443  0 break;
 1444  0 if ((ePos != -1 && j < ePos) || (ePos == -1 && j < ca1.length)) {
 1445  0 ca2[0] = ca1[j];
 1446  0 expon -= j;
 1447  0 j++;
 1448    } else {
 1449  0 ca2[0] = '0';
 1450  0 j = 2;
 1451    }
 1452    }
 1453  0 if (alternateForm || !precisionSet || precision != 0) {
 1454  0 ca2[1] = '.';
 1455  0 i = 2;
 1456    } else
 1457  0 i = 1;
 1458  0 for (k = 0; k < p && j < ca1.length; j++, i++, k++)
 1459  0 ca2[i] = ca1[j];
 1460  0 for (; i < ca2.length - eSize; i++)
 1461  0 ca2[i] = '0';
 1462  0 ca2[i++] = eChar;
 1463  0 if (expon < 0)
 1464  0 ca2[i++] = '-';
 1465    else
 1466  0 ca2[i++] = '+';
 1467  0 expon = Math.abs(expon);
 1468  0 if (expon >= 100) {
 1469  0 switch (expon / 100) {
 1470  0 case 1:
 1471  0 ca2[i] = '1';
 1472  0 break;
 1473  0 case 2:
 1474  0 ca2[i] = '2';
 1475  0 break;
 1476  0 case 3:
 1477  0 ca2[i] = '3';
 1478  0 break;
 1479  0 case 4:
 1480  0 ca2[i] = '4';
 1481  0 break;
 1482  0 case 5:
 1483  0 ca2[i] = '5';
 1484  0 break;
 1485  0 case 6:
 1486  0 ca2[i] = '6';
 1487  0 break;
 1488  0 case 7:
 1489  0 ca2[i] = '7';
 1490  0 break;
 1491  0 case 8:
 1492  0 ca2[i] = '8';
 1493  0 break;
 1494  0 case 9:
 1495  0 ca2[i] = '9';
 1496  0 break;
 1497    }
 1498  0 i++;
 1499    }
 1500  0 switch ((expon % 100) / 10) {
 1501  0 case 0:
 1502  0 ca2[i] = '0';
 1503  0 break;
 1504  0 case 1:
 1505  0 ca2[i] = '1';
 1506  0 break;
 1507  0 case 2:
 1508  0 ca2[i] = '2';
 1509  0 break;
 1510  0 case 3:
 1511  0 ca2[i] = '3';
 1512  0 break;
 1513  0 case 4:
 1514  0 ca2[i] = '4';
 1515  0 break;
 1516  0 case 5:
 1517  0 ca2[i] = '5';
 1518  0 break;
 1519  0 case 6:
 1520  0 ca2[i] = '6';
 1521  0 break;
 1522  0 case 7:
 1523  0 ca2[i] = '7';
 1524  0 break;
 1525  0 case 8:
 1526  0 ca2[i] = '8';
 1527  0 break;
 1528  0 case 9:
 1529  0 ca2[i] = '9';
 1530  0 break;
 1531    }
 1532  0 i++;
 1533  0 switch (expon % 10) {
 1534  0 case 0:
 1535  0 ca2[i] = '0';
 1536  0 break;
 1537  0 case 1:
 1538  0 ca2[i] = '1';
 1539  0 break;
 1540  0 case 2:
 1541  0 ca2[i] = '2';
 1542  0 break;
 1543  0 case 3:
 1544  0 ca2[i] = '3';
 1545  0 break;
 1546  0 case 4:
 1547  0 ca2[i] = '4';
 1548  0 break;
 1549  0 case 5:
 1550  0 ca2[i] = '5';
 1551  0 break;
 1552  0 case 6:
 1553  0 ca2[i] = '6';
 1554  0 break;
 1555  0 case 7:
 1556  0 ca2[i] = '7';
 1557  0 break;
 1558  0 case 8:
 1559  0 ca2[i] = '8';
 1560  0 break;
 1561  0 case 9:
 1562  0 ca2[i] = '9';
 1563  0 break;
 1564    }
 1565  0 int nZeros = 0;
 1566  0 if (!leftJustify && leadingZeros) {
 1567  0 int xThousands = 0;
 1568  0 if (thousands) {
 1569  0 int xlead = 0;
 1570  0 if (ca2[0] == '+' || ca2[0] == '-' || ca2[0] == ' ')
 1571  0 xlead = 1;
 1572  0 int xdp = xlead;
 1573  0 for (; xdp < ca2.length; xdp++)
 1574  0 if (ca2[xdp] == '.')
 1575  0 break;
 1576  0 xThousands = (xdp - xlead) / 3;
 1577    }
 1578  0 if (fieldWidthSet)
 1579  0 nZeros = fieldWidth - ca2.length;
 1580  0 if ((!minusSign && (leadingSign || leadingSpace)) || minusSign)
 1581  0 nZeros--;
 1582  0 nZeros -= xThousands;
 1583  0 if (nZeros < 0)
 1584  0 nZeros = 0;
 1585    }
 1586  0 j = 0;
 1587  0 if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
 1588  0 ca3 = new char[ca2.length + nZeros + 1];
 1589  0 j++;
 1590    } else
 1591  0 ca3 = new char[ca2.length + nZeros];
 1592  0 if (!minusSign) {
 1593  0 if (leadingSign)
 1594  0 ca3[0] = '+';
 1595  0 if (leadingSpace)
 1596  0 ca3[0] = ' ';
 1597    } else
 1598  0 ca3[0] = '-';
 1599  0 for (k = 0; k < nZeros; j++, k++)
 1600  0 ca3[j] = '0';
 1601  0 for (i = 0; i < ca2.length && j < ca3.length; i++, j++)
 1602  0 ca3[j] = ca2[i];
 1603   
 1604  0 int lead = 0;
 1605  0 if (ca3[0] == '+' || ca3[0] == '-' || ca3[0] == ' ')
 1606  0 lead = 1;
 1607  0 int dp = lead;
 1608  0 for (; dp < ca3.length; dp++)
 1609  0 if (ca3[dp] == '.')
 1610  0 break;
 1611  0 int nThousands = dp / 3;
 1612    // Localize the decimal point.
 1613  0 if (dp < ca3.length)
 1614  0 ca3[dp] = dfs.getDecimalSeparator();
 1615  0 char[] ca4 = ca3;
 1616  0 if (thousands && nThousands > 0) {
 1617  0 ca4 = new char[ca3.length + nThousands + lead];
 1618  0 ca4[0] = ca3[0];
 1619  0 for (i = lead, k = lead; i < dp; i++) {
 1620  0 if (i > 0 && (dp - i) % 3 == 0) {
 1621    // ca4[k]=',';
 1622  0 ca4[k] = dfs.getGroupingSeparator();
 1623  0 ca4[k + 1] = ca3[i];
 1624  0 k += 2;
 1625    } else {
 1626  0 ca4[k] = ca3[i];
 1627  0 k++;
 1628    }
 1629    }
 1630  0 for (; i < ca3.length; i++, k++)
 1631  0 ca4[k] = ca3[i];
 1632    }
 1633  0 return ca4;
 1634    }
 1635   
 1636    /**
 1637    * Check to see if the digits that are going to be truncated because of
 1638    * the precision should force a round in the preceding digits.
 1639    *
 1640    * @param ca1 the array of digits
 1641    * @param icarry the index of the first digit that is to be truncated
 1642    * from the print
 1643    * @return <code>true</code> if the truncation forces a round that
 1644    * will change the print
 1645    */
 1646  2 private boolean checkForCarry(char[] ca1, int icarry) {
 1647  2 boolean carry = false;
 1648  2 if (icarry < ca1.length) {
 1649  2 if (ca1[icarry] == '6' || ca1[icarry] == '7' || ca1[icarry] == '8' || ca1[icarry] == '9')
 1650  0 carry = true;
 1651  2 else if (ca1[icarry] == '5') {
 1652  0 int ii = icarry + 1;
 1653  0 for (; ii < ca1.length; ii++)
 1654  0 if (ca1[ii] != '0')
 1655  0 break;
 1656  0 carry = ii < ca1.length;
 1657  0 if (!carry && icarry > 0) {
 1658  0 carry = (ca1[icarry - 1] == '1' || ca1[icarry - 1] == '3' || ca1[icarry - 1] == '5' || ca1[icarry - 1] == '7' || ca1[icarry - 1] == '9');
 1659    }
 1660    }
 1661    }
 1662  2 return carry;
 1663    }
 1664   
 1665    /**
 1666    * Start the symbolic carry process. The process is not quite finished
 1667    * because the symbolic carry may change the length of the string and
 1668    * change the exponent (in e format).
 1669    *
 1670    * @param cLast index of the last digit changed by the round
 1671    * @param cFirst index of the first digit allowed to be changed by this
 1672    * phase of the round
 1673    * @return <code>true</code> if the carry forces a round that will
 1674    * change the print still more
 1675    */
 1676  0 private boolean startSymbolicCarry(char[] ca, int cLast, int cFirst) {
 1677  0 boolean carry = true;
 1678  0 for (int i = cLast; carry && i >= cFirst; i--) {
 1679  0 carry = false;
 1680  0 switch (ca[i]) {
 1681  0 case '0':
 1682  0 ca[i] = '1';
 1683  0 break;
 1684  0 case '1':
 1685  0 ca[i] = '2';
 1686  0 break;
 1687  0 case '2':
 1688  0 ca[i] = '3';
 1689  0 break;
 1690  0 case '3':
 1691  0 ca[i] = '4';
 1692  0 break;
 1693  0 case '4':
 1694  0 ca[i] = '5';
 1695  0 break;
 1696  0 case '5':
 1697  0 ca[i] = '6';
 1698  0 break;
 1699  0 case '6':
 1700  0 ca[i] = '7';
 1701  0 break;
 1702  0 case '7':
 1703  0 ca[i] = '8';
 1704  0 break;
 1705  0 case '8':
 1706  0 ca[i] = '9';
 1707  0 break;
 1708  0 case '9':
 1709  0 ca[i] = '0';
 1710  0 carry = true;
 1711  0 break;
 1712    }
 1713    }
 1714  0 return carry;
 1715    }
 1716   
 1717    /**
 1718    * An intermediate routine on the way to creating an e format String.
 1719    * The method decides whether the input double value is an infinity,
 1720    * not-a-number, or a finite double and formats each type of input
 1721    * appropriately.
 1722    *
 1723    * @param x the double value to be formatted.
 1724    * @param eChar an 'e' or 'E' to use in the converted double value.
 1725    * @return the converted double value.
 1726    */
 1727  0 private String eFormatString(double x, char eChar) {
 1728  0 boolean noDigits = false;
 1729  0 char[] ca4, ca5;
 1730  0 if (Double.isInfinite(x)) {
 1731  0 if (x == Double.POSITIVE_INFINITY) {
 1732  0 if (leadingSign)
 1733  0 ca4 = "+Inf".toCharArray();
 1734  0 else if (leadingSpace)
 1735  0 ca4 = " Inf".toCharArray();
 1736    else
 1737  0 ca4 = "Inf".toCharArray();
 1738    } else
 1739  0 ca4 = "-Inf".toCharArray();
 1740  0 noDigits = true;
 1741  0 } else if (Double.isNaN(x)) {
 1742  0 if (leadingSign)
 1743  0 ca4 = "+NaN".toCharArray();
 1744  0 else if (leadingSpace)
 1745  0 ca4 = " NaN".toCharArray();
 1746    else
 1747  0 ca4 = "NaN".toCharArray();
 1748  0 noDigits = true;
 1749    } else
 1750  0 ca4 = eFormatDigits(x, eChar);
 1751  0 ca5 = applyFloatPadding(ca4, false);
 1752  0 return new String(ca5);
 1753    }
 1754   
 1755    /**
 1756    * Apply zero or blank, left or right padding.
 1757    *
 1758    * @param ca4 array of characters before padding is finished
 1759    * @param noDigits NaN or signed Inf
 1760    * @return a padded array of characters
 1761    */
 1762  11 private char[] applyFloatPadding(char[] ca4, boolean noDigits) {
 1763  11 char[] ca5 = ca4;
 1764  11 if (fieldWidthSet) {
 1765  0 int i, j, nBlanks;
 1766  0 if (leftJustify) {
 1767  0 nBlanks = fieldWidth - ca4.length;
 1768  0 if (nBlanks > 0) {
 1769  0 ca5 = new char[ca4.length + nBlanks];
 1770  0 for (i = 0; i < ca4.length; i++)
 1771  0 ca5[i] = ca4[i];
 1772  0 for (j = 0; j < nBlanks; j++, i++)
 1773  0 ca5[i] = ' ';
 1774    }
 1775  0 } else if (!leadingZeros || noDigits) {
 1776  0 nBlanks = fieldWidth - ca4.length;
 1777  0 if (nBlanks > 0) {
 1778  0 ca5 = new char[ca4.length + nBlanks];
 1779  0 for (i = 0; i < nBlanks; i++)
 1780  0 ca5[i] = ' ';
 1781  0 for (j = 0; j < ca4.length; i++, j++)
 1782  0 ca5[i] = ca4[j];
 1783    }
 1784  0 } else if (leadingZeros) {
 1785  0 nBlanks = fieldWidth - ca4.length;
 1786  0 if (nBlanks > 0) {
 1787  0 ca5 = new char[ca4.length + nBlanks];
 1788  0 i = 0;
 1789  0 j = 0;
 1790  0 if (ca4[0] == '-') {
 1791  0 ca5[0] = '-';
 1792  0 i++;
 1793  0 j++;
 1794    }
 1795  0 for (int k = 0; k < nBlanks; i++, k++)
 1796  0 ca5[i] = '0';
 1797  0 for (; j < ca4.length; i++, j++)
 1798  0 ca5[i] = ca4[j];
 1799    }
 1800    }
 1801    }
 1802  11 return ca5;
 1803    }
 1804   
 1805    /**
 1806    * Format method for the f conversion character.
 1807    *
 1808    * @param x the double to format.
 1809    * @return the formatted String.
 1810    */
 1811  11 private String printFFormat(double x) {
 1812  11 return fFormatString(x);
 1813    }
 1814   
 1815    /**
 1816    * Format method for the e or E conversion character.
 1817    *
 1818    * @param x the double to format.
 1819    * @return the formatted String.
 1820    */
 1821  0 private String printEFormat(double x) {
 1822  0 if (conversionCharacter == 'e')
 1823  0 return eFormatString(x, 'e');
 1824    else
 1825  0 return eFormatString(x, 'E');
 1826    }
 1827   
 1828    /**
 1829    * Format method for the g conversion character. For g format, the flag
 1830    * character '-', means that the output should be left justified within
 1831    * the field. The default is to pad with blanks on the left. '+'
 1832    * character means that the conversion will always begin with a sign (+
 1833    * or -). The blank flag character means that a non-negative input will
 1834    * be preceded with a blank. If both a '+' and a ' ' are specified, the
 1835    * blank flag is ignored. The '0' flag character implies that padding to
 1836    * the field width will be done with zeros instead of blanks. The field
 1837    * width is treated as the minimum number of characters to be printed.
 1838    * The default is to add no padding. Padding is with blanks by default.
 1839    * The precision, if set, is the minimum number of digits to appear
 1840    * after the radix character. Padding is with trailing 0s.
 1841    *
 1842    * @param x the double to format.
 1843    * @return the formatted String.
 1844    */
 1845  0 private String printGFormat(double x) {
 1846  0 String sx, sy, sz, ret;
 1847  0 int savePrecision = precision;
 1848  0 int i;
 1849  0 char[] ca4, ca5;
 1850  0 boolean noDigits = false;
 1851  0 if (Double.isInfinite(x)) {
 1852  0 if (x == Double.POSITIVE_INFINITY) {
 1853  0 if (leadingSign)
 1854  0 ca4 = "+Inf".toCharArray();
 1855  0 else if (leadingSpace)
 1856  0 ca4 = " Inf".toCharArray();
 1857    else
 1858  0 ca4 = "Inf".toCharArray();
 1859    } else
 1860  0 ca4 = "-Inf".toCharArray();
 1861  0 noDigits = true;
 1862  0 } else if (Double.isNaN(x)) {
 1863  0 if (leadingSign)
 1864  0 ca4 = "+NaN".toCharArray();
 1865  0 else if (leadingSpace)
 1866  0 ca4 = " NaN".toCharArray();
 1867    else
 1868  0 ca4 = "NaN".toCharArray();
 1869  0 noDigits = true;
 1870    } else {
 1871  0 if (!precisionSet)
 1872  0 precision = defaultDigits;
 1873  0 if (precision == 0)
 1874  0 precision = 1;
 1875  0 int ePos = -1;
 1876  0 if (conversionCharacter == 'g') {
 1877  0 sx = eFormatString(x, 'e').trim();
 1878  0 ePos = sx.indexOf('e');
 1879    } else {
 1880  0 sx = eFormatString(x, 'E').trim();
 1881  0 ePos = sx.indexOf('E');
 1882    }
 1883  0 i = ePos + 1;
 1884  0 int expon = 0;
 1885  0 if (sx.charAt(i) == '-') {
 1886  0 for (++i; i < sx.length(); i++)
 1887  0 if (sx.charAt(i) != '0')
 1888  0 break;
 1889  0 if (i < sx.length())
 1890  0 expon = -Integer.parseInt(sx.substring(i));
 1891    } else {
 1892  0 if (sx.charAt(i) == '+')
 1893  0 ++i;
 1894  0 for (; i < sx.length(); i++)
 1895  0 if (sx.charAt(i) != '0')
 1896  0 break;
 1897  0 if (i < sx.length())
 1898  0 expon = Integer.parseInt(sx.substring(i));
 1899    }
 1900    // Trim trailing zeros.
 1901    // If the radix character is not followed by
 1902    // a digit, trim it, too.
 1903  0 if (!alternateForm) {
 1904  0 if (expon >= -4 && expon < precision)
 1905  0 sy = fFormatString(x).trim();
 1906    else
 1907  0 sy = sx.substring(0, ePos);
 1908  0 i = sy.length() - 1;
 1909  0 for (; i >= 0; i--)
 1910  0 if (sy.charAt(i) != '0')
 1911  0 break;
 1912  0 if (i >= 0 && sy.charAt(i) == '.')
 1913  0 i--;
 1914  0 if (i == -1)
 1915  0 sz = "0";
 1916  0 else if (!Character.isDigit(sy.charAt(i)))
 1917  0 sz = sy.substring(0, i + 1) + "0";
 1918    else
 1919  0 sz = sy.substring(0, i + 1);
 1920  0 if (expon >= -4 && expon < precision)
 1921  0 ret = sz;
 1922    else
 1923  0 ret = sz + sx.substring(ePos);
 1924    } else {
 1925  0 if (expon >= -4 && expon < precision)
 1926  0 ret = fFormatString(x).trim();
 1927    else
 1928  0 ret = sx;
 1929    }
 1930    // leading space was trimmed off during
 1931    // construction
 1932  0 if (leadingSpace)
 1933  0 if (x >= 0)
 1934  0 ret = " " + ret;
 1935  0 ca4 = ret.toCharArray();
 1936    }
 1937    // Pad with blanks or zeros.
 1938  0 ca5 = applyFloatPadding(ca4, false);
 1939  0 precision = savePrecision;
 1940  0 return new String(ca5);
 1941    }
 1942   
 1943    /**
 1944    * Format method for the d conversion specifer and short argument. For d
 1945    * format, the flag character '-', means that the output should be left
 1946    * justified within the field. The default is to pad with blanks on the
 1947    * left. A '+' character means that the conversion will always begin
 1948    * with a sign (+ or -). The blank flag character means that a
 1949    * non-negative input will be preceded with a blank. If both a '+' and a ' '
 1950    * are specified, the blank flag is ignored. The '0' flag character
 1951    * implies that padding to the field width will be done with zeros
 1952    * instead of blanks. The field width is treated as the minimum number
 1953    * of characters to be printed. The default is to add no padding.
 1954    * Padding is with blanks by default. The precision, if set, is the
 1955    * minimum number of digits to appear. Padding is with leading 0s.
 1956    *
 1957    * @param x the short to format.
 1958    * @return the formatted String.
 1959    */
 1960  0 private String printDFormat(short x) {
 1961  0 return printDFormat(Short.toString(x));
 1962    }
 1963   
 1964    /**
 1965    * Format method for the d conversion character and long argument. For d
 1966    * format, the flag character '-', means that the output should be left
 1967    * justified within the field. The default is to pad with blanks on the
 1968    * left. A '+' character means that the conversion will always begin
 1969    * with a sign (+ or -). The blank flag character means that a
 1970    * non-negative input will be preceded with a blank. If both a '+' and a ' '
 1971    * are specified, the blank flag is ignored. The '0' flag character
 1972    * implies that padding to the field width will be done with zeros
 1973    * instead of blanks. The field width is treated as the minimum number
 1974    * of characters to be printed. The default is to add no padding.
 1975    * Padding is with blanks by default. The precision, if set, is the
 1976    * minimum number of digits to appear. Padding is with leading 0s.
 1977    *
 1978    * @param x the long to format.
 1979    * @return the formatted String.
 1980    */
 1981  0 private String printDFormat(long x) {
 1982  0 return printDFormat(Long.toString(x));
 1983    }
 1984   
 1985    /**
 1986    * Format method for the d conversion character and int argument. For d
 1987    * format, the flag character '-', means that the output should be left
 1988    * justified within the field. The default is to pad with blanks on the
 1989    * left. A '+' character means that the conversion will always begin
 1990    * with a sign (+ or -). The blank flag character means that a
 1991    * non-negative input will be preceded with a blank. If both a '+' and a ' '
 1992    * are specified, the blank flag is ignored. The '0' flag character
 1993    * implies that padding to the field width will be done with zeros
 1994    * instead of blanks. The field width is treated as the minimum number
 1995    * of characters to be printed. The default is to add no padding.
 1996    * Padding is with blanks by default. The precision, if set, is the
 1997    * minimum number of digits to appear. Padding is with leading 0s.
 1998    *
 1999    * @param x the int to format.
 2000    * @return the formatted String.
 2001    */
 2002  0 private String printDFormat(int x) {
 2003  0 return printDFormat(Integer.toString(x));
 2004    }
 2005   
 2006    /**
 2007    * Utility method for formatting using the d conversion character.
 2008    *
 2009    * @param sx the String to format, the result of converting a short,
 2010    * int, or long to a String.
 2011    * @return the formatted String.
 2012    */
 2013  0 private String printDFormat(String sx) {
 2014  0 int nLeadingZeros = 0;
 2015  0 int nBlanks = 0, n = 0;
 2016  0 int i = 0, jFirst = 0;
 2017  0 boolean neg = sx.charAt(0) == '-';
 2018  0 if (sx.equals("0") && precisionSet && precision == 0)
 2019  0 sx = "";
 2020  0 if (!neg) {
 2021  0 if (precisionSet && sx.length() < precision)
 2022  0 nLeadingZeros = precision - sx.length();
 2023    } else {
 2024  0 if (precisionSet && (sx.length() - 1) < precision)
 2025  0 nLeadingZeros = precision - sx.length() + 1;
 2026    }
 2027  0 if (nLeadingZeros < 0)
 2028  0 nLeadingZeros = 0;
 2029  0 if (fieldWidthSet) {
 2030  0 nBlanks = fieldWidth - nLeadingZeros - sx.length();
 2031  0 if (!neg && (leadingSign || leadingSpace))
 2032  0 nBlanks--;
 2033    }
 2034  0 if (nBlanks < 0)
 2035  0 nBlanks = 0;
 2036  0 if (leadingSign)
 2037  0 n++;
 2038  0 else if (leadingSpace)
 2039  0 n++;
 2040  0 n += nBlanks;
 2041  0 n += nLeadingZeros;
 2042  0 n += sx.length();
 2043  0 char[] ca = new char[n];
 2044  0 if (leftJustify) {
 2045  0 if (neg)
 2046  0 ca[i++] = '-';
 2047  0 else if (leadingSign)
 2048  0 ca[i++] = '+';
 2049  0 else if (leadingSpace)
 2050  0 ca[i++] = ' ';
 2051  0 char[] csx = sx.toCharArray();
 2052  0 jFirst = neg ? 1 : 0;
 2053  0 for (int j = 0; j < nLeadingZeros; i++, j++)
 2054  0 ca[i] = '0';
 2055  0 for (int j = jFirst; j < csx.length; j++, i++)
 2056  0 ca[i] = csx[j];
 2057  0 for (int j = 0; j < nBlanks; i++, j++)
 2058  0 ca[i] = ' ';
 2059    } else {
 2060  0 if (!leadingZeros) {
 2061  0 for (i = 0; i < nBlanks; i++)
 2062  0 ca[i] = ' ';
 2063  0 if (neg)
 2064  0 ca[i++] = '-';
 2065  0 else if (leadingSign)
 2066  0 ca[i++] = '+';
 2067  0 else if (leadingSpace)
 2068  0 ca[i++] = ' ';
 2069    } else {
 2070  0 if (neg)
 2071  0 ca[i++] = '-';
 2072  0 else if (leadingSign)
 2073  0 ca[i++] = '+';
 2074  0 else if (leadingSpace)
 2075  0 ca[i++] = ' ';
 2076  0 for (int j = 0; j < nBlanks; j++, i++)
 2077  0 ca[i] = '0';
 2078    }
 2079  0 for (int j = 0; j < nLeadingZeros; j++, i++)
 2080  0 ca[i] = '0';
 2081  0 char[] csx = sx.toCharArray();
 2082  0 jFirst = neg ? 1 : 0;
 2083  0 for (int j = jFirst; j < csx.length; j++, i++)
 2084  0 ca[i] = csx[j];
 2085    }
 2086  0 return new String(ca);
 2087    }
 2088   
 2089    /**
 2090    * Format method for the x conversion character and short argument. For
 2091    * x format, the flag character '-', means that the output should be
 2092    * left justified within the field. The default is to pad with blanks on
 2093    * the left. The '#' flag character means to lead with '0x'. The field
 2094    * width is treated as the minimum number of characters to be printed.
 2095    * The default is to add no padding. Padding is with blanks by default.
 2096    * The precision, if set, is the minimum number of digits to appear.
 2097    * Padding is with leading 0s.
 2098    *
 2099    * @param x the short to format.
 2100    * @return the formatted String.
 2101    */
 2102  0 private String printXFormat(short x) {
 2103  0 String sx = null;
 2104  0 if (x == Short.MIN_VALUE)
 2105  0 sx = "8000";
 2106  0 else if (x < 0) {
 2107  0 String t;
 2108  0 if (x == Short.MIN_VALUE)
 2109  0 t = "0";
 2110    else {
 2111  0 t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE, 16);
 2112  0 if (t.charAt(0) == 'F' || t.charAt(0) == 'f')
 2113  0 t = t.substring(16, 32);
 2114    }
 2115  0 switch (t.length()) {
 2116  0 case 1:
 2117  0 sx = "800" + t;
 2118  0 break;
 2119  0 case 2:
 2120  0 sx = "80" + t;
 2121  0 break;
 2122  0 case 3:
 2123  0 sx = "8" + t;
 2124  0 break;
 2125  0 case 4:
 2126  0 switch (t.charAt(0)) {
 2127  0 case '1':
 2128  0 sx = "9" + t.substring(1, 4);
 2129  0 break;
 2130  0 case '2':
 2131  0 sx = "a" + t.substring(1, 4);
 2132  0 break;
 2133  0 case '3':
 2134  0 sx = "b" + t.substring(1, 4);
 2135  0 break;
 2136  0 case '4':
 2137  0 sx = "c" + t.substring(1, 4);
 2138  0 break;
 2139  0 case '5':
 2140  0 sx = "d" + t.substring(1, 4);
 2141  0 break;
 2142  0 case '6':
 2143  0 sx = "e" + t.substring(1, 4);
 2144  0 break;
 2145  0 case '7':
 2146  0 sx = "f" + t.substring(1, 4);
 2147  0 break;
 2148    }
 2149  0 break;
 2150    }
 2151    } else
 2152  0 sx = Integer.toString((int) x, 16);
 2153  0 return printXFormat(sx);
 2154    }
 2155   
 2156    /**
 2157    * Format method for the x conversion character and long argument. For x
 2158    * format, the flag character '-', means that the output should be left
 2159    * justified within the field. The default is to pad with blanks on the
 2160    * left. The '#' flag character means to lead with '0x'. The field width
 2161    * is treated as the minimum number of characters to be printed. The
 2162    * default is to add no padding. Padding is with blanks by default. The
 2163    * precision, if set, is the minimum number of digits to appear. Padding
 2164    * is with leading 0s.
 2165    *
 2166    * @param x the long to format.
 2167    * @return the formatted String.
 2168    */
 2169  0 private String printXFormat(long x) {
 2170  0 String sx = null;
 2171  0 if (x == Long.MIN_VALUE)
 2172  0 sx = "8000000000000000";
 2173  0 else if (x < 0) {
 2174  0 String t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE, 16);
 2175  0 switch (t.length()) {
 2176  0 case 1:
 2177  0 sx = "800000000000000" + t;
 2178  0 break;
 2179  0 case 2:
 2180  0 sx = "80000000000000" + t;
 2181  0 break;
 2182  0 case 3:
 2183  0 sx = "8000000000000" + t;
 2184  0 break;
 2185  0 case 4:
 2186  0 sx = "800000000000" + t;
 2187  0 break;
 2188  0 case 5:
 2189  0 sx = "80000000000" + t;
 2190  0 break;
 2191  0 case 6:
 2192  0 sx = "8000000000" + t;
 2193  0 break;
 2194  0 case 7:
 2195  0 sx = "800000000" + t;
 2196  0 break;
 2197  0 case 8:
 2198  0 sx = "80000000" + t;
 2199  0 break;
 2200  0 case 9:
 2201  0 sx = "8000000" + t;
 2202  0 break;
 2203  0 case 10:
 2204  0 sx = "800000" + t;
 2205  0 break;
 2206  0 case 11:
 2207  0 sx = "80000" + t;
 2208  0 break;
 2209  0 case 12:
 2210  0 sx = "8000" + t;
 2211  0 break;
 2212  0 case 13:
 2213  0 sx = "800" + t;
 2214  0 break;
 2215  0 case 14:
 2216  0 sx = "80" + t;
 2217  0 break;
 2218  0 case 15:
 2219  0 sx = "8" + t;
 2220  0 break;
 2221  0 case 16:
 2222  0 switch (t.charAt(0)) {
 2223  0 case '1':
 2224  0 sx = "9" + t.substring(1, 16);
 2225  0 break;
 2226  0 case '2':
 2227  0 sx = "a" + t.substring(1, 16);
 2228  0 break;
 2229  0 case '3':
 2230  0 sx = "b" + t.substring(1, 16);
 2231  0 break;
 2232  0 case '4':
 2233  0 sx = "c" + t.substring(1, 16);
 2234  0 break;
 2235  0 case '5':
 2236  0 sx = "d" + t.substring(1, 16);
 2237  0 break;
 2238  0 case '6':
 2239  0 sx = "e" + t.substring(1, 16);
 2240  0 break;
 2241  0 case '7':
 2242  0 sx = "f" + t.substring(1, 16);
 2243  0 break;
 2244    }
 2245  0 break;
 2246    }
 2247    } else
 2248  0 sx = Long.toString(x, 16);
 2249  0 return printXFormat(sx);
 2250    }
 2251   
 2252    /**
 2253    * Format method for the x conversion character and int argument. For x
 2254    * format, the flag character '-', means that the output should be left
 2255    * justified within the field. The default is to pad with blanks on the
 2256    * left. The '#' flag character means to lead with '0x'. The field width
 2257    * is treated as the minimum number of characters to be printed. The
 2258    * default is to add no padding. Padding is with blanks by default. The
 2259    * precision, if set, is the minimum number of digits to appear. Padding
 2260    * is with leading 0s.
 2261    *
 2262    * @param x the int to format.
 2263    * @return the formatted String.
 2264    */
 2265  0 private String printXFormat(int x) {
 2266  0 String sx = null;
 2267  0 if (x == Integer.MIN_VALUE)
 2268  0 sx = "80000000";
 2269  0 else if (x < 0) {
 2270  0 String t = Integer.toString((~(-x - 1)) ^ Integer.MIN_VALUE, 16);
 2271  0 switch (t.length()) {
 2272  0 case 1:
 2273  0 sx = "8000000" + t;
 2274  0 break;
 2275  0 case 2:
 2276  0 sx = "800000" + t;
 2277  0 break;
 2278  0 case 3:
 2279  0 sx = "80000" + t;
 2280  0 break;
 2281  0 case 4:
 2282  0 sx = "8000" + t;
 2283  0 break;
 2284  0 case 5:
 2285  0 sx = "800" + t;
 2286  0 break;
 2287  0 case 6:
 2288  0 sx = "80" + t;
 2289  0 break;
 2290  0 case 7:
 2291  0 sx = "8" + t;
 2292  0 break;
 2293  0 case 8:
 2294  0 switch (t.charAt(0)) {
 2295  0 case '1':
 2296  0 sx = "9" + t.substring(1, 8);
 2297  0 break;
 2298  0 case '2':
 2299  0 sx = "a" + t.substring(1, 8);
 2300  0 break;
 2301  0 case '3':
 2302  0 sx = "b" + t.substring(1, 8);
 2303  0 break;
 2304  0 case '4':
 2305  0 sx = "c" + t.substring(1, 8);
 2306  0 break;
 2307  0 case '5':
 2308  0 sx = "d" + t.substring(1, 8);
 2309  0 break;
 2310  0 case '6':
 2311  0 sx = "e" + t.substring(1, 8);
 2312  0 break;
 2313  0 case '7':
 2314  0 sx = "f" + t.substring(1, 8);
 2315  0 break;
 2316    }
 2317  0 break;
 2318    }
 2319    } else
 2320  0 sx = Integer.toString(x, 16);
 2321  0 return printXFormat(sx);
 2322    }
 2323   
 2324    /**
 2325    * Utility method for formatting using the x conversion character.
 2326    *
 2327    * @param sx the String to format, the result of converting a short,
 2328    * int, or long to a String.
 2329    * @return the formatted String.
 2330    */
 2331  0 private String printXFormat(String sx) {
 2332  0 int nLeadingZeros = 0;
 2333  0 int nBlanks = 0;
 2334  0 if (sx.equals("0") && precisionSet && precision == 0)
 2335  0 sx = "";
 2336  0 if (precisionSet)
 2337  0 nLeadingZeros = precision - sx.length();
 2338  0 if (nLeadingZeros < 0)
 2339  0 nLeadingZeros = 0;
 2340  0 if (fieldWidthSet) {
 2341  0 nBlanks = fieldWidth - nLeadingZeros - sx.length();
 2342  0 if (alternateForm)
 2343  0 nBlanks = nBlanks - 2;
 2344    }
 2345  0 if (nBlanks < 0)
 2346  0 nBlanks = 0;
 2347  0 int n = 0;
 2348  0 if (alternateForm)
 2349  0 n += 2;
 2350  0 n += nLeadingZeros;
 2351  0 n += sx.length();
 2352  0 n += nBlanks;
 2353  0 char[] ca = new char[n];
 2354  0 int i = 0;
 2355  0 if (leftJustify) {
 2356  0 if (alternateForm) {
 2357  0 ca[i++] = '0';
 2358  0 ca[i++] = 'x';
 2359    }
 2360  0 for (int j = 0; j < nLeadingZeros; j++, i++)
 2361  0 ca[i] = '0';
 2362  0 char[] csx = sx.toCharArray();
 2363  0 for (int j = 0; j < csx.length; j++, i++)
 2364  0 ca[i] = csx[j];
 2365  0 for (int j = 0; j < nBlanks; j++, i++)
 2366  0 ca[i] = ' ';
 2367    } else {
 2368  0 if (!leadingZeros)
 2369  0 for (int j = 0; j < nBlanks; j++, i++)
 2370  0 ca[i] = ' ';
 2371  0 if (alternateForm) {
 2372  0 ca[i++] = '0';
 2373  0 ca[i++] = 'x';
 2374    }
 2375  0 if (leadingZeros)
 2376  0 for (int j = 0; j < nBlanks; j++, i++)
 2377  0 ca[i] = '0';
 2378  0 for (int j = 0; j < nLeadingZeros; j++, i++)
 2379  0 ca[i] = '0';
 2380  0 char[] csx = sx.toCharArray();
 2381  0 for (int j = 0; j < csx.length; j++, i++)
 2382  0 ca[i] = csx[j];
 2383    }
 2384  0 String caReturn = new String(ca);
 2385  0 if (conversionCharacter == 'X')
 2386  0 caReturn = caReturn.toUpperCase();
 2387  0 return caReturn;
 2388    }
 2389   
 2390    /**
 2391    * Format method for the o conversion character and short argument. For
 2392    * o format, the flag character '-', means that the output should be
 2393    * left justified within the field. The default is to pad with blanks on
 2394    * the left. The '#' flag character means that the output begins with a
 2395    * leading 0 and the precision is increased by 1. The field width is
 2396    * treated as the minimum number of characters to be printed. The
 2397    * default is to add no padding. Padding is with blanks by default. The
 2398    * precision, if set, is the minimum number of digits to appear. Padding
 2399    * is with leading 0s.
 2400    *
 2401    * @param x the short to format.
 2402    * @return the formatted String.
 2403    */
 2404  0 private String printOFormat(short x) {
 2405  0 String sx = null;
 2406  0 if (x == Short.MIN_VALUE)
 2407  0 sx = "100000";
 2408  0 else if (x < 0) {
 2409  0 String t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE, 8);
 2410  0 switch (t.length()) {
 2411  0 case 1:
 2412  0 sx = "10000" + t;
 2413  0 break;
 2414  0 case 2:
 2415  0 sx = "1000" + t;
 2416  0 break;
 2417  0 case 3:
 2418  0 sx = "100" + t;
 2419  0 break;
 2420  0 case 4:
 2421  0 sx = "10" + t;
 2422  0 break;
 2423  0 case 5:
 2424  0 sx = "1" + t;
 2425  0 break;
 2426    }
 2427    } else
 2428  0 sx = Integer.toString((int) x, 8);
 2429  0 return printOFormat(sx);
 2430    }
 2431   
 2432    /**
 2433    * Format method for the o conversion character and long argument. For o
 2434    * format, the flag character '-', means that the output should be left
 2435    * justified within the field. The default is to pad with blanks on the
 2436    * left. The '#' flag character means that the output begins with a
 2437    * leading 0 and the precision is increased by 1. The field width is
 2438    * treated as the minimum number of characters to be printed. The
 2439    * default is to add no padding. Padding is with blanks by default. The
 2440    * precision, if set, is the minimum number of digits to appear. Padding
 2441    * is with leading 0s.
 2442    *
 2443    * @param x the long to format.
 2444    * @return the formatted String.
 2445    */
 2446  0 private String printOFormat(long x) {
 2447  0 String sx = null;
 2448  0 if (x == Long.MIN_VALUE)
 2449  0 sx = "1000000000000000000000";
 2450  0 else if (x < 0) {
 2451  0 String t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE, 8);
 2452  0 switch (t.length()) {
 2453  0 case 1:
 2454  0 sx = "100000000000000000000" + t;
 2455  0 break;
 2456  0 case 2:
 2457  0 sx = "10000000000000000000" + t;
 2458  0 break;
 2459  0 case 3:
 2460  0 sx = "1000000000000000000" + t;
 2461  0 break;
 2462  0 case 4:
 2463  0 sx = "100000000000000000" + t;
 2464  0 break;
 2465  0 case 5:
 2466  0 sx = "10000000000000000" + t;
 2467  0 break;
 2468  0 case 6:
 2469  0 sx = "1000000000000000" + t;
 2470  0 break;
 2471  0 case 7:
 2472  0 sx = "100000000000000" + t;
 2473  0 break;
 2474  0 case 8:
 2475  0 sx = "10000000000000" + t;
 2476  0 break;
 2477  0 case 9:
 2478  0 sx = "1000000000000" + t;
 2479  0 break;
 2480  0 case 10:
 2481  0 sx = "100000000000" + t;
 2482  0 break;
 2483  0 case 11:
 2484  0 sx = "10000000000" + t;
 2485  0 break;
 2486  0 case 12:
 2487  0 sx = "1000000000" + t;
 2488  0 break;
 2489  0 case 13:
 2490  0 sx = "100000000" + t;
 2491  0 break;
 2492  0 case 14:
 2493  0 sx = "10000000" + t;
 2494  0 break;
 2495  0 case 15:
 2496  0 sx = "1000000" + t;
 2497  0 break;
 2498  0 case 16:
 2499  0 sx = "100000" + t;
 2500  0 break;
 2501  0 case 17:
 2502  0 sx = "10000" + t;
 2503  0 break;
 2504  0 case 18:
 2505  0 sx = "1000" + t;
 2506  0 break;
 2507  0 case 19:
 2508  0 sx = "100" + t;
 2509  0 break;
 2510  0 case 20:
 2511  0 sx = "10" + t;
 2512  0 break;
 2513  0 case 21:
 2514  0 sx = "1" + t;
 2515  0 break;
 2516    }
 2517    } else
 2518  0 sx = Long.toString(x, 8);
 2519  0 return printOFormat(sx);
 2520    }
 2521   
 2522    /**
 2523    * Format method for the o conversion character and int argument. For o
 2524    * format, the flag character '-', means that the output should be left
 2525    * justified within the field. The default is to pad with blanks on the
 2526    * left. The '#' flag character means that the output begins with a
 2527    * leading 0 and the precision is increased by 1. The field width is
 2528    * treated as the minimum number of characters to be printed. The
 2529    * default is to add no padding. Padding is with blanks by default. The
 2530    * precision, if set, is the minimum number of digits to appear. Padding
 2531    * is with leading 0s.
 2532    *
 2533    * @param x the int to format.
 2534    * @return the formatted String.
 2535    */
 2536  0 private String printOFormat(int x) {
 2537  0 String sx = null;
 2538  0 if (x == Integer.MIN_VALUE)
 2539  0 sx = "20000000000";
 2540  0 else if (x < 0) {
 2541  0 String t = Integer.toString((~(-x - 1)) ^ Integer.MIN_VALUE, 8);
 2542  0 switch (t.length()) {
 2543  0 case 1:
 2544  0 sx = "2000000000" + t;
 2545  0 break;
 2546  0 case 2:
 2547  0 sx = "200000000" + t;
 2548  0 break;
 2549  0 case 3:
 2550  0 sx = "20000000" + t;
 2551  0 break;
 2552  0 case 4:
 2553  0 sx = "2000000" + t;
 2554  0 break;
 2555  0 case 5:
 2556  0 sx = "200000" + t;
 2557  0 break;
 2558  0 case 6:
 2559  0 sx = "20000" + t;
 2560  0 break;
 2561  0 case 7:
 2562  0 sx = "2000" + t;
 2563  0 break;
 2564  0 case 8:
 2565  0 sx = "200" + t;
 2566  0 break;
 2567  0 case 9:
 2568  0 sx = "20" + t;
 2569  0 break;
 2570  0 case 10:
 2571  0 sx = "2" + t;
 2572  0 break;
 2573  0 case 11:
 2574  0 sx = "3" + t.substring(1);
 2575  0 break;
 2576    }
 2577    } else
 2578  0 sx = Integer.toString(x, 8);
 2579  0 return printOFormat(sx);
 2580    }
 2581   
 2582    /**
 2583    * Utility method for formatting using the o conversion character.
 2584    *
 2585    * @param sx the String to format, the result of converting a short,
 2586    * int, or long to a String.
 2587    * @return the formatted String.
 2588    */
 2589  0 private String printOFormat(String sx) {
 2590  0 int nLeadingZeros = 0;
 2591  0 int nBlanks = 0;
 2592  0 if (sx.equals("0") && precisionSet && precision == 0)
 2593  0 sx = "";
 2594  0 if (precisionSet)
 2595  0 nLeadingZeros = precision - sx.length();
 2596  0 if (alternateForm)
 2597  0 nLeadingZeros++;
 2598  0 if (nLeadingZeros < 0)
 2599  0 nLeadingZeros = 0;
 2600  0 if (fieldWidthSet)
 2601  0 nBlanks = fieldWidth - nLeadingZeros - sx.length();
 2602  0 if (nBlanks < 0)
 2603  0 nBlanks = 0;
 2604  0 int n = nLeadingZeros + sx.length() + nBlanks;
 2605  0 char[] ca = new char[n];
 2606  0 int i;
 2607  0 if (leftJustify) {
 2608  0 for (i = 0; i < nLeadingZeros; i++)
 2609  0 ca[i] = '0';
 2610  0 char[] csx = sx.toCharArray();
 2611  0 for (int j = 0; j < csx.length; j++, i++)
 2612  0 ca[i] = csx[j];
 2613  0 for (int j = 0; j < nBlanks; j++, i++)
 2614  0 ca[i] = ' ';
 2615    } else {
 2616  0 if (leadingZeros)
 2617  0 for (i = 0; i < nBlanks; i++)
 2618  0 ca[i] = '0';
 2619    else
 2620  0 for (i = 0; i < nBlanks; i++)
 2621  0 ca[i] = ' ';
 2622  0 for (int j = 0; j < nLeadingZeros; j++, i++)
 2623  0 ca[i] = '0';
 2624  0 char[] csx = sx.toCharArray();
 2625  0 for (int j = 0; j < csx.length; j++, i++)
 2626  0 ca[i] = csx[j];
 2627    }
 2628  0 return new String(ca);
 2629    }
 2630   
 2631    /**
 2632    * Format method for the c conversion character and char argument. The
 2633    * only flag character that affects c format is the '-', meaning that
 2634    * the output should be left justified within the field. The default is
 2635    * to pad with blanks on the left. The field width is treated as the
 2636    * minimum number of characters to be printed. Padding is with blanks by
 2637    * default. The default width is 1. The precision, if set, is ignored.
 2638    *
 2639    * @param x the char to format.
 2640    * @return the formatted String.
 2641    */
 2642  0 private String printCFormat(char x) {
 2643  0 int nPrint = 1;
 2644  0 int width = fieldWidth;
 2645  0 if (!fieldWidthSet)
 2646  0 width = nPrint;
 2647  0 char[] ca = new char[width];
 2648  0 int i = 0;
 2649  0 if (leftJustify) {
 2650  0 ca[0] = x;
 2651  0 for (i = 1; i <= width - nPrint; i++)
 2652  0 ca[i] = ' ';
 2653    } else {
 2654  0 for (i = 0; i < width - nPrint; i++)
 2655  0 ca[i] = ' ';
 2656  0 ca[i] = x;
 2657    }
 2658  0 return new String(ca);
 2659    }
 2660   
 2661    /**
 2662    * Format method for the s conversion character and String argument. The
 2663    * only flag character that affects s format is the '-', meaning that
 2664    * the output should be left justified within the field. The default is
 2665    * to pad with blanks on the left. The field width is treated as the
 2666    * minimum number of characters to be printed. The default is the
 2667    * smaller of the number of characters in the the input and the
 2668    * precision. Padding is with blanks by default. The precision, if set,
 2669    * specifies the maximum number of characters to be printed from the
 2670    * string. A null digit string is treated as a 0. The default is not to
 2671    * set a maximum number of characters to be printed.
 2672    *
 2673    * @param x the String to format.
 2674    * @return the formatted String.
 2675    */
 2676  0 private String printSFormat(String x) {
 2677  0 int nPrint = x.length();
 2678  0 int width = fieldWidth;
 2679  0 if (precisionSet && nPrint > precision)
 2680  0 nPrint = precision;
 2681  0 if (!fieldWidthSet)
 2682  0 width = nPrint;
 2683  0 int n = 0;
 2684  0 if (width > nPrint)
 2685  0 n += width - nPrint;
 2686  0 if (nPrint >= x.length())
 2687  0 n += x.length();
 2688    else
 2689  0 n += nPrint;
 2690  0 char[] ca = new char[n];
 2691  0 int i = 0;
 2692  0 if (leftJustify) {
 2693  0 if (nPrint >= x.length()) {
 2694  0 char[] csx = x.toCharArray();
 2695  0 for (i = 0; i < x.length(); i++)
 2696  0 ca[i] = csx[i];
 2697    } else {
 2698  0 char[] csx = x.substring(0, nPrint).toCharArray();
 2699  0 for (i = 0; i < nPrint; i++)
 2700  0 ca[i] = csx[i];
 2701    }
 2702  0 for (int j = 0; j < width - nPrint; j++, i++)
 2703  0 ca[i] = ' ';
 2704    } else {
 2705  0 for (i = 0; i < width - nPrint; i++)
 2706  0 ca[i] = ' ';
 2707  0 if (nPrint >= x.length()) {
 2708  0 char[] csx = x.toCharArray();
 2709  0 for (int j = 0; j < x.length(); i++, j++)
 2710  0 ca[i] = csx[j];
 2711    } else {
 2712  0 char[] csx = x.substring(0, nPrint).toCharArray();
 2713  0 for (int j = 0; j < nPrint; i++, j++)
 2714  0 ca[i] = csx[j];
 2715    }
 2716    }
 2717  0 return new String(ca);
 2718    }
 2719   
 2720    /**
 2721    * Check for a conversion character. If it is there, store it.
 2722    *
 2723    * @param x the String to format.
 2724    * @return <code>true</code> if the conversion character is there, and
 2725    * <code>false</code> otherwise.
 2726    */
 2727  11 private boolean setConversionCharacter() {
 2728    /* idfgGoxXeEcs */
 2729  11 boolean ret = false;
 2730  11 conversionCharacter = '\0';
 2731  11 if (pos < fmt.length()) {
 2732  11 char c = fmt.charAt(pos);
 2733  11 if (c == 'i' || c == 'd' || c == 'f' || c == 'g' || c == 'G' || c == 'o' || c == 'x' || c == 'X' || c == 'e' || c == 'E' || c == 'c' || c == 's' || c == '%') {
 2734  11 conversionCharacter = c;
 2735  11 pos++;
 2736  11 ret = true;
 2737    }
 2738    }
 2739  11 return ret;
 2740    }
 2741   
 2742    /**
 2743    * Check for an h, l, or L in a format. An L is used to control the
 2744    * minimum number of digits in an exponent when using floating point
 2745    * formats. An l or h is used to control conversion of the input to a
 2746    * long or short, respectively, before formatting. If any of these is
 2747    * present, store them.
 2748    */
 2749  11 private void setOptionalHL() {
 2750  11 optionalh = false;
 2751  11 optionall = false;
 2752  11 optionalL = false;
 2753  11 if (pos < fmt.length()) {
 2754  11 char c = fmt.charAt(pos);
 2755  11 if (c == 'h') {
 2756  0 optionalh = true;
 2757  0 pos++;
 2758  11 } else if (c == 'l') {
 2759  0 optionall = true;
 2760  0 pos++;
 2761  11 } else if (c == 'L') {
 2762  0 optionalL = true;
 2763  0 pos++;
 2764    }
 2765    }
 2766    }
 2767   
 2768    /**
 2769    * Set the precision.
 2770    */
 2771  11 private void setPrecision() {
 2772  11 int firstPos = pos;
 2773  11 precisionSet = false;
 2774  11 if (pos < fmt.length() && fmt.charAt(pos) == '.') {
 2775  11 pos++;
 2776  11 if ((pos < fmt.length()) && (fmt.charAt(pos) == '*')) {
 2777  0 pos++;
 2778  0 if (!setPrecisionArgPosition()) {
 2779  0 variablePrecision = true;
 2780  0 precisionSet = true;
 2781    }
 2782  0 return;
 2783    } else {
 2784  33 while (pos < fmt.length()) {
 2785  33 char c = fmt.charAt(pos);
 2786  33 if (Character.isDigit(c))
 2787  22 pos++;
 2788    else
 2789  11 break;
 2790    }
 2791  11 if (pos > firstPos + 1) {
 2792  11 String sz = fmt.substring(firstPos + 1, pos);
 2793  11 precision = Integer.parseInt(sz);
 2794  11 precisionSet = true;
 2795    }
 2796    }
 2797    }
 2798    }
 2799   
 2800    /**
 2801    * Set the field width.
 2802    */
 2803  11 private void setFieldWidth() {
 2804  11 int firstPos = pos;
 2805  11 fieldWidth = 0;
 2806  11 fieldWidthSet = false;
 2807  11 if ((pos < fmt.length()) && (fmt.charAt(pos) == '*')) {
 2808  0 pos++;
 2809  0 if (!setFieldWidthArgPosition()) {
 2810  0 variableFieldWidth = true;
 2811  0 fieldWidthSet = true;
 2812    }
 2813    } else {
 2814  11 while (pos < fmt.length()) {
 2815  11 char c = fmt.charAt(pos);
 2816  11 if (Character.isDigit(c))
 2817  0 pos++;
 2818    else
 2819  11 break;
 2820    }
 2821  11 if (firstPos < pos && firstPos < fmt.length()) {
 2822  0 String sz = fmt.substring(firstPos, pos);
 2823  0 fieldWidth = Integer.parseInt(sz);
 2824  0 fieldWidthSet = true;
 2825    }
 2826    }
 2827    }
 2828   
 2829    /**
 2830    * Store the digits <code>n</code> in %n$ forms.
 2831    */
 2832  11 private void setArgPosition() {
 2833  11 int xPos;
 2834  11 for (xPos = pos; xPos < fmt.length(); xPos++) {
 2835  11 if (!Character.isDigit(fmt.charAt(xPos)))
 2836  11 break;
 2837    }
 2838  11 if (xPos > pos && xPos < fmt.length()) {
 2839  0 if (fmt.charAt(xPos) == '$') {
 2840  0 positionalSpecification = true;
 2841  0 argumentPosition = Integer.parseInt(fmt.substring(pos, xPos));
 2842  0 pos = xPos + 1;
 2843    }
 2844    }
 2845    }
 2846   
 2847    /**
 2848    * Store the digits <code>n</code> in *n$ forms.
 2849    */
 2850  0 private boolean setFieldWidthArgPosition() {
 2851  0 boolean ret = false;
 2852  0 int xPos;
 2853  0 for (xPos = pos; xPos < fmt.length(); xPos++) {
 2854  0 if (!Character.isDigit(fmt.charAt(xPos)))
 2855  0 break;
 2856    }
 2857  0 if (xPos > pos && xPos < fmt.length()) {
 2858  0 if (fmt.charAt(xPos) == '$') {
 2859  0 positionalFieldWidth = true;
 2860  0 argumentPositionForFieldWidth = Integer.parseInt(fmt.substring(pos, xPos));
 2861  0 pos = xPos + 1;
 2862  0 ret = true;
 2863    }
 2864    }
 2865  0 return ret;
 2866    }
 2867   
 2868    /**
 2869    * Store the digits <code>n</code> in *n$ forms.
 2870    */
 2871  0 private boolean setPrecisionArgPosition() {
 2872  0 boolean ret = false;
 2873  0 int xPos;
 2874  0 for (xPos = pos; xPos < fmt.length(); xPos++) {
 2875  0 if (!Character.isDigit(fmt.charAt(xPos)))
 2876  0 break;
 2877    }
 2878  0 if (xPos > pos && xPos < fmt.length()) {
 2879  0 if (fmt.charAt(xPos) == '$') {
 2880  0 positionalPrecision = true;
 2881  0 argumentPositionForPrecision = Integer.parseInt(fmt.substring(pos, xPos));
 2882  0 pos = xPos + 1;
 2883  0 ret = true;
 2884    }
 2885    }
 2886  0 return ret;
 2887    }
 2888   
 2889  0 boolean isPositionalSpecification() {
 2890  0 return positionalSpecification;
 2891    }
 2892   
 2893  0 int getArgumentPosition() {
 2894  0 return argumentPosition;
 2895    }
 2896   
 2897  0 boolean isPositionalFieldWidth() {
 2898  0 return positionalFieldWidth;
 2899    }
 2900   
 2901  0 int getArgumentPositionForFieldWidth() {
 2902  0 return argumentPositionForFieldWidth;
 2903    }
 2904   
 2905  0 boolean isPositionalPrecision() {
 2906  0 return positionalPrecision;
 2907    }
 2908   
 2909  0 int getArgumentPositionForPrecision() {
 2910  0 return argumentPositionForPrecision;
 2911    }
 2912   
 2913    /**
 2914    * Set flag characters, one of '-+#0 or a space.
 2915    */
 2916  11 private void setFlagCharacters() {
 2917    /* '-+ #0 */
 2918  11 thousands = false;
 2919  11 leftJustify = false;
 2920  11 leadingSign = false;
 2921  11 leadingSpace = false;
 2922  11 alternateForm = false;
 2923  11 leadingZeros = false;
 2924  11 for (; pos < fmt.length(); pos++) {
 2925  11 char c = fmt.charAt(pos);
 2926  11 if (c == '\'')
 2927  0 thousands = true;
 2928  11 else if (c == '-') {
 2929  0 leftJustify = true;
 2930  0 leadingZeros = false;
 2931  11 } else if (c == '+') {
 2932  0 leadingSign = true;
 2933  0 leadingSpace = false;
 2934  11 } else if (c == ' ') {
 2935  0 if (!leadingSign)
 2936  0 leadingSpace = true;
 2937  11 } else if (c == '#')
 2938  0 alternateForm = true;
 2939  11 else if (c == '0') {
 2940  0 if (!leftJustify)
 2941  0 leadingZeros = true;
 2942    } else
 2943  11 break;
 2944    }
 2945    }
 2946   
 2947    /**
 2948    * The integer portion of the result of a decimal conversion (i, d, u,
 2949    * f, g, or G) will be formatted with thousands' grouping characters.
 2950    * For other conversions the flag is ignored.
 2951    */
 2952    private boolean thousands = false;
 2953   
 2954    /**
 2955    * The result of the conversion will be left-justified within the field.
 2956    */
 2957    private boolean leftJustify = false;
 2958   
 2959    /**
 2960    * The result of a signed conversion will always begin with a sign (+ or
 2961    * -).
 2962    */
 2963    private boolean leadingSign = false;
 2964   
 2965    /**
 2966    * Flag indicating that left padding with spaces is specified.
 2967    */
 2968    private boolean leadingSpace = false;
 2969   
 2970    /**
 2971    * For an o conversion, increase the precision to force the first digit
 2972    * of the result to be a zero. For x (or X) conversions, a non-zero
 2973    * result will have 0x (or 0X) prepended to it. For e, E, f, g, or G
 2974    * conversions, the result will always contain a radix character, even
 2975    * if no digits follow the point. For g and G conversions, trailing
 2976    * zeros will not be removed from the result.
 2977    */
 2978    private boolean alternateForm = false;
 2979   
 2980    /**
 2981    * Flag indicating that left padding with zeroes is specified.
 2982    */
 2983    private boolean leadingZeros = false;
 2984   
 2985    /**
 2986    * Flag indicating that the field width is *.
 2987    */
 2988    private boolean variableFieldWidth = false;
 2989   
 2990    /**
 2991    * If the converted value has fewer bytes than the field width, it will
 2992    * be padded with spaces or zeroes.
 2993    */
 2994    private int fieldWidth = 0;
 2995   
 2996    /**
 2997    * Flag indicating whether or not the field width has been set.
 2998    */
 2999    private boolean fieldWidthSet = false;
 3000   
 3001    /**
 3002    * The minimum number of digits to appear for the d, i, o, u, x, or X
 3003    * conversions. The number of digits to appear after the radix character
 3004    * for the e, E, and f conversions. The maximum number of significant
 3005    * digits for the g and G conversions. The maximum number of bytes to be
 3006    * printed from a string in s and S conversions.
 3007    */
 3008    private int precision = 0;
 3009   
 3010    /** Default precision. */
 3011    private final static int defaultDigits = 6;
 3012   
 3013    /**
 3014    * Flag indicating that the precision is *.
 3015    */
 3016    private boolean variablePrecision = false;
 3017   
 3018    /**
 3019    * Flag indicating whether or not the precision has been set.
 3020    */
 3021    private boolean precisionSet = false;
 3022   
 3023    /*
 3024    */
 3025    private boolean positionalSpecification = false;
 3026   
 3027    private int argumentPosition = 0;
 3028   
 3029    private boolean positionalFieldWidth = false;
 3030   
 3031    private int argumentPositionForFieldWidth = 0;
 3032   
 3033    private boolean positionalPrecision = false;
 3034   
 3035    private int argumentPositionForPrecision = 0;
 3036   
 3037    /**
 3038    * Flag specifying that a following d, i, o, u, x, or X conversion
 3039    * character applies to a type short int.
 3040    */
 3041    private boolean optionalh = false;
 3042   
 3043    /**
 3044    * Flag specifying that a following d, i, o, u, x, or X conversion
 3045    * character applies to a type lont int argument.
 3046    */
 3047    private boolean optionall = false;
 3048   
 3049    /**
 3050    * Flag specifying that a following e, E, f, g, or G conversion
 3051    * character applies to a type double argument. This is a noop in Java.
 3052    */
 3053    private boolean optionalL = false;
 3054   
 3055    /** Control string type. */
 3056    private char conversionCharacter = '\0';
 3057   
 3058    /**
 3059    * Position within the control string. Used by the constructor.
 3060    */
 3061    private int pos = 0;
 3062   
 3063    /** Literal or control format string. */
 3064    private String fmt;
 3065    }
 3066   
 3067    /** Vector of control strings and format literals. */
 3068    private Vector vFmt = new Vector();
 3069   
 3070    /** Character position. Used by the constructor. */
 3071    private int cPos = 0;
 3072   
 3073    /** Character position. Used by the constructor. */
 3074    private DecimalFormatSymbols dfs = null;
 3075    }