summaryrefslogtreecommitdiffstats
path: root/src/demos/nurbs/surfaceapp/PrintfFormat.java
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2007-10-09 07:38:25 +0000
committerKenneth Russel <[email protected]>2007-10-09 07:38:25 +0000
commitc8e0d487886dbec1e3a994ea36724bbf59f5122a (patch)
tree0b9588684708a2429b8252ca367777d0b9125bf6 /src/demos/nurbs/surfaceapp/PrintfFormat.java
parent2bdf0b792c0b89cde549087af1676ee558e37aa6 (diff)
Integration of Tomas Hrasky's port of basic GLU NURBS functionality
from C++ to Java, plus example applications, done as part of his Bachelor of Science degree at the University of Hradec Králové, Faculty of Informatics and Management. Current state of code is documented in src/classes/com/sun/opengl/impl/nurbs/README.txt. Example applications require Java 1.5 and are not currently built by default. Specify -Djogl.nurbs=1 during jogl-demos build with a 1.5 javac on the PATH to build them. Dependent jars are copied to build output directory. Deleted old partially-complete GLU NURBS port. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/trunk@223 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
Diffstat (limited to 'src/demos/nurbs/surfaceapp/PrintfFormat.java')
-rwxr-xr-xsrc/demos/nurbs/surfaceapp/PrintfFormat.java3090
1 files changed, 3090 insertions, 0 deletions
diff --git a/src/demos/nurbs/surfaceapp/PrintfFormat.java b/src/demos/nurbs/surfaceapp/PrintfFormat.java
new file mode 100755
index 0000000..153460a
--- /dev/null
+++ b/src/demos/nurbs/surfaceapp/PrintfFormat.java
@@ -0,0 +1,3090 @@
+package demos.nurbs.surfaceapp;
+//
+// (c) 2000 Sun Microsystems, Inc.
+// ALL RIGHTS RESERVED
+//
+// License Grant-
+//
+//
+// Permission to use, copy, modify, and distribute this Software and its
+// documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is
+// hereby granted.
+//
+// This Software is provided "AS IS". All express warranties, including any
+// implied warranty of merchantability, satisfactory quality, fitness for a
+// particular purpose, or non-infringement, are disclaimed, except to the extent
+// that such disclaimers are held to be legally invalid.
+//
+// You acknowledge that Software is not designed, licensed or intended for use in
+// the design, construction, operation or maintenance of any nuclear facility
+// ("High Risk Activities"). Sun disclaims any express or implied warranty of
+// fitness for such uses.
+//
+// Please refer to the file http://www.sun.com/policies/trademarks/ for further
+// important trademark information and to
+// http://java.sun.com/nav/business/index.html for further important licensing
+// information for the Java Technology.
+//
+
+
+import java.util.Enumeration;
+import java.util.Vector;
+import java.util.Locale;
+import java.text.DecimalFormatSymbols;
+
+/**
+ * PrintfFormat allows the formatting of an array of
+ * objects embedded within a string. Primitive types
+ * must be passed using wrapper types. The formatting
+ * is controlled by a control string.
+ *<p>
+ * A control string is a Java string that contains a
+ * control specification. The control specification
+ * starts at the first percent sign (%) in the string,
+ * provided that this percent sign
+ *<ol>
+ *<li>is not escaped protected by a matching % or is
+ * not an escape % character,
+ *<li>is not at the end of the format string, and
+ *<li>precedes a sequence of characters that parses as
+ * a valid control specification.
+ *</ol>
+ *</p><p>
+ * A control specification usually takes the form:
+ *<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
+ * { [hlL] }+ [idfgGoxXeEcs]
+ *</pre>
+ * There are variants of this basic form that are
+ * discussed below.</p>
+ *<p>
+ * The format is composed of zero or more directives
+ * defined as follows:
+ *<ul>
+ *<li>ordinary characters, which are simply copied to
+ * the output stream;
+ *<li>escape sequences, which represent non-graphic
+ * characters; and
+ *<li>conversion specifications, each of which
+ * results in the fetching of zero or more arguments.
+ *</ul></p>
+ *<p>
+ * The results are undefined if there are insufficient
+ * arguments for the format. Usually an unchecked
+ * exception will be thrown. If the format is
+ * exhausted while arguments remain, the excess
+ * arguments are evaluated but are otherwise ignored.
+ * In format strings containing the % form of
+ * conversion specifications, each argument in the
+ * argument list is used exactly once.</p>
+ * <p>
+ * Conversions can be applied to the <code>n</code>th
+ * argument after the format in the argument list,
+ * rather than to the next unused argument. In this
+ * case, the conversion characer % is replaced by the
+ * sequence %<code>n</code>$, where <code>n</code> is
+ * a decimal integer giving the position of the
+ * argument in the argument list.</p>
+ * <p>
+ * In format strings containing the %<code>n</code>$
+ * form of conversion specifications, each argument
+ * in the argument list is used exactly once.</p>
+ *
+ *<h4>Escape Sequences</h4>
+ *<p>
+ * The following table lists escape sequences and
+ * associated actions on display devices capable of
+ * the action.
+ *<table>
+ *<tr><th align=left>Sequence</th>
+ * <th align=left>Name</th>
+ * <th align=left>Description</th></tr>
+ *<tr><td>\\</td><td>backlash</td><td>None.
+ *</td></tr>
+ *<tr><td>\a</td><td>alert</td><td>Attempts to alert
+ * the user through audible or visible
+ * notification.
+ *</td></tr>
+ *<tr><td>\b</td><td>backspace</td><td>Moves the
+ * printing position to one column before
+ * the current position, unless the
+ * current position is the start of a line.
+ *</td></tr>
+ *<tr><td>\f</td><td>form-feed</td><td>Moves the
+ * printing position to the initial
+ * printing position of the next logical
+ * page.
+ *</td></tr>
+ *<tr><td>\n</td><td>newline</td><td>Moves the
+ * printing position to the start of the
+ * next line.
+ *</td></tr>
+ *<tr><td>\r</td><td>carriage-return</td><td>Moves
+ * the printing position to the start of
+ * the current line.
+ *</td></tr>
+ *<tr><td>\t</td><td>tab</td><td>Moves the printing
+ * position to the next implementation-
+ * defined horizontal tab position.
+ *</td></tr>
+ *<tr><td>\v</td><td>vertical-tab</td><td>Moves the
+ * printing position to the start of the
+ * next implementation-defined vertical
+ * tab position.
+ *</td></tr>
+ *</table></p>
+ *<h4>Conversion Specifications</h4>
+ *<p>
+ * Each conversion specification is introduced by
+ * the percent sign character (%). After the character
+ * %, the following appear in sequence:</p>
+ *<p>
+ * Zero or more flags (in any order), which modify the
+ * meaning of the conversion specification.</p>
+ *<p>
+ * An optional minimum field width. If the converted
+ * value has fewer characters than the field width, it
+ * will be padded with spaces by default on the left;
+ * t will be padded on the right, if the left-
+ * adjustment flag (-), described below, is given to
+ * the field width. The field width takes the form
+ * of a decimal integer. If the conversion character
+ * is s, the field width is the the minimum number of
+ * characters to be printed.</p>
+ *<p>
+ * An optional precision that gives the minumum number
+ * of digits to appear for the d, i, o, x or X
+ * conversions (the field is padded with leading
+ * zeros); the number of digits to appear after the
+ * radix character for the e, E, and f conversions,
+ * the maximum number of significant digits for the g
+ * and G conversions; or the maximum number of
+ * characters to be written from a string is s and S
+ * conversions. The precision takes the form of an
+ * optional decimal digit string, where a null digit
+ * string is treated as 0. If a precision appears
+ * with a c conversion character the precision is
+ * ignored.
+ * </p>
+ *<p>
+ * An optional h specifies that a following d, i, o,
+ * x, or X conversion character applies to a type
+ * short argument (the argument will be promoted
+ * according to the integral promotions and its value
+ * converted to type short before printing).</p>
+ *<p>
+ * An optional l (ell) specifies that a following
+ * d, i, o, x, or X conversion character applies to a
+ * type long argument.</p>
+ *<p>
+ * A field width or precision may be indicated by an
+ * asterisk (*) instead of a digit string. In this
+ * case, an integer argument supplised the field width
+ * precision. The argument that is actually converted
+ * is not fetched until the conversion letter is seen,
+ * so the the arguments specifying field width or
+ * precision must appear before the argument (if any)
+ * to be converted. If the precision argument is
+ * negative, it will be changed to zero. A negative
+ * field width argument is taken as a - flag, followed
+ * by a positive field width.</p>
+ * <p>
+ * In format strings containing the %<code>n</code>$
+ * form of a conversion specification, a field width
+ * or precision may be indicated by the sequence
+ * *<code>m</code>$, where m is a decimal integer
+ * giving the position in the argument list (after the
+ * format argument) of an integer argument containing
+ * the field width or precision.</p>
+ * <p>
+ * The format can contain either numbered argument
+ * specifications (that is, %<code>n</code>$ and
+ * *<code>m</code>$), or unnumbered argument
+ * specifications (that is % and *), but normally not
+ * both. The only exception to this is that %% can
+ * be mixed with the %<code>n</code>$ form. The
+ * results of mixing numbered and unnumbered argument
+ * specifications in a format string are undefined.</p>
+ *
+ *<h4>Flag Characters</h4>
+ *<p>
+ * The flags and their meanings are:</p>
+ *<dl>
+ * <dt>'<dd> integer portion of the result of a
+ * decimal conversion (%i, %d, %f, %g, or %G) will
+ * be formatted with thousands' grouping
+ * characters. For other conversions the flag
+ * is ignored. The non-monetary grouping
+ * character is used.
+ * <dt>-<dd> result of the conversion is left-justified
+ * within the field. (It will be right-justified
+ * if this flag is not specified).</td></tr>
+ * <dt>+<dd> result of a signed conversion always
+ * begins with a sign (+ or -). (It will begin
+ * with a sign only when a negative value is
+ * converted if this flag is not specified.)
+ * <dt>&lt;space&gt;<dd> If the first character of a
+ * signed conversion is not a sign, a space
+ * character will be placed before the result.
+ * This means that if the space character and +
+ * flags both appear, the space flag will be
+ * ignored.
+ * <dt>#<dd> value is to be converted to an alternative
+ * form. For c, d, i, and s conversions, the flag
+ * has no effect. For o conversion, it increases
+ * the precision to force the first digit of the
+ * result to be a zero. For x or X conversion, a
+ * non-zero result has 0x or 0X prefixed to it,
+ * respectively. For e, E, f, g, and G
+ * conversions, the result always contains a radix
+ * character, even if no digits follow the radix
+ * character (normally, a decimal point appears in
+ * the result of these conversions only if a digit
+ * follows it). For g and G conversions, trailing
+ * zeros will not be removed from the result as
+ * they normally are.
+ * <dt>0<dd> d, i, o, x, X, e, E, f, g, and G
+ * conversions, leading zeros (following any
+ * indication of sign or base) are used to pad to
+ * the field width; no space padding is
+ * performed. If the 0 and - flags both appear,
+ * the 0 flag is ignored. For d, i, o, x, and X
+ * conversions, if a precision is specified, the
+ * 0 flag will be ignored. For c conversions,
+ * the flag is ignored.
+ *</dl>
+ *
+ *<h4>Conversion Characters</h4>
+ *<p>
+ * Each conversion character results in fetching zero
+ * or more arguments. The results are undefined if
+ * there are insufficient arguments for the format.
+ * Usually, an unchecked exception will be thrown.
+ * If the format is exhausted while arguments remain,
+ * the excess arguments are ignored.</p>
+ *
+ *<p>
+ * The conversion characters and their meanings are:
+ *</p>
+ *<dl>
+ * <dt>d,i<dd>The int argument is converted to a
+ * signed decimal in the style [-]dddd. The
+ * precision specifies the minimum number of
+ * digits to appear; if the value being
+ * converted can be represented in fewer
+ * digits, it will be expanded with leading
+ * zeros. The default precision is 1. The
+ * result of converting 0 with an explicit
+ * precision of 0 is no characters.
+ * <dt>o<dd> The int argument is converted to unsigned
+ * octal format in the style ddddd. The
+ * precision specifies the minimum number of
+ * digits to appear; if the value being
+ * converted can be represented in fewer
+ * digits, it will be expanded with leading
+ * zeros. The default precision is 1. The
+ * result of converting 0 with an explicit
+ * precision of 0 is no characters.
+ * <dt>x<dd> The int argument is converted to unsigned
+ * hexadecimal format in the style dddd; the
+ * letters abcdef are used. The precision
+ * specifies the minimum numberof digits to
+ * appear; if the value being converted can be
+ * represented in fewer digits, it will be
+ * expanded with leading zeros. The default
+ * precision is 1. The result of converting 0
+ * with an explicit precision of 0 is no
+ * characters.
+ * <dt>X<dd> Behaves the same as the x conversion
+ * character except that letters ABCDEF are
+ * used instead of abcdef.
+ * <dt>f<dd> The floating point number argument is
+ * written in decimal notation in the style
+ * [-]ddd.ddd, where the number of digits after
+ * the radix character (shown here as a decimal
+ * point) is equal to the precision
+ * specification. A Locale is used to determine
+ * the radix character to use in this format.
+ * If the precision is omitted from the
+ * argument, six digits are written after the
+ * radix character; if the precision is
+ * explicitly 0 and the # flag is not specified,
+ * no radix character appears. If a radix
+ * character appears, at least 1 digit appears
+ * before it. The value is rounded to the
+ * appropriate number of digits.
+ * <dt>e,E<dd>The floating point number argument is
+ * written in the style [-]d.ddde{+-}dd
+ * (the symbols {+-} indicate either a plus or
+ * minus sign), where there is one digit before
+ * the radix character (shown here as a decimal
+ * point) and the number of digits after it is
+ * equal to the precision. A Locale is used to
+ * determine the radix character to use in this
+ * format. When the precision is missing, six
+ * digits are written after the radix character;
+ * if the precision is 0 and the # flag is not
+ * specified, no radix character appears. The
+ * E conversion will produce a number with E
+ * instead of e introducing the exponent. The
+ * exponent always contains at least two digits.
+ * However, if the value to be written requires
+ * an exponent greater than two digits,
+ * additional exponent digits are written as
+ * necessary. The value is rounded to the
+ * appropriate number of digits.
+ * <dt>g,G<dd>The floating point number argument is
+ * written in style f or e (or in sytle E in the
+ * case of a G conversion character), with the
+ * precision specifying the number of
+ * significant digits. If the precision is
+ * zero, it is taken as one. The style used
+ * depends on the value converted: style e
+ * (or E) will be used only if the exponent
+ * resulting from the conversion is less than
+ * -4 or greater than or equal to the precision.
+ * Trailing zeros are removed from the result.
+ * A radix character appears only if it is
+ * followed by a digit.
+ * <dt>c,C<dd>The integer argument is converted to a
+ * char and the result is written.
+ *
+ * <dt>s,S<dd>The argument is taken to be a string and
+ * bytes from the string are written until the
+ * end of the string or the number of bytes
+ * indicated by the precision specification of
+ * the argument is reached. If the precision
+ * is omitted from the argument, it is taken to
+ * be infinite, so all characters up to the end
+ * of the string are written.
+ * <dt>%<dd>Write a % character; no argument is
+ * converted.
+ *</dl>
+ *<p>
+ * If a conversion specification does not match one of
+ * the above forms, an IllegalArgumentException is
+ * thrown and the instance of PrintfFormat is not
+ * created.</p>
+ *<p>
+ * If a floating point value is the internal
+ * representation for infinity, the output is
+ * [+]Infinity, where Infinity is either Infinity or
+ * Inf, depending on the desired output string length.
+ * Printing of the sign follows the rules described
+ * above.</p>
+ *<p>
+ * If a floating point value is the internal
+ * representation for "not-a-number," the output is
+ * [+]NaN. Printing of the sign follows the rules
+ * described above.</p>
+ *<p>
+ * In no case does a non-existent or small field width
+ * cause truncation of a field; if the result of a
+ * conversion is wider than the field width, the field
+ * is simply expanded to contain the conversion result.
+ *</p>
+ *<p>
+ * The behavior is like printf. One exception is that
+ * the minimum number of exponent digits is 3 instead
+ * of 2 for e and E formats when the optional L is used
+ * before the e, E, g, or G conversion character. The
+ * optional L does not imply conversion to a long long
+ * double. </p>
+ * <p>
+ * The biggest divergence from the C printf
+ * specification is in the use of 16 bit characters.
+ * This allows the handling of characters beyond the
+ * small ASCII character set and allows the utility to
+ * interoperate correctly with the rest of the Java
+ * runtime environment.</p>
+ *<p>
+ * Omissions from the C printf specification are
+ * numerous. All the known omissions are present
+ * because Java never uses bytes to represent
+ * characters and does not have pointers:</p>
+ *<ul>
+ * <li>%c is the same as %C.
+ * <li>%s is the same as %S.
+ * <li>u, p, and n conversion characters.
+ * <li>%ws format.
+ * <li>h modifier applied to an n conversion character.
+ * <li>l (ell) modifier applied to the c, n, or s
+ * conversion characters.
+ * <li>ll (ell ell) modifier to d, i, o, u, x, or X
+ * conversion characters.
+ * <li>ll (ell ell) modifier to an n conversion
+ * character.
+ * <li>c, C, d,i,o,u,x, and X conversion characters
+ * apply to Byte, Character, Short, Integer, Long
+ * types.
+ * <li>f, e, E, g, and G conversion characters apply
+ * to Float and Double types.
+ * <li>s and S conversion characters apply to String
+ * types.
+ * <li>All other reference types can be formatted
+ * using the s or S conversion characters only.
+ *</ul>
+ * <p>
+ * Most of this specification is quoted from the Unix
+ * man page for the sprintf utility.</p>
+ *
+ * @author Allan Jacobs
+ * @version 1
+ * Release 1: Initial release.
+ * Release 2: Asterisk field widths and precisions
+ * %n$ and *m$
+ * Bug fixes
+ * g format fix (2 digits in e form corrupt)
+ * rounding in f format implemented
+ * round up when digit not printed is 5
+ * formatting of -0.0f
+ * round up/down when last digits are 50000...
+ */
+public class PrintfFormat {
+ /**
+ * Constructs an array of control specifications
+ * possibly preceded, separated, or followed by
+ * ordinary strings. Control strings begin with
+ * unpaired percent signs. A pair of successive
+ * percent signs designates a single percent sign in
+ * the format.
+ * @param fmtArg Control string.
+ * @exception IllegalArgumentException if the control
+ * string is null, zero length, or otherwise
+ * malformed.
+ */
+ public PrintfFormat(String fmtArg)
+ throws IllegalArgumentException {
+ this(Locale.getDefault(),fmtArg);
+ }
+ /**
+ * Constructs an array of control specifications
+ * possibly preceded, separated, or followed by
+ * ordinary strings. Control strings begin with
+ * unpaired percent signs. A pair of successive
+ * percent signs designates a single percent sign in
+ * the format.
+ * @param fmtArg Control string.
+ * @exception IllegalArgumentException if the control
+ * string is null, zero length, or otherwise
+ * malformed.
+ */
+ public PrintfFormat(Locale locale,String fmtArg)
+ throws IllegalArgumentException {
+ dfs = new DecimalFormatSymbols(locale);
+ int ePos=0;
+ ConversionSpecification sFmt=null;
+ String unCS = this.nonControl(fmtArg,0);
+ if (unCS!=null) {
+ sFmt = new ConversionSpecification();
+ sFmt.setLiteral(unCS);
+ vFmt.addElement(sFmt);
+ }
+ while(cPos!=-1 && cPos<fmtArg.length()) {
+ for (ePos=cPos+1; ePos<fmtArg.length();
+ ePos++) {
+ char c=0;
+ c = fmtArg.charAt(ePos);
+ if (c == 'i') break;
+ if (c == 'd') break;
+ if (c == 'f') break;
+ if (c == 'g') break;
+ if (c == 'G') break;
+ if (c == 'o') break;
+ if (c == 'x') break;
+ if (c == 'X') break;
+ if (c == 'e') break;
+ if (c == 'E') break;
+ if (c == 'c') break;
+ if (c == 's') break;
+ if (c == '%') break;
+ }
+ ePos=Math.min(ePos+1,fmtArg.length());
+ sFmt = new ConversionSpecification(
+ fmtArg.substring(cPos,ePos));
+ vFmt.addElement(sFmt);
+ unCS = this.nonControl(fmtArg,ePos);
+ if (unCS!=null) {
+ sFmt = new ConversionSpecification();
+ sFmt.setLiteral(unCS);
+ vFmt.addElement(sFmt);
+ }
+ }
+ }
+ /**
+ * Return a substring starting at
+ * <code>start</code> and ending at either the end
+ * of the String <code>s</code>, the next unpaired
+ * percent sign, or at the end of the String if the
+ * last character is a percent sign.
+ * @param s Control string.
+ * @param start Position in the string
+ * <code>s</code> to begin looking for the start
+ * of a control string.
+ * @return the substring from the start position
+ * to the beginning of the control string.
+ */
+ private String nonControl(String s,int start) {
+ String ret="";
+ cPos=s.indexOf("%",start);
+ if (cPos==-1) cPos=s.length();
+ return s.substring(start,cPos);
+ }
+ /**
+ * Format an array of objects. Byte, Short,
+ * Integer, Long, Float, Double, and Character
+ * arguments are treated as wrappers for primitive
+ * types.
+ * @param o The array of objects to format.
+ * @return The formatted String.
+ */
+ public String sprintf(Object[] o) {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ int i=0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ else {
+ if (cs.isPositionalSpecification()) {
+ i=cs.getArgumentPosition()-1;
+ if (cs.isPositionalFieldWidth()) {
+ int ifw=cs.getArgumentPositionForFieldWidth()-1;
+ cs.setFieldWidthWithArg(((Integer)o[ifw]).intValue());
+ }
+ if (cs.isPositionalPrecision()) {
+ int ipr=cs.getArgumentPositionForPrecision()-1;
+ cs.setPrecisionWithArg(((Integer)o[ipr]).intValue());
+ }
+ }
+ else {
+ if (cs.isVariableFieldWidth()) {
+ cs.setFieldWidthWithArg(((Integer)o[i]).intValue());
+ i++;
+ }
+ if (cs.isVariablePrecision()) {
+ cs.setPrecisionWithArg(((Integer)o[i]).intValue());
+ i++;
+ }
+ }
+ if (o[i] instanceof Byte)
+ sb.append(cs.internalsprintf(
+ ((Byte)o[i]).byteValue()));
+ else if (o[i] instanceof Short)
+ sb.append(cs.internalsprintf(
+ ((Short)o[i]).shortValue()));
+ else if (o[i] instanceof Integer)
+ sb.append(cs.internalsprintf(
+ ((Integer)o[i]).intValue()));
+ else if (o[i] instanceof Long)
+ sb.append(cs.internalsprintf(
+ ((Long)o[i]).longValue()));
+ else if (o[i] instanceof Float)
+ sb.append(cs.internalsprintf(
+ ((Float)o[i]).floatValue()));
+ else if (o[i] instanceof Double)
+ sb.append(cs.internalsprintf(
+ ((Double)o[i]).doubleValue()));
+ else if (o[i] instanceof Character)
+ sb.append(cs.internalsprintf(
+ ((Character)o[i]).charValue()));
+ else if (o[i] instanceof String)
+ sb.append(cs.internalsprintf(
+ (String)o[i]));
+ else
+ sb.append(cs.internalsprintf(
+ o[i]));
+ if (!cs.isPositionalSpecification())
+ i++;
+ }
+ }
+ return sb.toString();
+ }
+ /**
+ * Format nothing. Just use the control string.
+ * @return the formatted String.
+ */
+ public String sprintf() {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ }
+ return sb.toString();
+ }
+ /**
+ * Format an int.
+ * @param x The int to format.
+ * @return The formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is f, e, E, g, G, s,
+ * or S.
+ */
+ public String sprintf(int x)
+ throws IllegalArgumentException {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ else sb.append(cs.internalsprintf(x));
+ }
+ return sb.toString();
+ }
+ /**
+ * Format an long.
+ * @param x The long to format.
+ * @return The formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is f, e, E, g, G, s,
+ * or S.
+ */
+ public String sprintf(long x)
+ throws IllegalArgumentException {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ else sb.append(cs.internalsprintf(x));
+ }
+ return sb.toString();
+ }
+ /**
+ * Format a double.
+ * @param x The double to format.
+ * @return The formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is c, C, s, S,
+ * d, d, x, X, or o.
+ */
+ public String sprintf(double x)
+ throws IllegalArgumentException {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ else sb.append(cs.internalsprintf(x));
+ }
+ return sb.toString();
+ }
+ /**
+ * Format a String.
+ * @param x The String to format.
+ * @return The formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is neither s nor S.
+ */
+ public String sprintf(String x)
+ throws IllegalArgumentException {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ else sb.append(cs.internalsprintf(x));
+ }
+ return sb.toString();
+ }
+ /**
+ * Format an Object. Convert wrapper types to
+ * their primitive equivalents and call the
+ * appropriate internal formatting method. Convert
+ * Strings using an internal formatting method for
+ * Strings. Otherwise use the default formatter
+ * (use toString).
+ * @param x the Object to format.
+ * @return the formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is inappropriate for
+ * formatting an unwrapped value.
+ */
+ public String sprintf(Object x)
+ throws IllegalArgumentException {
+ Enumeration e = vFmt.elements();
+ ConversionSpecification cs = null;
+ char c = 0;
+ StringBuffer sb=new StringBuffer();
+ while (e.hasMoreElements()) {
+ cs = (ConversionSpecification)
+ e.nextElement();
+ c = cs.getConversionCharacter();
+ if (c=='\0') sb.append(cs.getLiteral());
+ else if (c=='%') sb.append("%");
+ else {
+ if (x instanceof Byte)
+ sb.append(cs.internalsprintf(
+ ((Byte)x).byteValue()));
+ else if (x instanceof Short)
+ sb.append(cs.internalsprintf(
+ ((Short)x).shortValue()));
+ else if (x instanceof Integer)
+ sb.append(cs.internalsprintf(
+ ((Integer)x).intValue()));
+ else if (x instanceof Long)
+ sb.append(cs.internalsprintf(
+ ((Long)x).longValue()));
+ else if (x instanceof Float)
+ sb.append(cs.internalsprintf(
+ ((Float)x).floatValue()));
+ else if (x instanceof Double)
+ sb.append(cs.internalsprintf(
+ ((Double)x).doubleValue()));
+ else if (x instanceof Character)
+ sb.append(cs.internalsprintf(
+ ((Character)x).charValue()));
+ else if (x instanceof String)
+ sb.append(cs.internalsprintf(
+ (String)x));
+ else
+ sb.append(cs.internalsprintf(x));
+ }
+ }
+ return sb.toString();
+ }
+ /**
+ *<p>
+ * ConversionSpecification allows the formatting of
+ * a single primitive or object embedded within a
+ * string. The formatting is controlled by a
+ * format string. Only one Java primitive or
+ * object can be formatted at a time.
+ *<p>
+ * A format string is a Java string that contains
+ * a control string. The control string starts at
+ * the first percent sign (%) in the string,
+ * provided that this percent sign
+ *<ol>
+ *<li>is not escaped protected by a matching % or
+ * is not an escape % character,
+ *<li>is not at the end of the format string, and
+ *<li>precedes a sequence of characters that parses
+ * as a valid control string.
+ *</ol>
+ *<p>
+ * A control string takes the form:
+ *<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
+ * { [hlL] }+ [idfgGoxXeEcs]
+ *</pre>
+ *<p>
+ * The behavior is like printf. One (hopefully the
+ * only) exception is that the minimum number of
+ * exponent digits is 3 instead of 2 for e and E
+ * formats when the optional L is used before the
+ * e, E, g, or G conversion character. The
+ * optional L does not imply conversion to a long
+ * long double.
+ */
+ private class ConversionSpecification {
+ /**
+ * Constructor. Used to prepare an instance
+ * to hold a literal, not a control string.
+ */
+ ConversionSpecification() { }
+ /**
+ * Constructor for a conversion specification.
+ * The argument must begin with a % and end
+ * with the conversion character for the
+ * conversion specification.
+ * @param fmtArg String specifying the
+ * conversion specification.
+ * @exception IllegalArgumentException if the
+ * input string is null, zero length, or
+ * otherwise malformed.
+ */
+ ConversionSpecification(String fmtArg)
+ throws IllegalArgumentException {
+ if (fmtArg==null)
+ throw new NullPointerException();
+ if (fmtArg.length()==0)
+ throw new IllegalArgumentException(
+ "Control strings must have positive"+
+ " lengths.");
+ if (fmtArg.charAt(0)=='%') {
+ fmt = fmtArg;
+ pos=1;
+ setArgPosition();
+ setFlagCharacters();
+ setFieldWidth();
+ setPrecision();
+ setOptionalHL();
+ if (setConversionCharacter()) {
+ if (pos==fmtArg.length()) {
+ if(leadingZeros&&leftJustify)
+ leadingZeros=false;
+ if(precisionSet&&leadingZeros){
+ if(conversionCharacter=='d'
+ ||conversionCharacter=='i'
+ ||conversionCharacter=='o'
+ ||conversionCharacter=='x')
+ {
+ leadingZeros=false;
+ }
+ }
+ }
+ else
+ throw new IllegalArgumentException(
+ "Malformed conversion specification="+
+ fmtArg);
+ }
+ else
+ throw new IllegalArgumentException(
+ "Malformed conversion specification="+
+ fmtArg);
+ }
+ else
+ throw new IllegalArgumentException(
+ "Control strings must begin with %.");
+ }
+ /**
+ * Set the String for this instance.
+ * @param s the String to store.
+ */
+ void setLiteral(String s) {
+ fmt = s;
+ }
+ /**
+ * Get the String for this instance. Translate
+ * any escape sequences.
+ *
+ * @return s the stored String.
+ */
+ String getLiteral() {
+ StringBuffer sb=new StringBuffer();
+ int i=0;
+ while (i<fmt.length()) {
+ if (fmt.charAt(i)=='\\') {
+ i++;
+ if (i<fmt.length()) {
+ char c=fmt.charAt(i);
+ switch(c) {
+ case 'a':
+ sb.append((char)0x07);
+ break;
+ case 'b':
+ sb.append('\b');
+ break;
+ case 'f':
+ sb.append('\f');
+ break;
+ case 'n':
+ sb.append(System.getProperty("line.separator"));
+ break;
+ case 'r':
+ sb.append('\r');
+ break;
+ case 't':
+ sb.append('\t');
+ break;
+ case 'v':
+ sb.append((char)0x0b);
+ break;
+ case '\\':
+ sb.append('\\');
+ break;
+ }
+ i++;
+ }
+ else
+ sb.append('\\');
+ }
+ else
+ i++;
+ }
+ return fmt;
+ }
+ /**
+ * Get the conversion character that tells what
+ * type of control character this instance has.
+ *
+ * @return the conversion character.
+ */
+ char getConversionCharacter() {
+ return conversionCharacter;
+ }
+ /**
+ * Check whether the specifier has a variable
+ * field width that is going to be set by an
+ * argument.
+ * @return <code>true</code> if the conversion
+ * uses an * field width; otherwise
+ * <code>false</code>.
+ */
+ boolean isVariableFieldWidth() {
+ return variableFieldWidth;
+ }
+ /**
+ * Set the field width with an argument. A
+ * negative field width is taken as a - flag
+ * followed by a positive field width.
+ * @param fw the field width.
+ */
+ void setFieldWidthWithArg(int fw) {
+ if (fw<0) leftJustify = true;
+ fieldWidthSet = true;
+ fieldWidth = Math.abs(fw);
+ }
+ /**
+ * Check whether the specifier has a variable
+ * precision that is going to be set by an
+ * argument.
+ * @return <code>true</code> if the conversion
+ * uses an * precision; otherwise
+ * <code>false</code>.
+ */
+ boolean isVariablePrecision() {
+ return variablePrecision;
+ }
+ /**
+ * Set the precision with an argument. A
+ * negative precision will be changed to zero.
+ * @param pr the precision.
+ */
+ void setPrecisionWithArg(int pr) {
+ precisionSet = true;
+ precision = Math.max(pr,0);
+ }
+ /**
+ * Format an int argument using this conversion
+ * specification.
+ * @param s the int to format.
+ * @return the formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is f, e, E, g, or G.
+ */
+ String internalsprintf(int s)
+ throws IllegalArgumentException {
+ String s2 = "";
+ switch(conversionCharacter) {
+ case 'd':
+ case 'i':
+ if (optionalh)
+ s2 = printDFormat((short)s);
+ else if (optionall)
+ s2 = printDFormat((long)s);
+ else
+ s2 = printDFormat(s);
+ break;
+ case 'x':
+ case 'X':
+ if (optionalh)
+ s2 = printXFormat((short)s);
+ else if (optionall)
+ s2 = printXFormat((long)s);
+ else
+ s2 = printXFormat(s);
+ break;
+ case 'o':
+ if (optionalh)
+ s2 = printOFormat((short)s);
+ else if (optionall)
+ s2 = printOFormat((long)s);
+ else
+ s2 = printOFormat(s);
+ break;
+ case 'c':
+ case 'C':
+ s2 = printCFormat((char)s);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Cannot format a int with a format using a "+
+ conversionCharacter+
+ " conversion character.");
+ }
+ return s2;
+ }
+ /**
+ * Format a long argument using this conversion
+ * specification.
+ * @param s the long to format.
+ * @return the formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is f, e, E, g, or G.
+ */
+ String internalsprintf(long s)
+ throws IllegalArgumentException {
+ String s2 = "";
+ switch(conversionCharacter) {
+ case 'd':
+ case 'i':
+ if (optionalh)
+ s2 = printDFormat((short)s);
+ else if (optionall)
+ s2 = printDFormat(s);
+ else
+ s2 = printDFormat((int)s);
+ break;
+ case 'x':
+ case 'X':
+ if (optionalh)
+ s2 = printXFormat((short)s);
+ else if (optionall)
+ s2 = printXFormat(s);
+ else
+ s2 = printXFormat((int)s);
+ break;
+ case 'o':
+ if (optionalh)
+ s2 = printOFormat((short)s);
+ else if (optionall)
+ s2 = printOFormat(s);
+ else
+ s2 = printOFormat((int)s);
+ break;
+ case 'c':
+ case 'C':
+ s2 = printCFormat((char)s);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Cannot format a long with a format using a "+
+ conversionCharacter+" conversion character.");
+ }
+ return s2;
+ }
+ /**
+ * Format a double argument using this conversion
+ * specification.
+ * @param s the double to format.
+ * @return the formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is c, C, s, S, i, d,
+ * x, X, or o.
+ */
+ String internalsprintf(double s)
+ throws IllegalArgumentException {
+ String s2 = "";
+ switch(conversionCharacter) {
+ case 'f':
+ s2 = printFFormat(s);
+ break;
+ case 'E':
+ case 'e':
+ s2 = printEFormat(s);
+ break;
+ case 'G':
+ case 'g':
+ s2 = printGFormat(s);
+ break;
+ default:
+ throw new IllegalArgumentException("Cannot "+
+ "format a double with a format using a "+
+ conversionCharacter+" conversion character.");
+ }
+ return s2;
+ }
+ /**
+ * Format a String argument using this conversion
+ * specification.
+ * @param s the String to format.
+ * @return the formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is neither s nor S.
+ */
+ String internalsprintf(String s)
+ throws IllegalArgumentException {
+ String s2 = "";
+ if(conversionCharacter=='s'
+ || conversionCharacter=='S')
+ s2 = printSFormat(s);
+ else
+ throw new IllegalArgumentException("Cannot "+
+ "format a String with a format using a "+
+ conversionCharacter+" conversion character.");
+ return s2;
+ }
+ /**
+ * Format an Object argument using this conversion
+ * specification.
+ * @param s the Object to format.
+ * @return the formatted String.
+ * @exception IllegalArgumentException if the
+ * conversion character is neither s nor S.
+ */
+ String internalsprintf(Object s) {
+ String s2 = "";
+ if(conversionCharacter=='s'
+ || conversionCharacter=='S')
+ s2 = printSFormat(s.toString());
+ else
+ throw new IllegalArgumentException(
+ "Cannot format a String with a format using"+
+ " a "+conversionCharacter+
+ " conversion character.");
+ return s2;
+ }
+ /**
+ * For f format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. '+' character means that the conversion
+ * will always begin with a sign (+ or -). The
+ * blank flag character means that a non-negative
+ * input will be preceded with a blank. If both
+ * a '+' and a ' ' are specified, the blank flag
+ * is ignored. The '0' flag character implies that
+ * padding to the field width will be done with
+ * zeros instead of blanks.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the number of digits
+ * to appear after the radix character. Padding is
+ * with trailing 0s.
+ */
+ private char[] fFormatDigits(double x) {
+ // int defaultDigits=6;
+ String sx,sxOut;
+ int i,j,k;
+ int n1In,n2In;
+ int expon=0;
+ boolean minusSign=false;
+ if (x>0.0)
+ sx = Double.toString(x);
+ else if (x<0.0) {
+ sx = Double.toString(-x);
+ minusSign=true;
+ }
+ else {
+ sx = Double.toString(x);
+ if (sx.charAt(0)=='-') {
+ minusSign=true;
+ sx=sx.substring(1);
+ }
+ }
+ int ePos = sx.indexOf('E');
+ int rPos = sx.indexOf('.');
+ if (rPos!=-1) n1In=rPos;
+ else if (ePos!=-1) n1In=ePos;
+ else n1In=sx.length();
+ if (rPos!=-1) {
+ if (ePos!=-1) n2In = ePos-rPos-1;
+ else n2In = sx.length()-rPos-1;
+ }
+ else
+ n2In = 0;
+ if (ePos!=-1) {
+ int ie=ePos+1;
+ expon=0;
+ if (sx.charAt(ie)=='-') {
+ for (++ie; ie<sx.length(); ie++)
+ if (sx.charAt(ie)!='0') break;
+ if (ie<sx.length())
+ expon=-Integer.parseInt(sx.substring(ie));
+ }
+ else {
+ if (sx.charAt(ie)=='+') ++ie;
+ for (; ie<sx.length(); ie++)
+ if (sx.charAt(ie)!='0') break;
+ if (ie<sx.length())
+ expon=Integer.parseInt(sx.substring(ie));
+ }
+ }
+ int p;
+ if (precisionSet) p = precision;
+ else p = defaultDigits-1;
+ char[] ca1 = sx.toCharArray();
+ char[] ca2 = new char[n1In+n2In];
+ char[] ca3,ca4,ca5;
+ for (j=0; j<n1In; j++)
+ ca2[j] = ca1[j];
+ i = j+1;
+ for (k=0; k<n2In; j++,i++,k++)
+ ca2[j] = ca1[i];
+ if (n1In+expon<=0) {
+ ca3 = new char[-expon+n2In];
+ for (j=0,k=0; k<(-n1In-expon); k++,j++)
+ ca3[j]='0';
+ for (i=0; i<(n1In+n2In); i++,j++)
+ ca3[j]=ca2[i];
+ }
+ else
+ ca3 = ca2;
+ boolean carry=false;
+ if (p<-expon+n2In) {
+ if (expon<0) i = p;
+ else i = p+n1In;
+ carry=checkForCarry(ca3,i);
+ if (carry)
+ carry=startSymbolicCarry(ca3,i-1,0);
+ }
+ if (n1In+expon<=0) {
+ ca4 = new char[2+p];
+ if (!carry) ca4[0]='0';
+ else ca4[0]='1';
+ if(alternateForm||!precisionSet||precision!=0){
+ ca4[1]='.';
+ for(i=0,j=2;i<Math.min(p,ca3.length);i++,j++)
+ ca4[j]=ca3[i];
+ for (; j<ca4.length; j++) ca4[j]='0';
+ }
+ }
+ else {
+ if (!carry) {
+ if(alternateForm||!precisionSet
+ ||precision!=0)
+ ca4 = new char[n1In+expon+p+1];
+ else
+ ca4 = new char[n1In+expon];
+ j=0;
+ }
+ else {
+ if(alternateForm||!precisionSet
+ ||precision!=0)
+ ca4 = new char[n1In+expon+p+2];
+ else
+ ca4 = new char[n1In+expon+1];
+ ca4[0]='1';
+ j=1;
+ }
+ for (i=0; i<Math.min(n1In+expon,ca3.length); i++,j++)
+ ca4[j]=ca3[i];
+ for (; i<n1In+expon; i++,j++)
+ ca4[j]='0';
+ if(alternateForm||!precisionSet||precision!=0){
+ ca4[j]='.'; j++;
+ for (k=0; i<ca3.length && k<p; i++,j++,k++)
+ ca4[j]=ca3[i];
+ for (; j<ca4.length; j++) ca4[j]='0';
+ }
+ }
+ int nZeros=0;
+ if (!leftJustify && leadingZeros) {
+ int xThousands=0;
+ if (thousands) {
+ int xlead=0;
+ if (ca4[0]=='+'||ca4[0]=='-'||ca4[0]==' ')
+ xlead=1;
+ int xdp=xlead;
+ for (; xdp<ca4.length; xdp++)
+ if (ca4[xdp]=='.') break;
+ xThousands=(xdp-xlead)/3;
+ }
+ if (fieldWidthSet)
+ nZeros = fieldWidth-ca4.length;
+ if ((!minusSign&&(leadingSign||leadingSpace))||minusSign)
+ nZeros--;
+ nZeros-=xThousands;
+ if (nZeros<0) nZeros=0;
+ }
+ j=0;
+ if ((!minusSign&&(leadingSign||leadingSpace))||minusSign) {
+ ca5 = new char[ca4.length+nZeros+1];
+ j++;
+ }
+ else
+ ca5 = new char[ca4.length+nZeros];
+ if (!minusSign) {
+ if (leadingSign) ca5[0]='+';
+ if (leadingSpace) ca5[0]=' ';
+ }
+ else
+ ca5[0]='-';
+ for (i=0; i<nZeros; i++,j++)
+ ca5[j]='0';
+ for (i=0; i<ca4.length; i++,j++) ca5[j]=ca4[i];
+
+ int lead=0;
+ if (ca5[0]=='+'||ca5[0]=='-'||ca5[0]==' ')
+ lead=1;
+ int dp=lead;
+ for (; dp<ca5.length; dp++)
+ if (ca5[dp]=='.') break;
+ int nThousands=(dp-lead)/3;
+ // Localize the decimal point.
+ if (dp<ca5.length)
+ ca5[dp]=dfs.getDecimalSeparator();
+ char[] ca6 = ca5;
+ if (thousands && nThousands>0) {
+ ca6 = new char[ca5.length+nThousands+lead];
+ ca6[0]=ca5[0];
+ for (i=lead,k=lead; i<dp; i++) {
+ if (i>0 && (dp-i)%3==0) {
+ // ca6[k]=',';
+ ca6[k]=dfs.getGroupingSeparator();
+ ca6[k+1]=ca5[i];
+ k+=2;
+ }
+ else {
+ ca6[k]=ca5[i]; k++;
+ }
+ }
+ for (; i<ca5.length; i++,k++) {
+ ca6[k]=ca5[i];
+ }
+ }
+ return ca6;
+ }
+ /**
+ * An intermediate routine on the way to creating
+ * an f format String. The method decides whether
+ * the input double value is an infinity,
+ * not-a-number, or a finite double and formats
+ * each type of input appropriately.
+ * @param x the double value to be formatted.
+ * @return the converted double value.
+ */
+ private String fFormatString(double x) {
+ boolean noDigits=false;
+ char[] ca6,ca7;
+ if (Double.isInfinite(x)) {
+ if (x==Double.POSITIVE_INFINITY) {
+ if (leadingSign) ca6 = "+Inf".toCharArray();
+ else if (leadingSpace)
+ ca6 = " Inf".toCharArray();
+ else ca6 = "Inf".toCharArray();
+ }
+ else
+ ca6 = "-Inf".toCharArray();
+ noDigits = true;
+ }
+ else if (Double.isNaN(x)) {
+ if (leadingSign) ca6 = "+NaN".toCharArray();
+ else if (leadingSpace)
+ ca6 = " NaN".toCharArray();
+ else ca6 = "NaN".toCharArray();
+ noDigits = true;
+ }
+ else
+ ca6 = fFormatDigits(x);
+ ca7 = applyFloatPadding(ca6,false);
+ return new String(ca7);
+ }
+ /**
+ * For e format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. '+' character means that the conversion
+ * will always begin with a sign (+ or -). The
+ * blank flag character means that a non-negative
+ * input will be preceded with a blank. If both a
+ * '+' and a ' ' are specified, the blank flag is
+ * ignored. The '0' flag character implies that
+ * padding to the field width will be done with
+ * zeros instead of blanks.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear after the radix character.
+ * Padding is with trailing 0s.
+ *
+ * The behavior is like printf. One (hopefully the
+ * only) exception is that the minimum number of
+ * exponent digits is 3 instead of 2 for e and E
+ * formats when the optional L is used before the
+ * e, E, g, or G conversion character. The optional
+ * L does not imply conversion to a long long
+ * double.
+ */
+ private char[] eFormatDigits(double x,char eChar) {
+ char[] ca1,ca2,ca3;
+ // int defaultDigits=6;
+ String sx,sxOut;
+ int i,j,k,p;
+ int n1In,n2In;
+ int expon=0;
+ int ePos,rPos,eSize;
+ boolean minusSign=false;
+ if (x>0.0)
+ sx = Double.toString(x);
+ else if (x<0.0) {
+ sx = Double.toString(-x);
+ minusSign=true;
+ }
+ else {
+ sx = Double.toString(x);
+ if (sx.charAt(0)=='-') {
+ minusSign=true;
+ sx=sx.substring(1);
+ }
+ }
+ ePos = sx.indexOf('E');
+ if (ePos==-1) ePos = sx.indexOf('e');
+ rPos = sx.indexOf('.');
+ if (rPos!=-1) n1In=rPos;
+ else if (ePos!=-1) n1In=ePos;
+ else n1In=sx.length();
+ if (rPos!=-1) {
+ if (ePos!=-1) n2In = ePos-rPos-1;
+ else n2In = sx.length()-rPos-1;
+ }
+ else
+ n2In = 0;
+ if (ePos!=-1) {
+ int ie=ePos+1;
+ expon=0;
+ if (sx.charAt(ie)=='-') {
+ for (++ie; ie<sx.length(); ie++)
+ if (sx.charAt(ie)!='0') break;
+ if (ie<sx.length())
+ expon=-Integer.parseInt(sx.substring(ie));
+ }
+ else {
+ if (sx.charAt(ie)=='+') ++ie;
+ for (; ie<sx.length(); ie++)
+ if (sx.charAt(ie)!='0') break;
+ if (ie<sx.length())
+ expon=Integer.parseInt(sx.substring(ie));
+ }
+ }
+ if (rPos!=-1) expon += rPos-1;
+ if (precisionSet) p = precision;
+ else p = defaultDigits-1;
+ if (rPos!=-1 && ePos!=-1)
+ ca1=(sx.substring(0,rPos)+
+ sx.substring(rPos+1,ePos)).toCharArray();
+ else if (rPos!=-1)
+ ca1 = (sx.substring(0,rPos)+
+ sx.substring(rPos+1)).toCharArray();
+ else if (ePos!=-1)
+ ca1 = sx.substring(0,ePos).toCharArray();
+ else
+ ca1 = sx.toCharArray();
+ boolean carry=false;
+ int i0=0;
+ if (ca1[0]!='0')
+ i0 = 0;
+ else
+ for (i0=0; i0<ca1.length; i0++)
+ if (ca1[i0]!='0') break;
+ if (i0+p<ca1.length-1) {
+ carry=checkForCarry(ca1,i0+p+1);
+ if (carry)
+ carry = startSymbolicCarry(ca1,i0+p,i0);
+ if (carry) {
+ ca2 = new char[i0+p+1];
+ ca2[i0]='1';
+ for (j=0; j<i0; j++) ca2[j]='0';
+ for (i=i0,j=i0+1; j<p+1; i++,j++)
+ ca2[j] = ca1[i];
+ expon++;
+ ca1 = ca2;
+ }
+ }
+ if (Math.abs(expon)<100 && !optionalL) eSize=4;
+ else eSize=5;
+ if (alternateForm||!precisionSet||precision!=0)
+ ca2 = new char[2+p+eSize];
+ else
+ ca2 = new char[1+eSize];
+ if (ca1[0]!='0') {
+ ca2[0] = ca1[0];
+ j=1;
+ }
+ else {
+ for (j=1; j<(ePos==-1?ca1.length:ePos); j++)
+ if (ca1[j]!='0') break;
+ if ((ePos!=-1 && j<ePos)||
+ (ePos==-1 && j<ca1.length)) {
+ ca2[0] = ca1[j];
+ expon -= j;
+ j++;
+ }
+ else {
+ ca2[0]='0';
+ j=2;
+ }
+ }
+ if (alternateForm||!precisionSet||precision!=0) {
+ ca2[1] = '.';
+ i=2;
+ }
+ else
+ i=1;
+ for (k=0; k<p && j<ca1.length; j++,i++,k++)
+ ca2[i] = ca1[j];
+ for (;i<ca2.length-eSize; i++)
+ ca2[i] = '0';
+ ca2[i++] = eChar;
+ if (expon<0) ca2[i++]='-';
+ else ca2[i++]='+';
+ expon = Math.abs(expon);
+ if (expon>=100) {
+ switch(expon/100) {
+ case 1: ca2[i]='1'; break;
+ case 2: ca2[i]='2'; break;
+ case 3: ca2[i]='3'; break;
+ case 4: ca2[i]='4'; break;
+ case 5: ca2[i]='5'; break;
+ case 6: ca2[i]='6'; break;
+ case 7: ca2[i]='7'; break;
+ case 8: ca2[i]='8'; break;
+ case 9: ca2[i]='9'; break;
+ }
+ i++;
+ }
+ switch((expon%100)/10) {
+ case 0: ca2[i]='0'; break;
+ case 1: ca2[i]='1'; break;
+ case 2: ca2[i]='2'; break;
+ case 3: ca2[i]='3'; break;
+ case 4: ca2[i]='4'; break;
+ case 5: ca2[i]='5'; break;
+ case 6: ca2[i]='6'; break;
+ case 7: ca2[i]='7'; break;
+ case 8: ca2[i]='8'; break;
+ case 9: ca2[i]='9'; break;
+ }
+ i++;
+ switch(expon%10) {
+ case 0: ca2[i]='0'; break;
+ case 1: ca2[i]='1'; break;
+ case 2: ca2[i]='2'; break;
+ case 3: ca2[i]='3'; break;
+ case 4: ca2[i]='4'; break;
+ case 5: ca2[i]='5'; break;
+ case 6: ca2[i]='6'; break;
+ case 7: ca2[i]='7'; break;
+ case 8: ca2[i]='8'; break;
+ case 9: ca2[i]='9'; break;
+ }
+ int nZeros=0;
+ if (!leftJustify && leadingZeros) {
+ int xThousands=0;
+ if (thousands) {
+ int xlead=0;
+ if (ca2[0]=='+'||ca2[0]=='-'||ca2[0]==' ')
+ xlead=1;
+ int xdp=xlead;
+ for (; xdp<ca2.length; xdp++)
+ if (ca2[xdp]=='.') break;
+ xThousands=(xdp-xlead)/3;
+ }
+ if (fieldWidthSet)
+ nZeros = fieldWidth-ca2.length;
+ if ((!minusSign&&(leadingSign||leadingSpace))||minusSign)
+ nZeros--;
+ nZeros-=xThousands;
+ if (nZeros<0) nZeros=0;
+ }
+ j=0;
+ if ((!minusSign&&(leadingSign || leadingSpace))||minusSign) {
+ ca3 = new char[ca2.length+nZeros+1];
+ j++;
+ }
+ else
+ ca3 = new char[ca2.length+nZeros];
+ if (!minusSign) {
+ if (leadingSign) ca3[0]='+';
+ if (leadingSpace) ca3[0]=' ';
+ }
+ else
+ ca3[0]='-';
+ for (k=0; k<nZeros; j++,k++)
+ ca3[j]='0';
+ for (i=0; i<ca2.length && j<ca3.length; i++,j++)
+ ca3[j]=ca2[i];
+
+ int lead=0;
+ if (ca3[0]=='+'||ca3[0]=='-'||ca3[0]==' ')
+ lead=1;
+ int dp=lead;
+ for (; dp<ca3.length; dp++)
+ if (ca3[dp]=='.') break;
+ int nThousands=dp/3;
+ // Localize the decimal point.
+ if (dp < ca3.length)
+ ca3[dp] = dfs.getDecimalSeparator();
+ char[] ca4 = ca3;
+ if (thousands && nThousands>0) {
+ ca4 = new char[ca3.length+nThousands+lead];
+ ca4[0]=ca3[0];
+ for (i=lead,k=lead; i<dp; i++) {
+ if (i>0 && (dp-i)%3==0) {
+ // ca4[k]=',';
+ ca4[k]=dfs.getGroupingSeparator();
+ ca4[k+1]=ca3[i];
+ k+=2;
+ }
+ else {
+ ca4[k]=ca3[i]; k++;
+ }
+ }
+ for (; i<ca3.length; i++,k++)
+ ca4[k]=ca3[i];
+ }
+ return ca4;
+ }
+ /**
+ * Check to see if the digits that are going to
+ * be truncated because of the precision should
+ * force a round in the preceding digits.
+ * @param ca1 the array of digits
+ * @param icarry the index of the first digit that
+ * is to be truncated from the print
+ * @return <code>true</code> if the truncation forces
+ * a round that will change the print
+ */
+ private boolean checkForCarry(char[] ca1,int icarry) {
+ boolean carry=false;
+ if (icarry<ca1.length) {
+ if (ca1[icarry]=='6'||ca1[icarry]=='7'
+ ||ca1[icarry]=='8'||ca1[icarry]=='9') carry=true;
+ else if (ca1[icarry]=='5') {
+ int ii=icarry+1;
+ for (;ii<ca1.length; ii++)
+ if (ca1[ii]!='0') break;
+ carry=ii<ca1.length;
+ if (!carry&&icarry>0) {
+ carry=(ca1[icarry-1]=='1'||ca1[icarry-1]=='3'
+ ||ca1[icarry-1]=='5'||ca1[icarry-1]=='7'
+ ||ca1[icarry-1]=='9');
+ }
+ }
+ }
+ return carry;
+ }
+ /**
+ * Start the symbolic carry process. The process
+ * is not quite finished because the symbolic
+ * carry may change the length of the string and
+ * change the exponent (in e format).
+ * @param cLast index of the last digit changed
+ * by the round
+ * @param cFirst index of the first digit allowed
+ * to be changed by this phase of the round
+ * @return <code>true</code> if the carry forces
+ * a round that will change the print still
+ * more
+ */
+ private boolean startSymbolicCarry(
+ char[] ca,int cLast,int cFirst) {
+ boolean carry=true;
+ for (int i=cLast; carry && i>=cFirst; i--) {
+ carry = false;
+ switch(ca[i]) {
+ case '0': ca[i]='1'; break;
+ case '1': ca[i]='2'; break;
+ case '2': ca[i]='3'; break;
+ case '3': ca[i]='4'; break;
+ case '4': ca[i]='5'; break;
+ case '5': ca[i]='6'; break;
+ case '6': ca[i]='7'; break;
+ case '7': ca[i]='8'; break;
+ case '8': ca[i]='9'; break;
+ case '9': ca[i]='0'; carry=true; break;
+ }
+ }
+ return carry;
+ }
+ /**
+ * An intermediate routine on the way to creating
+ * an e format String. The method decides whether
+ * the input double value is an infinity,
+ * not-a-number, or a finite double and formats
+ * each type of input appropriately.
+ * @param x the double value to be formatted.
+ * @param eChar an 'e' or 'E' to use in the
+ * converted double value.
+ * @return the converted double value.
+ */
+ private String eFormatString(double x,char eChar) {
+ boolean noDigits=false;
+ char[] ca4,ca5;
+ if (Double.isInfinite(x)) {
+ if (x==Double.POSITIVE_INFINITY) {
+ if (leadingSign) ca4 = "+Inf".toCharArray();
+ else if (leadingSpace)
+ ca4 = " Inf".toCharArray();
+ else ca4 = "Inf".toCharArray();
+ }
+ else
+ ca4 = "-Inf".toCharArray();
+ noDigits = true;
+ }
+ else if (Double.isNaN(x)) {
+ if (leadingSign) ca4 = "+NaN".toCharArray();
+ else if (leadingSpace)
+ ca4 = " NaN".toCharArray();
+ else ca4 = "NaN".toCharArray();
+ noDigits = true;
+ }
+ else
+ ca4 = eFormatDigits(x,eChar);
+ ca5 = applyFloatPadding(ca4,false);
+ return new String(ca5);
+ }
+ /**
+ * Apply zero or blank, left or right padding.
+ * @param ca4 array of characters before padding is
+ * finished
+ * @param noDigits NaN or signed Inf
+ * @return a padded array of characters
+ */
+ private char[] applyFloatPadding(
+ char[] ca4,boolean noDigits) {
+ char[] ca5 = ca4;
+ if (fieldWidthSet) {
+ int i,j,nBlanks;
+ if (leftJustify) {
+ nBlanks = fieldWidth-ca4.length;
+ if (nBlanks > 0) {
+ ca5 = new char[ca4.length+nBlanks];
+ for (i=0; i<ca4.length; i++)
+ ca5[i] = ca4[i];
+ for (j=0; j<nBlanks; j++,i++)
+ ca5[i] = ' ';
+ }
+ }
+ else if (!leadingZeros || noDigits) {
+ nBlanks = fieldWidth-ca4.length;
+ if (nBlanks > 0) {
+ ca5 = new char[ca4.length+nBlanks];
+ for (i=0; i<nBlanks; i++)
+ ca5[i] = ' ';
+ for (j=0; j<ca4.length; i++,j++)
+ ca5[i] = ca4[j];
+ }
+ }
+ else if (leadingZeros) {
+ nBlanks = fieldWidth-ca4.length;
+ if (nBlanks > 0) {
+ ca5 = new char[ca4.length+nBlanks];
+ i=0; j=0;
+ if (ca4[0]=='-') { ca5[0]='-'; i++; j++; }
+ for (int k=0; k<nBlanks; i++,k++)
+ ca5[i] = '0';
+ for (; j<ca4.length; i++,j++)
+ ca5[i] = ca4[j];
+ }
+ }
+ }
+ return ca5;
+ }
+ /**
+ * Format method for the f conversion character.
+ * @param x the double to format.
+ * @return the formatted String.
+ */
+ private String printFFormat(double x) {
+ return fFormatString(x);
+ }
+ /**
+ * Format method for the e or E conversion
+ * character.
+ * @param x the double to format.
+ * @return the formatted String.
+ */
+ private String printEFormat(double x) {
+ if (conversionCharacter=='e')
+ return eFormatString(x,'e');
+ else
+ return eFormatString(x,'E');
+ }
+ /**
+ * Format method for the g conversion character.
+ *
+ * For g format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. '+' character means that the conversion
+ * will always begin with a sign (+ or -). The
+ * blank flag character means that a non-negative
+ * input will be preceded with a blank. If both a
+ * '+' and a ' ' are specified, the blank flag is
+ * ignored. The '0' flag character implies that
+ * padding to the field width will be done with
+ * zeros instead of blanks.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear after the radix character.
+ * Padding is with trailing 0s.
+ * @param x the double to format.
+ * @return the formatted String.
+ */
+ private String printGFormat(double x) {
+ String sx,sy,sz,ret;
+ int savePrecision=precision;
+ int i;
+ char[] ca4,ca5;
+ boolean noDigits=false;
+ if (Double.isInfinite(x)) {
+ if (x==Double.POSITIVE_INFINITY) {
+ if (leadingSign) ca4 = "+Inf".toCharArray();
+ else if (leadingSpace)
+ ca4 = " Inf".toCharArray();
+ else ca4 = "Inf".toCharArray();
+ }
+ else
+ ca4 = "-Inf".toCharArray();
+ noDigits = true;
+ }
+ else if (Double.isNaN(x)) {
+ if (leadingSign) ca4 = "+NaN".toCharArray();
+ else if (leadingSpace)
+ ca4 = " NaN".toCharArray();
+ else ca4 = "NaN".toCharArray();
+ noDigits = true;
+ }
+ else {
+ if (!precisionSet) precision=defaultDigits;
+ if (precision==0) precision=1;
+ int ePos=-1;
+ if (conversionCharacter=='g') {
+ sx = eFormatString(x,'e').trim();
+ ePos=sx.indexOf('e');
+ }
+ else {
+ sx = eFormatString(x,'E').trim();
+ ePos=sx.indexOf('E');
+ }
+ i=ePos+1;
+ int expon=0;
+ if (sx.charAt(i)=='-') {
+ for (++i; i<sx.length(); i++)
+ if (sx.charAt(i)!='0') break;
+ if (i<sx.length())
+ expon=-Integer.parseInt(sx.substring(i));
+ }
+ else {
+ if (sx.charAt(i)=='+') ++i;
+ for (; i<sx.length(); i++)
+ if (sx.charAt(i)!='0') break;
+ if (i<sx.length())
+ expon=Integer.parseInt(sx.substring(i));
+ }
+ // Trim trailing zeros.
+ // If the radix character is not followed by
+ // a digit, trim it, too.
+ if (!alternateForm) {
+ if (expon>=-4 && expon<precision)
+ sy = fFormatString(x).trim();
+ else
+ sy = sx.substring(0,ePos);
+ i=sy.length()-1;
+ for (; i>=0; i--)
+ if (sy.charAt(i)!='0') break;
+ if (i>=0 && sy.charAt(i)=='.') i--;
+ if (i==-1) sz="0";
+ else if (!Character.isDigit(sy.charAt(i)))
+ sz=sy.substring(0,i+1)+"0";
+ else sz=sy.substring(0,i+1);
+ if (expon>=-4 && expon<precision)
+ ret=sz;
+ else
+ ret=sz+sx.substring(ePos);
+ }
+ else {
+ if (expon>=-4 && expon<precision)
+ ret = fFormatString(x).trim();
+ else
+ ret = sx;
+ }
+ // leading space was trimmed off during
+ // construction
+ if (leadingSpace) if (x>=0) ret = " "+ret;
+ ca4 = ret.toCharArray();
+ }
+ // Pad with blanks or zeros.
+ ca5 = applyFloatPadding(ca4,false);
+ precision=savePrecision;
+ return new String(ca5);
+ }
+ /**
+ * Format method for the d conversion specifer and
+ * short argument.
+ *
+ * For d format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. A '+' character means that the conversion
+ * will always begin with a sign (+ or -). The
+ * blank flag character means that a non-negative
+ * input will be preceded with a blank. If both a
+ * '+' and a ' ' are specified, the blank flag is
+ * ignored. The '0' flag character implies that
+ * padding to the field width will be done with
+ * zeros instead of blanks.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the short to format.
+ * @return the formatted String.
+ */
+ private String printDFormat(short x) {
+ return printDFormat(Short.toString(x));
+ }
+ /**
+ * Format method for the d conversion character and
+ * long argument.
+ *
+ * For d format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. A '+' character means that the conversion
+ * will always begin with a sign (+ or -). The
+ * blank flag character means that a non-negative
+ * input will be preceded with a blank. If both a
+ * '+' and a ' ' are specified, the blank flag is
+ * ignored. The '0' flag character implies that
+ * padding to the field width will be done with
+ * zeros instead of blanks.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the long to format.
+ * @return the formatted String.
+ */
+ private String printDFormat(long x) {
+ return printDFormat(Long.toString(x));
+ }
+ /**
+ * Format method for the d conversion character and
+ * int argument.
+ *
+ * For d format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. A '+' character means that the conversion
+ * will always begin with a sign (+ or -). The
+ * blank flag character means that a non-negative
+ * input will be preceded with a blank. If both a
+ * '+' and a ' ' are specified, the blank flag is
+ * ignored. The '0' flag character implies that
+ * padding to the field width will be done with
+ * zeros instead of blanks.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the int to format.
+ * @return the formatted String.
+ */
+ private String printDFormat(int x) {
+ return printDFormat(Integer.toString(x));
+ }
+ /**
+ * Utility method for formatting using the d
+ * conversion character.
+ * @param sx the String to format, the result of
+ * converting a short, int, or long to a
+ * String.
+ * @return the formatted String.
+ */
+ private String printDFormat(String sx) {
+ int nLeadingZeros=0;
+ int nBlanks=0,n=0;
+ int i=0,jFirst=0;
+ boolean neg = sx.charAt(0)=='-';
+ if (sx.equals("0")&&precisionSet&&precision==0)
+ sx="";
+ if (!neg) {
+ if (precisionSet && sx.length() < precision)
+ nLeadingZeros = precision-sx.length();
+ }
+ else {
+ if (precisionSet&&(sx.length()-1)<precision)
+ nLeadingZeros = precision-sx.length()+1;
+ }
+ if (nLeadingZeros<0) nLeadingZeros=0;
+ if (fieldWidthSet) {
+ nBlanks = fieldWidth-nLeadingZeros-sx.length();
+ if (!neg&&(leadingSign||leadingSpace))
+ nBlanks--;
+ }
+ if (nBlanks<0) nBlanks=0;
+ if (leadingSign) n++;
+ else if (leadingSpace) n++;
+ n += nBlanks;
+ n += nLeadingZeros;
+ n += sx.length();
+ char[] ca = new char[n];
+ if (leftJustify) {
+ if (neg) ca[i++] = '-';
+ else if (leadingSign) ca[i++] = '+';
+ else if (leadingSpace) ca[i++] = ' ';
+ char[] csx = sx.toCharArray();
+ jFirst = neg?1:0;
+ for (int j=0; j<nLeadingZeros; i++,j++)
+ ca[i]='0';
+ for (int j=jFirst; j<csx.length; j++,i++)
+ ca[i] = csx[j];
+ for (int j=0; j<nBlanks; i++,j++)
+ ca[i] = ' ';
+ }
+ else {
+ if (!leadingZeros) {
+ for (i=0; i<nBlanks; i++)
+ ca[i] = ' ';
+ if (neg) ca[i++] = '-';
+ else if (leadingSign) ca[i++] = '+';
+ else if (leadingSpace) ca[i++] = ' ';
+ }
+ else {
+ if (neg) ca[i++] = '-';
+ else if (leadingSign) ca[i++] = '+';
+ else if (leadingSpace) ca[i++] = ' ';
+ for (int j=0; j<nBlanks; j++,i++)
+ ca[i] = '0';
+ }
+ for (int j=0; j<nLeadingZeros; j++,i++)
+ ca[i] = '0';
+ char[] csx = sx.toCharArray();
+ jFirst = neg?1:0;
+ for (int j=jFirst; j<csx.length; j++,i++)
+ ca[i] = csx[j];
+ }
+ return new String(ca);
+ }
+ /**
+ * Format method for the x conversion character and
+ * short argument.
+ *
+ * For x format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. The '#' flag character means to lead with
+ * '0x'.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the short to format.
+ * @return the formatted String.
+ */
+ private String printXFormat(short x) {
+ String sx=null;
+ if (x == Short.MIN_VALUE)
+ sx = "8000";
+ else if (x < 0) {
+ String t;
+ if (x==Short.MIN_VALUE)
+ t = "0";
+ else {
+ t = Integer.toString(
+ (~(-x-1))^Short.MIN_VALUE,16);
+ if (t.charAt(0)=='F'||t.charAt(0)=='f')
+ t = t.substring(16,32);
+ }
+ switch (t.length()) {
+ case 1:
+ sx = "800"+t;
+ break;
+ case 2:
+ sx = "80"+t;
+ break;
+ case 3:
+ sx = "8"+t;
+ break;
+ case 4:
+ switch (t.charAt(0)) {
+ case '1':
+ sx = "9"+t.substring(1,4);
+ break;
+ case '2':
+ sx = "a"+t.substring(1,4);
+ break;
+ case '3':
+ sx = "b"+t.substring(1,4);
+ break;
+ case '4':
+ sx = "c"+t.substring(1,4);
+ break;
+ case '5':
+ sx = "d"+t.substring(1,4);
+ break;
+ case '6':
+ sx = "e"+t.substring(1,4);
+ break;
+ case '7':
+ sx = "f"+t.substring(1,4);
+ break;
+ }
+ break;
+ }
+ }
+ else
+ sx = Integer.toString((int)x,16);
+ return printXFormat(sx);
+ }
+ /**
+ * Format method for the x conversion character and
+ * long argument.
+ *
+ * For x format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. The '#' flag character means to lead with
+ * '0x'.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the long to format.
+ * @return the formatted String.
+ */
+ private String printXFormat(long x) {
+ String sx=null;
+ if (x == Long.MIN_VALUE)
+ sx = "8000000000000000";
+ else if (x < 0) {
+ String t = Long.toString(
+ (~(-x-1))^Long.MIN_VALUE,16);
+ switch (t.length()) {
+ case 1:
+ sx = "800000000000000"+t;
+ break;
+ case 2:
+ sx = "80000000000000"+t;
+ break;
+ case 3:
+ sx = "8000000000000"+t;
+ break;
+ case 4:
+ sx = "800000000000"+t;
+ break;
+ case 5:
+ sx = "80000000000"+t;
+ break;
+ case 6:
+ sx = "8000000000"+t;
+ break;
+ case 7:
+ sx = "800000000"+t;
+ break;
+ case 8:
+ sx = "80000000"+t;
+ break;
+ case 9:
+ sx = "8000000"+t;
+ break;
+ case 10:
+ sx = "800000"+t;
+ break;
+ case 11:
+ sx = "80000"+t;
+ break;
+ case 12:
+ sx = "8000"+t;
+ break;
+ case 13:
+ sx = "800"+t;
+ break;
+ case 14:
+ sx = "80"+t;
+ break;
+ case 15:
+ sx = "8"+t;
+ break;
+ case 16:
+ switch (t.charAt(0)) {
+ case '1':
+ sx = "9"+t.substring(1,16);
+ break;
+ case '2':
+ sx = "a"+t.substring(1,16);
+ break;
+ case '3':
+ sx = "b"+t.substring(1,16);
+ break;
+ case '4':
+ sx = "c"+t.substring(1,16);
+ break;
+ case '5':
+ sx = "d"+t.substring(1,16);
+ break;
+ case '6':
+ sx = "e"+t.substring(1,16);
+ break;
+ case '7':
+ sx = "f"+t.substring(1,16);
+ break;
+ }
+ break;
+ }
+ }
+ else
+ sx = Long.toString(x,16);
+ return printXFormat(sx);
+ }
+ /**
+ * Format method for the x conversion character and
+ * int argument.
+ *
+ * For x format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. The '#' flag character means to lead with
+ * '0x'.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the int to format.
+ * @return the formatted String.
+ */
+ private String printXFormat(int x) {
+ String sx=null;
+ if (x == Integer.MIN_VALUE)
+ sx = "80000000";
+ else if (x < 0) {
+ String t = Integer.toString(
+ (~(-x-1))^Integer.MIN_VALUE,16);
+ switch (t.length()) {
+ case 1:
+ sx = "8000000"+t;
+ break;
+ case 2:
+ sx = "800000"+t;
+ break;
+ case 3:
+ sx = "80000"+t;
+ break;
+ case 4:
+ sx = "8000"+t;
+ break;
+ case 5:
+ sx = "800"+t;
+ break;
+ case 6:
+ sx = "80"+t;
+ break;
+ case 7:
+ sx = "8"+t;
+ break;
+ case 8:
+ switch (t.charAt(0)) {
+ case '1':
+ sx = "9"+t.substring(1,8);
+ break;
+ case '2':
+ sx = "a"+t.substring(1,8);
+ break;
+ case '3':
+ sx = "b"+t.substring(1,8);
+ break;
+ case '4':
+ sx = "c"+t.substring(1,8);
+ break;
+ case '5':
+ sx = "d"+t.substring(1,8);
+ break;
+ case '6':
+ sx = "e"+t.substring(1,8);
+ break;
+ case '7':
+ sx = "f"+t.substring(1,8);
+ break;
+ }
+ break;
+ }
+ }
+ else
+ sx = Integer.toString(x,16);
+ return printXFormat(sx);
+ }
+ /**
+ * Utility method for formatting using the x
+ * conversion character.
+ * @param sx the String to format, the result of
+ * converting a short, int, or long to a
+ * String.
+ * @return the formatted String.
+ */
+ private String printXFormat(String sx) {
+ int nLeadingZeros = 0;
+ int nBlanks = 0;
+ if (sx.equals("0")&&precisionSet&&precision==0)
+ sx="";
+ if (precisionSet)
+ nLeadingZeros = precision-sx.length();
+ if (nLeadingZeros<0) nLeadingZeros=0;
+ if (fieldWidthSet) {
+ nBlanks = fieldWidth-nLeadingZeros-sx.length();
+ if (alternateForm) nBlanks = nBlanks - 2;
+ }
+ if (nBlanks<0) nBlanks=0;
+ int n=0;
+ if (alternateForm) n+=2;
+ n += nLeadingZeros;
+ n += sx.length();
+ n += nBlanks;
+ char[] ca = new char[n];
+ int i=0;
+ if (leftJustify) {
+ if (alternateForm) {
+ ca[i++]='0'; ca[i++]='x';
+ }
+ for (int j=0; j<nLeadingZeros; j++,i++)
+ ca[i]='0';
+ char[] csx = sx.toCharArray();
+ for (int j=0; j<csx.length; j++,i++)
+ ca[i] = csx[j];
+ for (int j=0; j<nBlanks; j++,i++)
+ ca[i] = ' ';
+ }
+ else {
+ if (!leadingZeros)
+ for (int j=0; j<nBlanks; j++,i++)
+ ca[i] = ' ';
+ if (alternateForm) {
+ ca[i++]='0'; ca[i++]='x';
+ }
+ if (leadingZeros)
+ for (int j=0; j<nBlanks; j++,i++)
+ ca[i] = '0';
+ for (int j=0; j<nLeadingZeros; j++,i++)
+ ca[i]='0';
+ char[] csx = sx.toCharArray();
+ for (int j=0; j<csx.length; j++,i++)
+ ca[i] = csx[j];
+ }
+ String caReturn=new String(ca);
+ if (conversionCharacter=='X')
+ caReturn = caReturn.toUpperCase();
+ return caReturn;
+ }
+ /**
+ * Format method for the o conversion character and
+ * short argument.
+ *
+ * For o format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. The '#' flag character means that the
+ * output begins with a leading 0 and the precision
+ * is increased by 1.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the short to format.
+ * @return the formatted String.
+ */
+ private String printOFormat(short x) {
+ String sx=null;
+ if (x == Short.MIN_VALUE)
+ sx = "100000";
+ else if (x < 0) {
+ String t = Integer.toString(
+ (~(-x-1))^Short.MIN_VALUE,8);
+ switch (t.length()) {
+ case 1:
+ sx = "10000"+t;
+ break;
+ case 2:
+ sx = "1000"+t;
+ break;
+ case 3:
+ sx = "100"+t;
+ break;
+ case 4:
+ sx = "10"+t;
+ break;
+ case 5:
+ sx = "1"+t;
+ break;
+ }
+ }
+ else
+ sx = Integer.toString((int)x,8);
+ return printOFormat(sx);
+ }
+ /**
+ * Format method for the o conversion character and
+ * long argument.
+ *
+ * For o format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. The '#' flag character means that the
+ * output begins with a leading 0 and the precision
+ * is increased by 1.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the long to format.
+ * @return the formatted String.
+ */
+ private String printOFormat(long x) {
+ String sx=null;
+ if (x == Long.MIN_VALUE)
+ sx = "1000000000000000000000";
+ else if (x < 0) {
+ String t = Long.toString(
+ (~(-x-1))^Long.MIN_VALUE,8);
+ switch (t.length()) {
+ case 1:
+ sx = "100000000000000000000"+t;
+ break;
+ case 2:
+ sx = "10000000000000000000"+t;
+ break;
+ case 3:
+ sx = "1000000000000000000"+t;
+ break;
+ case 4:
+ sx = "100000000000000000"+t;
+ break;
+ case 5:
+ sx = "10000000000000000"+t;
+ break;
+ case 6:
+ sx = "1000000000000000"+t;
+ break;
+ case 7:
+ sx = "100000000000000"+t;
+ break;
+ case 8:
+ sx = "10000000000000"+t;
+ break;
+ case 9:
+ sx = "1000000000000"+t;
+ break;
+ case 10:
+ sx = "100000000000"+t;
+ break;
+ case 11:
+ sx = "10000000000"+t;
+ break;
+ case 12:
+ sx = "1000000000"+t;
+ break;
+ case 13:
+ sx = "100000000"+t;
+ break;
+ case 14:
+ sx = "10000000"+t;
+ break;
+ case 15:
+ sx = "1000000"+t;
+ break;
+ case 16:
+ sx = "100000"+t;
+ break;
+ case 17:
+ sx = "10000"+t;
+ break;
+ case 18:
+ sx = "1000"+t;
+ break;
+ case 19:
+ sx = "100"+t;
+ break;
+ case 20:
+ sx = "10"+t;
+ break;
+ case 21:
+ sx = "1"+t;
+ break;
+ }
+ }
+ else
+ sx = Long.toString(x,8);
+ return printOFormat(sx);
+ }
+ /**
+ * Format method for the o conversion character and
+ * int argument.
+ *
+ * For o format, the flag character '-', means that
+ * the output should be left justified within the
+ * field. The default is to pad with blanks on the
+ * left. The '#' flag character means that the
+ * output begins with a leading 0 and the precision
+ * is increased by 1.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is to
+ * add no padding. Padding is with blanks by
+ * default.
+ *
+ * The precision, if set, is the minimum number of
+ * digits to appear. Padding is with leading 0s.
+ * @param x the int to format.
+ * @return the formatted String.
+ */
+ private String printOFormat(int x) {
+ String sx=null;
+ if (x == Integer.MIN_VALUE)
+ sx = "20000000000";
+ else if (x < 0) {
+ String t = Integer.toString(
+ (~(-x-1))^Integer.MIN_VALUE,8);
+ switch (t.length()) {
+ case 1:
+ sx = "2000000000"+t;
+ break;
+ case 2:
+ sx = "200000000"+t;
+ break;
+ case 3:
+ sx = "20000000"+t;
+ break;
+ case 4:
+ sx = "2000000"+t;
+ break;
+ case 5:
+ sx = "200000"+t;
+ break;
+ case 6:
+ sx = "20000"+t;
+ break;
+ case 7:
+ sx = "2000"+t;
+ break;
+ case 8:
+ sx = "200"+t;
+ break;
+ case 9:
+ sx = "20"+t;
+ break;
+ case 10:
+ sx = "2"+t;
+ break;
+ case 11:
+ sx = "3"+t.substring(1);
+ break;
+ }
+ }
+ else
+ sx = Integer.toString(x,8);
+ return printOFormat(sx);
+ }
+ /**
+ * Utility method for formatting using the o
+ * conversion character.
+ * @param sx the String to format, the result of
+ * converting a short, int, or long to a
+ * String.
+ * @return the formatted String.
+ */
+ private String printOFormat(String sx) {
+ int nLeadingZeros = 0;
+ int nBlanks = 0;
+ if (sx.equals("0")&&precisionSet&&precision==0)
+ sx="";
+ if (precisionSet)
+ nLeadingZeros = precision-sx.length();
+ if (alternateForm) nLeadingZeros++;
+ if (nLeadingZeros<0) nLeadingZeros=0;
+ if (fieldWidthSet)
+ nBlanks = fieldWidth-nLeadingZeros-sx.length();
+ if (nBlanks<0) nBlanks=0;
+ int n=nLeadingZeros+sx.length()+nBlanks;
+ char[] ca = new char[n];
+ int i;
+ if (leftJustify) {
+ for (i=0; i<nLeadingZeros; i++) ca[i]='0';
+ char[] csx = sx.toCharArray();
+ for (int j=0; j<csx.length; j++,i++)
+ ca[i] = csx[j];
+ for (int j=0; j<nBlanks; j++,i++) ca[i] = ' ';
+ }
+ else {
+ if (leadingZeros)
+ for (i=0; i<nBlanks; i++) ca[i]='0';
+ else
+ for (i=0; i<nBlanks; i++) ca[i]=' ';
+ for (int j=0; j<nLeadingZeros; j++,i++)
+ ca[i]='0';
+ char[] csx = sx.toCharArray();
+ for (int j=0; j<csx.length; j++,i++)
+ ca[i] = csx[j];
+ }
+ return new String(ca);
+ }
+ /**
+ * Format method for the c conversion character and
+ * char argument.
+ *
+ * The only flag character that affects c format is
+ * the '-', meaning that the output should be left
+ * justified within the field. The default is to
+ * pad with blanks on the left.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. Padding is with
+ * blanks by default. The default width is 1.
+ *
+ * The precision, if set, is ignored.
+ * @param x the char to format.
+ * @return the formatted String.
+ */
+ private String printCFormat(char x) {
+ int nPrint = 1;
+ int width = fieldWidth;
+ if (!fieldWidthSet) width = nPrint;
+ char[] ca = new char[width];
+ int i=0;
+ if (leftJustify) {
+ ca[0] = x;
+ for (i=1; i<=width-nPrint; i++) ca[i]=' ';
+ }
+ else {
+ for (i=0; i<width-nPrint; i++) ca[i]=' ';
+ ca[i] = x;
+ }
+ return new String(ca);
+ }
+ /**
+ * Format method for the s conversion character and
+ * String argument.
+ *
+ * The only flag character that affects s format is
+ * the '-', meaning that the output should be left
+ * justified within the field. The default is to
+ * pad with blanks on the left.
+ *
+ * The field width is treated as the minimum number
+ * of characters to be printed. The default is the
+ * smaller of the number of characters in the the
+ * input and the precision. Padding is with blanks
+ * by default.
+ *
+ * The precision, if set, specifies the maximum
+ * number of characters to be printed from the
+ * string. A null digit string is treated
+ * as a 0. The default is not to set a maximum
+ * number of characters to be printed.
+ * @param x the String to format.
+ * @return the formatted String.
+ */
+ private String printSFormat(String x) {
+ int nPrint = x.length();
+ int width = fieldWidth;
+ if (precisionSet && nPrint>precision)
+ nPrint=precision;
+ if (!fieldWidthSet) width = nPrint;
+ int n=0;
+ if (width>nPrint) n+=width-nPrint;
+ if (nPrint>=x.length()) n+= x.length();
+ else n+= nPrint;
+ char[] ca = new char[n];
+ int i=0;
+ if (leftJustify) {
+ if (nPrint>=x.length()) {
+ char[] csx = x.toCharArray();
+ for (i=0; i<x.length(); i++) ca[i]=csx[i];
+ }
+ else {
+ char[] csx =
+ x.substring(0,nPrint).toCharArray();
+ for (i=0; i<nPrint; i++) ca[i]=csx[i];
+ }
+ for (int j=0; j<width-nPrint; j++,i++)
+ ca[i]=' ';
+ }
+ else {
+ for (i=0; i<width-nPrint; i++) ca[i]=' ';
+ if (nPrint>=x.length()) {
+ char[] csx = x.toCharArray();
+ for (int j=0; j<x.length(); i++,j++)
+ ca[i]=csx[j];
+ }
+ else {
+ char[] csx =
+ x.substring(0,nPrint).toCharArray();
+ for (int j=0; j<nPrint; i++,j++)
+ ca[i]=csx[j];
+ }
+ }
+ return new String(ca);
+ }
+ /**
+ * Check for a conversion character. If it is
+ * there, store it.
+ * * @return <code>true</code> if the conversion
+ * character is there, and
+ * <code>false</code> otherwise.
+ */
+ private boolean setConversionCharacter() {
+ /* idfgGoxXeEcs */
+ boolean ret = false;
+ conversionCharacter='\0';
+ if (pos < fmt.length()) {
+ char c = fmt.charAt(pos);
+ 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=='%') {
+ conversionCharacter = c;
+ pos++;
+ ret = true;
+ }
+ }
+ return ret;
+ }
+ /**
+ * Check for an h, l, or L in a format. An L is
+ * used to control the minimum number of digits
+ * in an exponent when using floating point
+ * formats. An l or h is used to control
+ * conversion of the input to a long or short,
+ * respectively, before formatting. If any of
+ * these is present, store them.
+ */
+ private void setOptionalHL() {
+ optionalh=false;
+ optionall=false;
+ optionalL=false;
+ if (pos < fmt.length()) {
+ char c = fmt.charAt(pos);
+ if (c=='h') { optionalh=true; pos++; }
+ else if (c=='l') { optionall=true; pos++; }
+ else if (c=='L') { optionalL=true; pos++; }
+ }
+ }
+ /**
+ * Set the precision.
+ */
+ private void setPrecision() {
+ int firstPos = pos;
+ precisionSet = false;
+ if (pos<fmt.length()&&fmt.charAt(pos)=='.') {
+ pos++;
+ if ((pos < fmt.length())
+ && (fmt.charAt(pos)=='*')) {
+ pos++;
+ if (!setPrecisionArgPosition()) {
+ variablePrecision = true;
+ precisionSet = true;
+ }
+ return;
+ }
+ else {
+ while (pos < fmt.length()) {
+ char c = fmt.charAt(pos);
+ if (Character.isDigit(c)) pos++;
+ else break;
+ }
+ if (pos > firstPos+1) {
+ String sz = fmt.substring(firstPos+1,pos);
+ precision = Integer.parseInt(sz);
+ precisionSet = true;
+ }
+ }
+ }
+ }
+ /**
+ * Set the field width.
+ */
+ private void setFieldWidth() {
+ int firstPos = pos;
+ fieldWidth = 0;
+ fieldWidthSet = false;
+ if ((pos < fmt.length())
+ && (fmt.charAt(pos)=='*')) {
+ pos++;
+ if (!setFieldWidthArgPosition()) {
+ variableFieldWidth = true;
+ fieldWidthSet = true;
+ }
+ }
+ else {
+ while (pos < fmt.length()) {
+ char c = fmt.charAt(pos);
+ if (Character.isDigit(c)) pos++;
+ else break;
+ }
+ if (firstPos<pos && firstPos < fmt.length()) {
+ String sz = fmt.substring(firstPos,pos);
+ fieldWidth = Integer.parseInt(sz);
+ fieldWidthSet = true;
+ }
+ }
+ }
+ /**
+ * Store the digits <code>n</code> in %n$ forms.
+ */
+ private void setArgPosition() {
+ int xPos;
+ for (xPos=pos; xPos<fmt.length(); xPos++) {
+ if (!Character.isDigit(fmt.charAt(xPos)))
+ break;
+ }
+ if (xPos>pos && xPos<fmt.length()) {
+ if (fmt.charAt(xPos)=='$') {
+ positionalSpecification = true;
+ argumentPosition=
+ Integer.parseInt(fmt.substring(pos,xPos));
+ pos=xPos+1;
+ }
+ }
+ }
+ /**
+ * Store the digits <code>n</code> in *n$ forms.
+ */
+ private boolean setFieldWidthArgPosition() {
+ boolean ret=false;
+ int xPos;
+ for (xPos=pos; xPos<fmt.length(); xPos++) {
+ if (!Character.isDigit(fmt.charAt(xPos)))
+ break;
+ }
+ if (xPos>pos && xPos<fmt.length()) {
+ if (fmt.charAt(xPos)=='$') {
+ positionalFieldWidth = true;
+ argumentPositionForFieldWidth=
+ Integer.parseInt(fmt.substring(pos,xPos));
+ pos=xPos+1;
+ ret=true;
+ }
+ }
+ return ret;
+ }
+ /**
+ * Store the digits <code>n</code> in *n$ forms.
+ */
+ private boolean setPrecisionArgPosition() {
+ boolean ret=false;
+ int xPos;
+ for (xPos=pos; xPos<fmt.length(); xPos++) {
+ if (!Character.isDigit(fmt.charAt(xPos)))
+ break;
+ }
+ if (xPos>pos && xPos<fmt.length()) {
+ if (fmt.charAt(xPos)=='$') {
+ positionalPrecision = true;
+ argumentPositionForPrecision=
+ Integer.parseInt(fmt.substring(pos,xPos));
+ pos=xPos+1;
+ ret=true;
+ }
+ }
+ return ret;
+ }
+ boolean isPositionalSpecification() {
+ return positionalSpecification;
+ }
+ int getArgumentPosition() { return argumentPosition; }
+ boolean isPositionalFieldWidth() {
+ return positionalFieldWidth;
+ }
+ int getArgumentPositionForFieldWidth() {
+ return argumentPositionForFieldWidth;
+ }
+ boolean isPositionalPrecision() {
+ return positionalPrecision;
+ }
+ int getArgumentPositionForPrecision() {
+ return argumentPositionForPrecision;
+ }
+ /**
+ * Set flag characters, one of '-+#0 or a space.
+ */
+ private void setFlagCharacters() {
+ /* '-+ #0 */
+ thousands = false;
+ leftJustify = false;
+ leadingSign = false;
+ leadingSpace = false;
+ alternateForm = false;
+ leadingZeros = false;
+ for ( ; pos < fmt.length(); pos++) {
+ char c = fmt.charAt(pos);
+ if (c == '\'') thousands = true;
+ else if (c == '-') {
+ leftJustify = true;
+ leadingZeros = false;
+ }
+ else if (c == '+') {
+ leadingSign = true;
+ leadingSpace = false;
+ }
+ else if (c == ' ') {
+ if (!leadingSign) leadingSpace = true;
+ }
+ else if (c == '#') alternateForm = true;
+ else if (c == '0') {
+ if (!leftJustify) leadingZeros = true;
+ }
+ else break;
+ }
+ }
+ /**
+ * The integer portion of the result of a decimal
+ * conversion (i, d, u, f, g, or G) will be
+ * formatted with thousands' grouping characters.
+ * For other conversions the flag is ignored.
+ */
+ private boolean thousands = false;
+ /**
+ * The result of the conversion will be
+ * left-justified within the field.
+ */
+ private boolean leftJustify = false;
+ /**
+ * The result of a signed conversion will always
+ * begin with a sign (+ or -).
+ */
+ private boolean leadingSign = false;
+ /**
+ * Flag indicating that left padding with spaces is
+ * specified.
+ */
+ private boolean leadingSpace = false;
+ /**
+ * For an o conversion, increase the precision to
+ * force the first digit of the result to be a
+ * zero. For x (or X) conversions, a non-zero
+ * result will have 0x (or 0X) prepended to it.
+ * For e, E, f, g, or G conversions, the result
+ * will always contain a radix character, even if
+ * no digits follow the point. For g and G
+ * conversions, trailing zeros will not be removed
+ * from the result.
+ */
+ private boolean alternateForm = false;
+ /**
+ * Flag indicating that left padding with zeroes is
+ * specified.
+ */
+ private boolean leadingZeros = false;
+ /**
+ * Flag indicating that the field width is *.
+ */
+ private boolean variableFieldWidth = false;
+ /**
+ * If the converted value has fewer bytes than the
+ * field width, it will be padded with spaces or
+ * zeroes.
+ */
+ private int fieldWidth = 0;
+ /**
+ * Flag indicating whether or not the field width
+ * has been set.
+ */
+ private boolean fieldWidthSet = false;
+ /**
+ * The minimum number of digits to appear for the
+ * d, i, o, u, x, or X conversions. The number of
+ * digits to appear after the radix character for
+ * the e, E, and f conversions. The maximum number
+ * of significant digits for the g and G
+ * conversions. The maximum number of bytes to be
+ * printed from a string in s and S conversions.
+ */
+ private int precision = 0;
+ /** Default precision. */
+ private final static int defaultDigits=6;
+ /**
+ * Flag indicating that the precision is *.
+ */
+ private boolean variablePrecision = false;
+ /**
+ * Flag indicating whether or not the precision has
+ * been set.
+ */
+ private boolean precisionSet = false;
+ /*
+ */
+ private boolean positionalSpecification=false;
+ private int argumentPosition=0;
+ private boolean positionalFieldWidth=false;
+ private int argumentPositionForFieldWidth=0;
+ private boolean positionalPrecision=false;
+ private int argumentPositionForPrecision=0;
+ /**
+ * Flag specifying that a following d, i, o, u, x,
+ * or X conversion character applies to a type
+ * short int.
+ */
+ private boolean optionalh = false;
+ /**
+ * Flag specifying that a following d, i, o, u, x,
+ * or X conversion character applies to a type lont
+ * int argument.
+ */
+ private boolean optionall = false;
+ /**
+ * Flag specifying that a following e, E, f, g, or
+ * G conversion character applies to a type double
+ * argument. This is a noop in Java.
+ */
+ private boolean optionalL = false;
+ /** Control string type. */
+ private char conversionCharacter = '\0';
+ /**
+ * Position within the control string. Used by
+ * the constructor.
+ */
+ private int pos = 0;
+ /** Literal or control format string. */
+ private String fmt;
+ }
+ /** Vector of control strings and format literals. */
+ private Vector vFmt = new Vector();
+ /** Character position. Used by the constructor. */
+ private int cPos=0;
+ /** Character position. Used by the constructor. */
+ private DecimalFormatSymbols dfs=null;
+}