KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dbforms > util > external > PrintfFormat


1 /*
2  * $Header: /cvsroot/jdbforms/dbforms/src/org/dbforms/util/external/PrintfFormat.java,v 1.11 2004/08/18 12:26:09 hkollmann Exp $
3  * $Revision: 1.11 $
4  * $Date: 2004/08/18 12:26:09 $
5  *
6  * DbForms - a Rapid Application Development Framework
7  * Copyright (C) 2001 Joachim Peer <joepeer@excite.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */

23
24 /*
25   This class was part of an article written by Allan Jacobs October 2000 about
26   formatted printing within Java. It was published at:
27
28       http://developer.java.sun.com/developer/technicalArticles/Programming/sprintf/
29
30   The Java source itself was downloadable at:
31
32       http://developer.java.sun.com/developer/technicalArticles/Programming/sprintf/PrintfFormat.java
33
34   License conditions say (see below):
35
36    'Permission to use, copy, modify, and distribute this Software and its
37     documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is
38     hereby granted.'
39
40   Changes for integration into dbforms:
41
42   packet changed to org.dbforms.util;
43
44   2002-12-18 (dikr) NP check within internalsprintf(Object s) added
45
46 */

47 package org.dbforms.util.external;
48
49 import java.text.DateFormat JavaDoc;
50 import java.text.DecimalFormatSymbols JavaDoc;
51
52 import java.util.Date JavaDoc;
53
54 // below follows orininal source:
55
// ---------------------------------------------------------------------------------------------------
56
//
57
// (c) 2000 Sun Microsystems, Inc.
58
// ALL RIGHTS RESERVED
59
//
60
// License Grant-
61
//
62
//
63
// Permission to use, copy, modify, and distribute this Software and its
64
// documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is
65
// hereby granted.
66
//
67
// This Software is provided "AS IS". All express warranties, including any
68
// implied warranty of merchantability, satisfactory quality, fitness for a
69
// particular purpose, or non-infringement, are disclaimed, except to the extent
70
// that such disclaimers are held to be legally invalid.
71
//
72
// You acknowledge that Software is not designed, licensed or intended for use in
73
// the design, construction, operation or maintenance of any nuclear facility
74
// ("High Risk Activities"). Sun disclaims any express or implied warranty of
75
// fitness for such uses.
76
//
77
// Please refer to the file http://www.sun.com/policies/trademarks/ for further
78
// important trademark information and to
79
// http://java.sun.com/nav/business/index.html for further important licensing
80
// information for the Java Technology.
81
//
82
import java.util.Enumeration JavaDoc;
83 import java.util.Locale JavaDoc;
84 import java.util.Vector JavaDoc;
85
86
87
88 /**
89  * PrintfFormat allows the formatting of an array of objects embedded within a
90  * string. Primitive types must be passed using wrapper types. The
91  * formatting is controlled by a control string.
92  * @author Allan Jacobs
93  * @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...
94  *
95  * <p>
96  * A control string is a Java string that contains a control specification.
97  * The control specification starts at the first percent sign (%) in the
98  * string, provided that this percent sign
99  *
100  * <ol>
101  * <li>
102  * is not escaped protected by a matching % or is not an escape % character,
103  * </li>
104  * <li>
105  * is not at the end of the format string, and
106  * </li>
107  * <li>
108  * precedes a sequence of characters that parses as a valid control
109  * specification.
110  * </li>
111  * </ol>
112  * </p>
113  *
114  * <p>
115  * A control specification usually takes the form:
116  * <pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
117  * { [hlL] }+ [idfgGoxXeEcs]
118  * </pre>
119  * There are variants of this basic form that are discussed below.
120  * </p>
121  *
122  * <p>
123  * The format is composed of zero or more directives defined as follows:
124  *
125  * <ul>
126  * <li>
127  * ordinary characters, which are simply copied to the output stream;
128  * </li>
129  * <li>
130  * escape sequences, which represent non-graphic characters; and
131  * </li>
132  * <li>
133  * conversion specifications, each of which results in the fetching of zero or
134  * more arguments.
135  * </li>
136  * </ul>
137  * </p>
138  *
139  * <p>
140  * The results are undefined if there are insufficient arguments for the
141  * format. Usually an unchecked exception will be thrown. If the format is
142  * exhausted while arguments remain, the excess arguments are evaluated but
143  * are otherwise ignored. In format strings containing the % form of
144  * conversion specifications, each argument in the argument list is used
145  * exactly once.
146  * </p>
147  *
148  * <p>
149  * Conversions can be applied to the <code>n</code>th argument after the format
150  * in the argument list, rather than to the next unused argument. In this
151  * case, the conversion characer % is replaced by the sequence
152  * %<code>n</code>$, where <code>n</code> is a decimal integer giving the
153  * position of the argument in the argument list.
154  * </p>
155  *
156  * <p>
157  * In format strings containing the %<code>n</code>$ form of conversion
158  * specifications, each argument in the argument list is used exactly once.
159  * </p>
160  * <h4>
161  *
162  * <p>
163  * The following table lists escape sequences and associated actions on display
164  * devices capable of the action.
165  * </p>
166  * <h4>
167  *
168  * <p>
169  * Each conversion specification is introduced by the percent sign character
170  * (%). After the character %, the following appear in sequence:
171  * </p>
172  *
173  * <p>
174  * Zero or more flags (in any order), which modify the meaning of the
175  * conversion specification.
176  * </p>
177  *
178  * <p>
179  * An optional minimum field width. If the converted value has fewer
180  * characters than the field width, it will be padded with spaces by default
181  * on the left; t will be padded on the right, if the left- adjustment flag
182  * (-), described below, is given to the field width. The field width takes
183  * the form of a decimal integer. If the conversion character is s, the field
184  * width is the the minimum number of characters to be printed.
185  * </p>
186  *
187  * <p>
188  * An optional precision that gives the minumum number of digits to appear for
189  * the d, i, o, x or X conversions (the field is padded with leading zeros);
190  * the number of digits to appear after the radix character for the e, E, and
191  * f conversions, the maximum number of significant digits for the g and G
192  * conversions; or the maximum number of characters to be written from a
193  * string is s and S conversions. The precision takes the form of an optional
194  * decimal digit string, where a null digit string is treated as 0. If a
195  * precision appears with a c conversion character the precision is ignored.
196  * </p>
197  *
198  * <p>
199  * An optional h specifies that a following d, i, o, x, or X conversion
200  * character applies to a type short argument (the argument will be promoted
201  * according to the integral promotions and its value converted to type short
202  * before printing).
203  * </p>
204  *
205  * <p>
206  * An optional l (ell) specifies that a following d, i, o, x, or X conversion
207  * character applies to a type long argument.
208  * </p>
209  *
210  * <p>
211  * A field width or precision may be indicated by an asterisk () instead of a
212  * digit string. In this case, an integer argument supplised the field width
213  * precision. The argument that is actually converted is not fetched until
214  * the conversion letter is seen, so the the arguments specifying field width
215  * or precision must appear before the argument (if any) to be converted. If
216  * the precision argument is negative, it will be changed to zero. A negative
217  * field width argument is taken as a - flag, followed by a positive field
218  * width.
219  * </p>
220  *
221  * <p>
222  * In format strings containing the %<code>n</code>$ form of a conversion
223  * specification, a field width or precision may be indicated by the sequence
224  * <code>m</code>$, where m is a decimal integer giving the position in the
225  * argument list (after the format argument) of an integer argument containing
226  * the field width or precision.
227  * </p>
228  *
229  * <p>
230  * The format can contain either numbered argument specifications (that is,
231  * %<code>n</code>$ and <code>m</code>$), or unnumbered argument
232  * specifications (that is % and ), but normally not both. The only exception
233  * to this is that %% can be mixed with the %<code>n</code>$ form. The
234  * results of mixing numbered and unnumbered argument specifications in a
235  * format string are undefined.
236  * </p>
237  * <h4>
238  *
239  * <p>
240  * The flags and their meanings are:
241  * </p>
242  *
243  * <dl>
244  * <dt>
245  * '
246  * </dt>
247  * <dd>
248  * integer portion of the result of a decimal conversion (%i, %d, %f, %g, or
249  * %G) will be formatted with thousands' grouping characters. For other
250  * conversions the flag is ignored. The non-monetary grouping character is
251  * used.
252  * </dd>
253  * <dt>
254  * -
255  * </dt>
256  * <dd>
257  * result of the conversion is left-justified within the field. (It will be
258  * right-justified if this flag is not specified).
259  * </dd>
260  * <dt>
261  * +
262  * </dt>
263  * <dd>
264  * result of a signed conversion always begins with a sign (+ or -). (It will
265  * begin with a sign only when a negative value is converted if this flag is
266  * not specified.)
267  * </dd>
268  * <dt>
269  * &lt;space&gt;
270  * </dt>
271  * <dd>
272  * If the first character of a signed conversion is not a sign, a space
273  * character will be placed before the result. This means that if the space
274  * character and + flags both appear, the space flag will be ignored.
275  * </dd>
276  * <dt>
277  * #
278  * </dt>
279  * <dd>
280  * value is to be converted to an alternative form. For c, d, i, and s
281  * conversions, the flag has no effect. For o conversion, it increases the
282  * precision to force the first digit of the result to be a zero. For x or X
283  * conversion, a non-zero result has 0x or 0X prefixed to it, respectively.
284  * For e, E, f, g, and G conversions, the result always contains a radix
285  * character, even if no digits follow the radix character (normally, a
286  * decimal point appears in the result of these conversions only if a digit
287  * follows it). For g and G conversions, trailing zeros will not be removed
288  * from the result as they normally are.
289  * </dd>
290  * <dt>
291  * 0
292  * </dt>
293  * <dd>
294  * d, i, o, x, X, e, E, f, g, and G conversions, leading zeros (following any
295  * indication of sign or base) are used to pad to the field width; no space
296  * padding is performed. If the 0 and - flags both appear, the 0 flag is
297  * ignored. For d, i, o, x, and X conversions, if a precision is specified,
298  * the 0 flag will be ignored. For c conversions, the flag is ignored.
299  * </dd>
300  * </dl>
301  *
302  * <p>
303  * Each conversion character results in fetching zero or more arguments. The
304  * results are undefined if there are insufficient arguments for the format.
305  * Usually, an unchecked exception will be thrown. If the format is exhausted
306  * while arguments remain, the excess arguments are ignored.
307  * </p>
308  *
309  * <p>
310  * The conversion characters and their meanings are:
311  * </p>
312  *
313  * <dl>
314  * <dt>
315  * d,i
316  * </dt>
317  * <dd>
318  * The int argument is converted to a signed decimal in the style [-]dddd. The
319  * precision specifies the minimum number of digits to appear; if the value
320  * being converted can be represented in fewer digits, it will be expanded
321  * with leading zeros. The default precision is 1. The result of converting
322  * 0 with an explicit precision of 0 is no characters.
323  * </dd>
324  * <dt>
325  * o
326  * </dt>
327  * <dd>
328  * The int argument is converted to unsigned octal format in the style ddddd.
329  * The precision specifies the minimum number of digits to appear; if the
330  * value being converted can be represented in fewer digits, it will be
331  * expanded with leading zeros. The default precision is 1. The result of
332  * converting 0 with an explicit precision of 0 is no characters.
333  * </dd>
334  * <dt>
335  * x
336  * </dt>
337  * <dd>
338  * The int argument is converted to unsigned hexadecimal format in the style
339  * dddd; the letters abcdef are used. The precision specifies the minimum
340  * numberof digits to appear; if the value being converted can be represented
341  * in fewer digits, it will be expanded with leading zeros. The default
342  * precision is 1. The result of converting 0 with an explicit precision of 0
343  * is no characters.
344  * </dd>
345  * <dt>
346  * X
347  * </dt>
348  * <dd>
349  * Behaves the same as the x conversion character except that letters ABCDEF
350  * are used instead of abcdef.
351  * </dd>
352  * <dt>
353  * f
354  * </dt>
355  * <dd>
356  * The floating point number argument is written in decimal notation in the
357  * style [-]ddd.ddd, where the number of digits after the radix character
358  * (shown here as a decimal point) is equal to the precision specification. A
359  * Locale is used to determine the radix character to use in this format. If
360  * the precision is omitted from the argument, six digits are written after
361  * the radix character; if the precision is explicitly 0 and the # flag is
362  * not specified, no radix character appears. If a radix character appears,
363  * at least 1 digit appears before it. The value is rounded to the
364  * appropriate number of digits.
365  * </dd>
366  * <dt>
367  * e,E
368  * </dt>
369  * <dd>
370  * The floating point number argument is written in the style [-]d.ddde{+-}dd
371  * (the symbols {+-} indicate either a plus or minus sign), where there is one
372  * digit before the radix character (shown here as a decimal point) and the
373  * number of digits after it is equal to the precision. A Locale is used to
374  * determine the radix character to use in this format. When the precision is
375  * missing, six digits are written after the radix character; if the precision
376  * is 0 and the # flag is not specified, no radix character appears. The E
377  * conversion will produce a number with E instead of e introducing the
378  * exponent. The exponent always contains at least two digits. However, if
379  * the value to be written requires an exponent greater than two digits,
380  * additional exponent digits are written as necessary. The value is rounded
381  * to the appropriate number of digits.
382  * </dd>
383  * <dt>
384  * g,G
385  * </dt>
386  * <dd>
387  * The floating point number argument is written in style f or e (or in sytle E
388  * in the case of a G conversion character), with the precision specifying the
389  * number of significant digits. If the precision is zero, it is taken as
390  * one. The style used depends on the value converted: style e (or E) will
391  * be used only if the exponent resulting from the conversion is less than -4
392  * or greater than or equal to the precision. Trailing zeros are removed from
393  * the result. A radix character appears only if it is followed by a digit.
394  * </dd>
395  * <dt>
396  * c,C
397  * </dt>
398  * <dd>
399  * The integer argument is converted to a char and the result is written.
400  * </dd>
401  * <dt>
402  * s,S
403  * </dt>
404  * <dd>
405  * The argument is taken to be a string and bytes from the string are written
406  * until the end of the string or the number of bytes indicated by the
407  * precision specification of the argument is reached. If the precision is
408  * omitted from the argument, it is taken to be infinite, so all characters up
409  * to the end of the string are written.
410  * </dd>
411  * <dt>
412  * %
413  * </dt>
414  * <dd>
415  * Write a % character; no argument is converted.
416  * </dd>
417  * </dl>
418  *
419  * <p>
420  * If a conversion specification does not match one of the above forms, an
421  * IllegalArgumentException is thrown and the instance of PrintfFormat is not
422  * created.
423  * </p>
424  *
425  * <p>
426  * If a floating point value is the internal representation for infinity, the
427  * output is [+]Infinity, where Infinity is either Infinity or Inf, depending
428  * on the desired output string length. Printing of the sign follows the rules
429  * described above.
430  * </p>
431  *
432  * <p>
433  * If a floating point value is the internal representation for "not-a-number,"
434  * the output is [+]NaN. Printing of the sign follows the rules described
435  * above.
436  * </p>
437  *
438  * <p>
439  * In no case does a non-existent or small field width cause truncation of a
440  * field; if the result of a conversion is wider than the field width, the
441  * field is simply expanded to contain the conversion result.
442  * </p>
443  *
444  * <p>
445  * The behavior is like printf. One exception is that the minimum number of
446  * exponent digits is 3 instead of 2 for e and E formats when the optional L
447  * is used before the e, E, g, or G conversion character. The optional L does
448  * not imply conversion to a long long double.
449  * </p>
450  *
451  * <p>
452  * The biggest divergence from the C printf specification is in the use of 16
453  * bit characters. This allows the handling of characters beyond the small
454  * ASCII character set and allows the utility to interoperate correctly with
455  * the rest of the Java runtime environment.
456  * </p>
457  *
458  * <p>
459  * Omissions from the C printf specification are numerous. All the known
460  * omissions are present because Java never uses bytes to represent characters
461  * and does not have pointers:
462  * </p>
463  *
464  * <ul>
465  * <li>
466  * %c is the same as %C.
467  * </li>
468  * <li>
469  * %s is the same as %S.
470  * </li>
471  * <li>
472  * u, p, and n conversion characters.
473  * </li>
474  * <li>
475  * %ws format.
476  * </li>
477  * <li>
478  * h modifier applied to an n conversion character.
479  * </li>
480  * <li>
481  * l (ell) modifier applied to the c, n, or s conversion characters.
482  * </li>
483  * <li>
484  * ll (ell ell) modifier to d, i, o, u, x, or X conversion characters.
485  * </li>
486  * <li>
487  * ll (ell ell) modifier to an n conversion character.
488  * </li>
489  * <li>
490  * c, C, d,i,o,u,x, and X conversion characters apply to Byte, Character,
491  * Short, Integer, Long types.
492  * </li>
493  * <li>
494  * f, e, E, g, and G conversion characters apply to Float and Double types.
495  * </li>
496  * <li>
497  * s and S conversion characters apply to String types.
498  * </li>
499  * <li>
500  * All other reference types can be formatted using the s or S conversion
501  * characters only.
502  * </li>
503  * </ul>
504  *
505  * <p>
506  * Most of this specification is quoted from the Unix man page for the sprintf
507  * utility.
508  * </p>
509  */

510 public class PrintfFormat {
511    /** Character position. Used by the constructor. */
512    private DecimalFormatSymbols JavaDoc dfs = null;
513    private Locale JavaDoc locale = null;
514
515    /** Vector of control strings and format literals. */
516    private Vector JavaDoc vFmt = new Vector JavaDoc();
517
518    /** Character position. Used by the constructor. */
519    private int cPos = 0;
520    private int formatCount = 0;
521
522    /**
523     * Creates a new PrintfFormat object.
524     *
525     * @param locale DOCUMENT ME!
526     */

527    public PrintfFormat(Locale JavaDoc locale) {
528       this();
529       setLocale(locale);
530    }
531
532
533    /**
534     * Creates a new PrintfFormat object.
535     */

536    public PrintfFormat() {
537       setLocale(Locale.getDefault());
538    }
539
540
541    /**
542     * Constructs an array of control specifications possibly preceded,
543     * separated, or followed by ordinary strings. Control strings begin with
544     * unpaired percent signs. A pair of successive percent signs designates a
545     * single percent sign in the format.
546     *
547     * @param fmtArg Control string.
548     *
549     * @exception IllegalArgumentException if the control string is null, zero
550     * length, or otherwise malformed.
551     */

552    public PrintfFormat(String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
553       this();
554       setFormat(fmtArg);
555    }
556
557
558    /**
559     * Constructs an array of control specifications possibly preceded,
560     * separated, or followed by ordinary strings. Control strings begin with
561     * unpaired percent signs. A pair of successive percent signs designates a
562     * single percent sign in the format.
563     *
564     * @param locale DOCUMENT ME!
565     * @param fmtArg Control string.
566     *
567     * @exception IllegalArgumentException if the control string is null, zero
568     * length, or otherwise malformed.
569     */

570    public PrintfFormat(Locale JavaDoc locale,
571                        String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
572       this(locale);
573       setFormat(fmtArg);
574    }
575
576    /**
577     * DOCUMENT ME!
578     *
579     * @param fmtArg DOCUMENT ME!
580     *
581     * @throws IllegalArgumentException DOCUMENT ME!
582     */

583    public void setFormat(String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
584       formatCount = 0;
585
586       int ePos = 0;
587       ConversionSpecification sFmt = null;
588       String JavaDoc unCS = this.nonControl(fmtArg, 0);
589       vFmt.clear();
590
591       if (unCS != null) {
592          sFmt = new ConversionSpecification();
593          sFmt.setLiteral(unCS);
594          vFmt.addElement(sFmt);
595       }
596
597       while ((cPos != -1) && (cPos < fmtArg.length())) {
598          for (ePos = cPos + 1; ePos < fmtArg.length(); ePos++) {
599             char c = 0;
600             c = fmtArg.charAt(ePos);
601
602             if (c == 'i') {
603                break;
604             }
605
606             if (c == 'd') {
607                break;
608             }
609
610             if (c == 'f') {
611                break;
612             }
613
614             if (c == 'g') {
615                break;
616             }
617
618             if (c == 'G') {
619                break;
620             }
621
622             if (c == 'o') {
623                break;
624             }
625
626             if (c == 'x') {
627                break;
628             }
629
630             if (c == 'X') {
631                break;
632             }
633
634             if (c == 'e') {
635                break;
636             }
637
638             if (c == 'E') {
639                break;
640             }
641
642             if (c == 'c') {
643                break;
644             }
645
646             if (c == 's') {
647                break;
648             }
649
650             if (c == '%') {
651                break;
652             }
653          }
654
655          ePos = Math.min(ePos + 1, fmtArg.length());
656          sFmt = new ConversionSpecification(fmtArg.substring(cPos, ePos));
657          formatCount++;
658          vFmt.addElement(sFmt);
659          unCS = this.nonControl(fmtArg, ePos);
660
661          if (unCS != null) {
662             sFmt = new ConversionSpecification();
663             sFmt.setLiteral(unCS);
664             vFmt.addElement(sFmt);
665          }
666       }
667    }
668
669
670    /**
671     * DOCUMENT ME!
672     *
673     * @param locale DOCUMENT ME!
674     */

675    public void setLocale(Locale JavaDoc locale) {
676       if (locale != null) {
677          this.locale = locale;
678          dfs = new DecimalFormatSymbols JavaDoc(getLocale());
679       }
680    }
681
682
683    /**
684     * DOCUMENT ME!
685     *
686     * @return DOCUMENT ME!
687     */

688    public Locale JavaDoc getLocale() {
689       return locale;
690    }
691
692
693    /**
694     * Format an array of objects. Byte, Short, Integer, Long, Float, Double,
695     * and Character arguments are treated as wrappers for primitive types.
696     *
697     * @param o The array of objects to format.
698     *
699     * @return The formatted String.
700     */

701    public String JavaDoc sprintf(Object JavaDoc[] o) {
702       Enumeration JavaDoc e = vFmt.elements();
703       ConversionSpecification cs = null;
704       char c = 0;
705       int i = 0;
706       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
707
708       while (e.hasMoreElements()) {
709          cs = (ConversionSpecification) e.nextElement();
710          c = cs.getConversionCharacter();
711
712          if (c == '\0') {
713             sb.append(cs.getLiteral());
714          } else if (c == '%') {
715             sb.append("%");
716          } else {
717             if (cs.isPositionalSpecification()) {
718                i = cs.getArgumentPosition() - 1;
719
720                if (cs.isPositionalFieldWidth()) {
721                   int ifw = cs.getArgumentPositionForFieldWidth() - 1;
722                   cs.setFieldWidthWithArg(((Integer JavaDoc) o[ifw]).intValue());
723                }
724
725                if (cs.isPositionalPrecision()) {
726                   int ipr = cs.getArgumentPositionForPrecision() - 1;
727                   cs.setPrecisionWithArg(((Integer JavaDoc) o[ipr]).intValue());
728                }
729             } else {
730                if (cs.isVariableFieldWidth()) {
731                   cs.setFieldWidthWithArg(((Integer JavaDoc) o[i]).intValue());
732                   i++;
733                }
734
735                if (cs.isVariablePrecision()) {
736                   cs.setPrecisionWithArg(((Integer JavaDoc) o[i]).intValue());
737                   i++;
738                }
739             }
740
741             if (o[i] instanceof Byte JavaDoc) {
742                sb.append(cs.internalsprintf(((Byte JavaDoc) o[i]).byteValue()));
743             } else if (o[i] instanceof Short JavaDoc) {
744                sb.append(cs.internalsprintf(((Short JavaDoc) o[i]).shortValue()));
745             } else if (o[i] instanceof Integer JavaDoc) {
746                sb.append(cs.internalsprintf(((Integer JavaDoc) o[i]).intValue()));
747             } else if (o[i] instanceof Long JavaDoc) {
748                sb.append(cs.internalsprintf(((Long JavaDoc) o[i]).longValue()));
749             } else if (o[i] instanceof Float JavaDoc) {
750                sb.append(cs.internalsprintf(((Float JavaDoc) o[i]).floatValue()));
751             } else if (o[i] instanceof Double JavaDoc) {
752                sb.append(cs.internalsprintf(((Double JavaDoc) o[i]).doubleValue()));
753             } else if (o[i] instanceof Character JavaDoc) {
754                sb.append(cs.internalsprintf(((Character JavaDoc) o[i]).charValue()));
755             } else if (o[i] instanceof String JavaDoc) {
756                sb.append(cs.internalsprintf((String JavaDoc) o[i]));
757             } else if (o[i] instanceof Date JavaDoc) {
758                sb.append(cs.internalsprintf((Date JavaDoc) o[i]));
759             } else {
760                sb.append(cs.internalsprintf(o[i]));
761             }
762
763             if (!cs.isPositionalSpecification()) {
764                i++;
765             }
766          }
767       }
768
769       return sb.toString();
770    }
771
772
773    /**
774     * Format nothing. Just use the control string.
775     *
776     * @return the formatted String.
777     */

778    public String JavaDoc sprintf() {
779       Enumeration JavaDoc e = vFmt.elements();
780       ConversionSpecification cs = null;
781       char c = 0;
782       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
783
784       while (e.hasMoreElements()) {
785          cs = (ConversionSpecification) e.nextElement();
786          c = cs.getConversionCharacter();
787
788          if (c == '\0') {
789             sb.append(cs.getLiteral());
790          } else if (c == '%') {
791             sb.append("%");
792          }
793       }
794
795       return sb.toString();
796    }
797
798
799    /**
800     * Format an int.
801     *
802     * @param x The int to format.
803     *
804     * @return The formatted String.
805     *
806     * @exception IllegalArgumentException if the conversion character is f, e,
807     * E, g, G, s, or S.
808     */

809    public String JavaDoc sprintf(int x) throws IllegalArgumentException JavaDoc {
810       Enumeration JavaDoc e = vFmt.elements();
811       ConversionSpecification cs = null;
812       char c = 0;
813       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
814
815       while (e.hasMoreElements()) {
816          cs = (ConversionSpecification) e.nextElement();
817          c = cs.getConversionCharacter();
818
819          if (c == '\0') {
820             sb.append(cs.getLiteral());
821          } else if (c == '%') {
822             sb.append("%");
823          } else {
824             sb.append(cs.internalsprintf(x));
825          }
826       }
827
828       return sb.toString();
829    }
830
831
832    /**
833     * Format an long.
834     *
835     * @param x The long to format.
836     *
837     * @return The formatted String.
838     *
839     * @exception IllegalArgumentException if the conversion character is f, e,
840     * E, g, G, s, or S.
841     */

842    public String JavaDoc sprintf(long x) throws IllegalArgumentException JavaDoc {
843       Enumeration JavaDoc e = vFmt.elements();
844       ConversionSpecification cs = null;
845       char c = 0;
846       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
847
848       while (e.hasMoreElements()) {
849          cs = (ConversionSpecification) e.nextElement();
850          c = cs.getConversionCharacter();
851
852          if (c == '\0') {
853             sb.append(cs.getLiteral());
854          } else if (c == '%') {
855             sb.append("%");
856          } else {
857             sb.append(cs.internalsprintf(x));
858          }
859       }
860
861       return sb.toString();
862    }
863
864
865    /**
866     * Format a double.
867     *
868     * @param x The double to format.
869     *
870     * @return The formatted String.
871     *
872     * @exception IllegalArgumentException if the conversion character is c, C,
873     * s, S, d, d, x, X, or o.
874     */

875    public String JavaDoc sprintf(double x) throws IllegalArgumentException JavaDoc {
876       Enumeration JavaDoc e = vFmt.elements();
877       ConversionSpecification cs = null;
878       char c = 0;
879       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
880
881       while (e.hasMoreElements()) {
882          cs = (ConversionSpecification) e.nextElement();
883          c = cs.getConversionCharacter();
884
885          if (c == '\0') {
886             sb.append(cs.getLiteral());
887          } else if (c == '%') {
888             sb.append("%");
889          } else {
890             sb.append(cs.internalsprintf(x));
891          }
892       }
893
894       return sb.toString();
895    }
896
897
898    /**
899     * Format a String.
900     *
901     * @param x The String to format.
902     *
903     * @return The formatted String.
904     *
905     * @exception IllegalArgumentException if the conversion character is
906     * neither s nor S.
907     */

908    public String JavaDoc sprintf(String JavaDoc x) throws IllegalArgumentException JavaDoc {
909       Enumeration JavaDoc e = vFmt.elements();
910       ConversionSpecification cs = null;
911       char c = 0;
912       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
913
914       while (e.hasMoreElements()) {
915          cs = (ConversionSpecification) e.nextElement();
916          c = cs.getConversionCharacter();
917
918          if (c == '\0') {
919             sb.append(cs.getLiteral());
920          } else if (c == '%') {
921             sb.append("%");
922          } else {
923             sb.append(cs.internalsprintf(x));
924          }
925       }
926
927       return sb.toString();
928    }
929
930
931    /**
932     * Format an Object. Convert wrapper types to their primitive equivalents
933     * and call the appropriate internal formatting method. Convert Strings
934     * using an internal formatting method for Strings. Otherwise use the
935     * default formatter (use toString).
936     *
937     * @param x the Object to format.
938     *
939     * @return the formatted String.
940     *
941     * @exception IllegalArgumentException if the conversion character is
942     * inappropriate for formatting an unwrapped value.
943     */

944    public String JavaDoc sprintf(Object JavaDoc x) throws IllegalArgumentException JavaDoc {
945       Enumeration JavaDoc e = vFmt.elements();
946       ConversionSpecification cs = null;
947       char c = 0;
948       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
949
950       while (e.hasMoreElements()) {
951          cs = (ConversionSpecification) e.nextElement();
952          c = cs.getConversionCharacter();
953
954          if (c == '\0') {
955             sb.append(cs.getLiteral());
956          } else if (c == '%') {
957             sb.append("%");
958          } else {
959             if (x instanceof Byte JavaDoc) {
960                sb.append(cs.internalsprintf(((Byte JavaDoc) x).byteValue()));
961             } else if (x instanceof Short JavaDoc) {
962                sb.append(cs.internalsprintf(((Short JavaDoc) x).shortValue()));
963             } else if (x instanceof Integer JavaDoc) {
964                sb.append(cs.internalsprintf(((Integer JavaDoc) x).intValue()));
965             } else if (x instanceof Long JavaDoc) {
966                sb.append(cs.internalsprintf(((Long JavaDoc) x).longValue()));
967             } else if (x instanceof Float JavaDoc) {
968                sb.append(cs.internalsprintf(((Float JavaDoc) x).floatValue()));
969             } else if (x instanceof Double JavaDoc) {
970                sb.append(cs.internalsprintf(((Double JavaDoc) x).doubleValue()));
971             } else if (x instanceof Character JavaDoc) {
972                sb.append(cs.internalsprintf(((Character JavaDoc) x).charValue()));
973             } else if (x instanceof String JavaDoc) {
974                sb.append(cs.internalsprintf((String JavaDoc) x));
975             } else {
976                sb.append(cs.internalsprintf(x));
977             }
978          }
979       }
980
981       return sb.toString();
982    }
983
984
985    /**
986     * DOCUMENT ME!
987     *
988     * @return DOCUMENT ME!
989     */

990    protected int getFormatCount() {
991       return formatCount;
992    }
993
994
995    /**
996     * Return a substring starting at <code>start</code> and ending at either
997     * the end of the String <code>s</code>, the next unpaired percent sign, or
998     * at the end of the String if the last character is a percent sign.
999     *
1000    * @param s Control string.
1001    * @param start Position in the string <code>s</code> to begin looking for
1002    * the start of a control string.
1003    *
1004    * @return the substring from the start position to the beginning of the
1005    * control string.
1006    */

1007   private String JavaDoc nonControl(String JavaDoc s,
1008                             int start) {
1009      cPos = s.indexOf("%", start);
1010
1011      if (cPos == -1) {
1012         cPos = s.length();
1013      }
1014
1015      return s.substring(start, cPos);
1016   }
1017
1018   /**
1019    * <p>
1020    * ConversionSpecification allows the formatting of a single primitive or
1021    * object embedded within a string. The formatting is controlled by a
1022    * format string. Only one Java primitive or object can be formatted at a
1023    * time.
1024    * </p>
1025    *
1026    * <p>
1027    * A format string is a Java string that contains a control string. The
1028    * control string starts at the first percent sign (%) in the string,
1029    * provided that this percent sign
1030    *
1031    * <ol>
1032    * <li>
1033    * is not escaped protected by a matching % or is not an escape % character,
1034    * </li>
1035    * <li>
1036    * is not at the end of the format string, and
1037    * </li>
1038    * <li>
1039    * precedes a sequence of characters that parses as a valid control string.
1040    * </li>
1041    * </ol>
1042    * </p>
1043    *
1044    * <p>
1045    * A control string takes the form:
1046    * <pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
1047    * { [hlL] }+ [idfgGoxXeEcs]
1048    * </pre>
1049    * </p>
1050    *
1051    * <p>
1052    * The behavior is like printf. One (hopefully the only) exception is that
1053    * the minimum number of exponent digits is 3 instead of 2 for e and E
1054    * formats when the optional L is used before the e, E, g, or G conversion
1055    * character. The optional L does not imply conversion to a long long
1056    * double.
1057    * </p>
1058    */

1059   private class ConversionSpecification {
1060      /** Default precision. */
1061      private static final int DEFAULTDIGITS = 6;
1062
1063      /** Literal or control format string. */
1064      private String JavaDoc fmt;
1065
1066      /**
1067       * For an o conversion, increase the precision to force the first digit
1068       * of the result to be a zero. For x (or X) conversions, a non-zero
1069       * result will have 0x (or 0X) prepended to it. For e, E, f, g, or G
1070       * conversions, the result will always contain a radix character, even
1071       * if no digits follow the point. For g and G conversions, trailing
1072       * zeros will not be removed from the result.
1073       */

1074      private boolean alternateForm = false;
1075
1076      /** Flag indicating whether or not the field width has been set. */
1077      private boolean fieldWidthSet = false;
1078
1079      /**
1080       * The result of a signed conversion will always begin with a sign (+ or
1081       * -).
1082       */

1083      private boolean leadingSign = false;
1084
1085      /** Flag indicating that left padding with spaces is specified. */
1086      private boolean leadingSpace = false;
1087
1088      /** Flag indicating that left padding with zeroes is specified. */
1089      private boolean leadingZeros = false;
1090
1091      /**
1092       * The result of the conversion will be left-justified within the field.
1093       */

1094      private boolean leftJustify = false;
1095
1096      /**
1097       * Flag specifying that a following e, E, f, g, or G conversion character
1098       * applies to a type double argument. This is a noop in Java.
1099       */

1100      private boolean optionalL = false;
1101
1102      /**
1103       * Flag specifying that a following d, i, o, u, x, or X conversion
1104       * character applies to a type short int.
1105       */

1106      private boolean optionalh = false;
1107
1108      /**
1109       * Flag specifying that a following d, i, o, u, x, or X conversion
1110       * character applies to a type lont int argument.
1111       */

1112      private boolean optionall = false;
1113      private boolean positionalFieldWidth = false;
1114      private boolean positionalPrecision = false;
1115
1116      /*
1117       */

1118      private boolean positionalSpecification = false;
1119
1120      /** Flag indicating whether or not the precision has been set. */
1121      private boolean precisionSet = false;
1122
1123      /**
1124       * The integer portion of the result of a decimal conversion (i, d, u, f,
1125       * g, or G) will be formatted with thousands' grouping characters. For
1126       * other conversions the flag is ignored.
1127       */

1128      private boolean thousands = false;
1129
1130      /** Flag indicating that the field width is . */
1131      private boolean variableFieldWidth = false;
1132
1133      /** Flag indicating that the precision is . */
1134      private boolean variablePrecision = false;
1135
1136      /** Control string type. */
1137      private char conversionCharacter = '\0';
1138      private int argumentPosition = 0;
1139      private int argumentPositionForFieldWidth = 0;
1140      private int argumentPositionForPrecision = 0;
1141
1142      /**
1143       * If the converted value has fewer bytes than the field width, it will
1144       * be padded with spaces or zeroes.
1145       */

1146      private int fieldWidth = 0;
1147
1148      /** Position within the control string. Used by the constructor. */
1149      private int pos = 0;
1150
1151      /**
1152       * The minimum number of digits to appear for the d, i, o, u, x, or X
1153       * conversions. The number of digits to appear after the radix
1154       * character for the e, E, and f conversions. The maximum number of
1155       * significant digits for the g and G conversions. The maximum number
1156       * of bytes to be printed from a string in s and S conversions.
1157       */

1158      private int precision = 0;
1159
1160      /**
1161       * Constructor. Used to prepare an instance to hold a literal, not a
1162       * control string.
1163       */

1164      ConversionSpecification() {
1165      }
1166
1167
1168      /**
1169       * Constructor for a conversion specification. The argument must begin
1170       * with a % and end with the conversion character for the conversion
1171       * specification.
1172       *
1173       * @param fmtArg String specifying the conversion specification.
1174       *
1175       * @exception IllegalArgumentException if the input string is null, zero
1176       * length, or otherwise malformed.
1177       */

1178      ConversionSpecification(String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
1179         if (fmtArg == null) {
1180            throw new NullPointerException JavaDoc();
1181         }
1182
1183         if (fmtArg.length() == 0) {
1184            throw new IllegalArgumentException JavaDoc("Control strings must have positive"
1185                                               + " lengths.");
1186         }
1187
1188         if (fmtArg.charAt(0) == '%') {
1189            fmt = fmtArg;
1190            pos = 1;
1191            setArgPosition();
1192            setFlagCharacters();
1193            setFieldWidth();
1194            setPrecision();
1195            setOptionalHL();
1196
1197            if (setConversionCharacter()) {
1198               if (pos == fmtArg.length()) {
1199                  if (leadingZeros && leftJustify) {
1200                     leadingZeros = false;
1201                  }
1202
1203                  if (precisionSet && leadingZeros) {
1204                     if ((conversionCharacter == 'd')
1205                               || (conversionCharacter == 'i')
1206                               || (conversionCharacter == 'o')
1207                               || (conversionCharacter == 'x')) {
1208                        leadingZeros = false;
1209                     }
1210                  }
1211               } else {
1212                  throw new IllegalArgumentException JavaDoc("Malformed conversion specification="
1213                                                     + fmtArg);
1214               }
1215            } else {
1216               throw new IllegalArgumentException JavaDoc("Malformed conversion specification="
1217                                                  + fmtArg);
1218            }
1219         } else {
1220            throw new IllegalArgumentException JavaDoc("Control strings must begin with %.");
1221         }
1222      }
1223
1224      int getArgumentPosition() {
1225         return argumentPosition;
1226      }
1227
1228
1229      int getArgumentPositionForFieldWidth() {
1230         return argumentPositionForFieldWidth;
1231      }
1232
1233
1234      int getArgumentPositionForPrecision() {
1235         return argumentPositionForPrecision;
1236      }
1237
1238
1239      /**
1240       * Get the conversion character that tells what type of control character
1241       * this instance has.
1242       *
1243       * @return the conversion character.
1244       */

1245      char getConversionCharacter() {
1246         return conversionCharacter;
1247      }
1248
1249
1250      /**
1251       * Set the field width with an argument. A negative field width is taken
1252       * as a - flag followed by a positive field width.
1253       *
1254       * @param fw the field width.
1255       */

1256      void setFieldWidthWithArg(int fw) {
1257         if (fw < 0) {
1258            leftJustify = true;
1259         }
1260
1261         fieldWidthSet = true;
1262         fieldWidth = Math.abs(fw);
1263      }
1264
1265
1266      /**
1267       * Set the String for this instance.
1268       *
1269       * @param s the String to store.
1270       */

1271      void setLiteral(String JavaDoc s) {
1272         fmt = s;
1273      }
1274
1275
1276      /**
1277       * Get the String for this instance. Translate any escape sequences.
1278       *
1279       * @return s the stored String.
1280       */

1281      String JavaDoc getLiteral() {
1282         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1283         int i = 0;
1284
1285         while (i < fmt.length()) {
1286            if (fmt.charAt(i) == '\\') {
1287               i++;
1288
1289               if (i < fmt.length()) {
1290                  char c = fmt.charAt(i);
1291
1292                  switch (c) {
1293                     case 'a':
1294                        sb.append((char) 0x07);
1295
1296                        break;
1297
1298                     case 'b':
1299                        sb.append('\b');
1300
1301                        break;
1302
1303                     case 'f':
1304                        sb.append('\f');
1305
1306                        break;
1307
1308                     case 'n':
1309                        sb.append(System.getProperty("line.separator"));
1310
1311                        break;
1312
1313                     case 'r':
1314                        sb.append('\r');
1315
1316                        break;
1317
1318                     case 't':
1319                        sb.append('\t');
1320
1321                        break;
1322
1323                     case 'v':
1324                        sb.append((char) 0x0b);
1325
1326                        break;
1327
1328                     case '\\':
1329                        sb.append('\\');
1330
1331                        break;
1332                  }
1333
1334                  i++;
1335               } else {
1336                  sb.append('\\');
1337               }
1338            } else {
1339               i++;
1340            }
1341         }
1342
1343         return fmt;
1344      }
1345
1346
1347      boolean isPositionalFieldWidth() {
1348         return positionalFieldWidth;
1349      }
1350
1351
1352      boolean isPositionalPrecision() {
1353         return positionalPrecision;
1354      }
1355
1356
1357      boolean isPositionalSpecification() {
1358         return positionalSpecification;
1359      }
1360
1361
1362      /**
1363       * Set the precision with an argument. A negative precision will be
1364       * changed to zero.
1365       *
1366       * @param pr the precision.
1367       */

1368      void setPrecisionWithArg(int pr) {
1369         precisionSet = true;
1370         precision = Math.max(pr, 0);
1371      }
1372
1373
1374      /**
1375       * Check whether the specifier has a variable field width that is going
1376       * to be set by an argument.
1377       *
1378       * @return <code>true</code> if the conversion uses an field width;
1379       * otherwise <code>false</code>.
1380       */

1381      boolean isVariableFieldWidth() {
1382         return variableFieldWidth;
1383      }
1384
1385
1386      /**
1387       * Check whether the specifier has a variable precision that is going to
1388       * be set by an argument.
1389       *
1390       * @return <code>true</code> if the conversion uses an precision;
1391       * otherwise <code>false</code>.
1392       */

1393      boolean isVariablePrecision() {
1394         return variablePrecision;
1395      }
1396
1397
1398      /**
1399       * Format an Date argument using this conversion specification.
1400       *
1401       * @param s the Object to format.
1402       *
1403       * @return the formatted String.
1404       *
1405       * @exception IllegalArgumentException if the conversion character is
1406       * neither s nor S.
1407       */

1408      String JavaDoc internalsprintf(Date JavaDoc s) {
1409         if (s == null) {
1410            return ""; // dikr 2002-12-18, return null values as empty string
1411
}
1412
1413         String JavaDoc s2 = "";
1414
1415         if ((conversionCharacter == 's') || (conversionCharacter == 'S')) {
1416            DateFormat JavaDoc f = DateFormat.getDateInstance(DateFormat.MEDIUM,
1417                                                      getLocale());
1418            String JavaDoc ss = f.format(s);
1419            s2 = printSFormat(ss);
1420         } else {
1421            throw new IllegalArgumentException JavaDoc("Cannot format a String with a format using"
1422                                               + " a " + conversionCharacter
1423                                               + " conversion character.");
1424         }
1425
1426         return s2;
1427      }
1428
1429
1430      /**
1431       * Format an Object argument using this conversion specification.
1432       *
1433       * @param s the Object to format.
1434       *
1435       * @return the formatted String.
1436       *
1437       * @exception IllegalArgumentException if the conversion character is
1438       * neither s nor S.
1439       */

1440      String JavaDoc internalsprintf(Object JavaDoc s) {
1441         if (s == null) {
1442            return ""; // dikr 2002-12-18, return null values as empty string
1443
}
1444
1445         String JavaDoc s2 = "";
1446
1447         if ((conversionCharacter == 's') || (conversionCharacter == 'S')) {
1448            s2 = printSFormat(s.toString());
1449         } else {
1450            throw new IllegalArgumentException JavaDoc("Cannot format a String with a format using"
1451                                               + " a " + conversionCharacter
1452                                               + " conversion character.");
1453         }
1454
1455         return s2;
1456      }
1457
1458
1459      /**
1460       * Format an int argument using this conversion specification.
1461       *
1462       * @param s the int to format.
1463       *
1464       * @return the formatted String.
1465       *
1466       * @exception IllegalArgumentException if the conversion character is f,
1467       * e, E, g, or G.
1468       */

1469      String JavaDoc internalsprintf(int s) throws IllegalArgumentException JavaDoc {
1470         String JavaDoc s2 = "";
1471
1472         switch (conversionCharacter) {
1473            case 'd':
1474            case 'i':
1475
1476               if (optionalh) {
1477                  s2 = printDFormat((short) s);
1478               } else if (optionall) {
1479                  s2 = printDFormat((long) s);
1480               } else {
1481                  s2 = printDFormat(s);
1482               }
1483
1484               break;
1485
1486            case 'x':
1487            case 'X':
1488
1489               if (optionalh) {
1490                  s2 = printXFormat((short) s);
1491               } else if (optionall) {
1492                  s2 = printXFormat((long) s);
1493               } else {
1494                  s2 = printXFormat(s);
1495               }
1496
1497               break;
1498
1499            case 'o':
1500
1501               if (optionalh) {
1502                  s2 = printOFormat((short) s);
1503               } else if (optionall) {
1504                  s2 = printOFormat((long) s);
1505               } else {
1506                  s2 = printOFormat(s);
1507               }
1508
1509               break;
1510
1511            case 'c':
1512            case 'C':
1513               s2 = printCFormat((char) s);
1514
1515               break;
1516
1517            default:
1518               throw new IllegalArgumentException JavaDoc("Cannot format a int with a format using a "
1519                                                  + conversionCharacter
1520                                                  + " conversion character.");
1521         }
1522
1523         return s2;
1524      }
1525
1526
1527      /**
1528       * Format a long argument using this conversion specification.
1529       *
1530       * @param s the long to format.
1531       *
1532       * @return the formatted String.
1533       *
1534       * @exception IllegalArgumentException if the conversion character is f,
1535       * e, E, g, or G.
1536       */

1537      String JavaDoc internalsprintf(long s) throws IllegalArgumentException JavaDoc {
1538         String JavaDoc s2 = "";
1539
1540         switch (conversionCharacter) {
1541            case 'd':
1542            case 'i':
1543
1544               if (optionalh) {
1545                  s2 = printDFormat((short) s);
1546               } else if (optionall) {
1547                  s2 = printDFormat(s);
1548               } else {
1549                  s2 = printDFormat((int) s);
1550               }
1551
1552               break;
1553
1554            case 'x':
1555            case 'X':
1556
1557               if (optionalh) {
1558                  s2 = printXFormat((short) s);
1559               } else if (optionall) {
1560                  s2 = printXFormat(s);
1561               } else {
1562                  s2 = printXFormat((int) s);
1563               }
1564
1565               break;
1566
1567            case 'o':
1568
1569               if (optionalh) {
1570                  s2 = printOFormat((short) s);
1571               } else if (optionall) {
1572                  s2 = printOFormat(s);
1573               } else {
1574                  s2 = printOFormat((int) s);
1575               }
1576
1577               break;
1578
1579            case 'c':
1580            case 'C':
1581               s2 = printCFormat((char) s);
1582
1583               break;
1584
1585            default:
1586               throw new IllegalArgumentException JavaDoc("Cannot format a long with a format using a "
1587                                                  + conversionCharacter
1588                                                  + " conversion character.");
1589         }
1590
1591         return s2;
1592      }
1593
1594
1595      /**
1596       * Format a double argument using this conversion specification.
1597       *
1598       * @param s the double to format.
1599       *
1600       * @return the formatted String.
1601       *
1602       * @exception IllegalArgumentException if the conversion character is c,
1603       * C, s, S, i, d, x, X, or o.
1604       */

1605      String JavaDoc internalsprintf(double s) throws IllegalArgumentException JavaDoc {
1606         String JavaDoc s2 = "";
1607
1608         switch (conversionCharacter) {
1609            case 'f':
1610               s2 = printFFormat(s);
1611
1612               break;
1613
1614            case 'E':
1615            case 'e':
1616               s2 = printEFormat(s);
1617
1618               break;
1619
1620            case 'G':
1621            case 'g':
1622               s2 = printGFormat(s);
1623
1624               break;
1625
1626            default:
1627               throw new IllegalArgumentException JavaDoc("Cannot "
1628                                                  + "format a double with a format using a "
1629                                                  + conversionCharacter
1630                                                  + " conversion character.");
1631         }
1632
1633         return s2;
1634      }
1635
1636
1637      /**
1638       * Format a String argument using this conversion specification.
1639       *
1640       * @param s the String to format.
1641       *
1642       * @return the formatted String.
1643       *
1644       * @exception IllegalArgumentException if the conversion character is
1645       * neither s nor S.
1646       */

1647      String JavaDoc internalsprintf(String JavaDoc s) throws IllegalArgumentException JavaDoc {
1648         String JavaDoc s2 = "";
1649
1650         if ((conversionCharacter == 's') || (conversionCharacter == 'S')) {
1651            s2 = printSFormat(s);
1652         } else {
1653            throw new IllegalArgumentException JavaDoc("Cannot "
1654                                               + "format a String with a format using a "
1655                                               + conversionCharacter
1656                                               + " conversion character.");
1657         }
1658
1659         return s2;
1660      }
1661
1662
1663      /**
1664       * Store the digits <code>n</code> in %n$ forms.
1665       */

1666      private void setArgPosition() {
1667         int xPos;
1668
1669         for (xPos = pos; xPos < fmt.length(); xPos++) {
1670            if (!Character.isDigit(fmt.charAt(xPos))) {
1671               break;
1672            }
1673         }
1674
1675         if ((xPos > pos) && (xPos < fmt.length())) {
1676            if (fmt.charAt(xPos) == '$') {
1677               positionalSpecification = true;
1678               argumentPosition = Integer.parseInt(fmt.substring(pos,
1679                                                                        xPos));
1680               pos = xPos + 1;
1681            }
1682         }
1683      }
1684
1685
1686      /**
1687       * Check for a conversion character. If it is there, store it.
1688       *
1689       * @return <code>true</code> if the conversion character is there, and
1690       * <code>false</code> otherwise.
1691       */

1692      private boolean setConversionCharacter() {
1693         /* idfgGoxXeEcs */
1694         boolean ret = false;
1695         conversionCharacter = '\0';
1696
1697         if (pos < fmt.length()) {
1698            char c = fmt.charAt(pos);
1699
1700            if ((c == 'i')
1701                      || (c == 'd')
1702                      || (c == 'f')
1703                      || (c == 'g')
1704                      || (c == 'G')
1705                      || (c == 'o')
1706                      || (c == 'x')
1707                      || (c == 'X')
1708                      || (c == 'e')
1709                      || (c == 'E')
1710                      || (c == 'c')
1711                      || (c == 's')
1712                      || (c == '%')) {
1713               conversionCharacter = c;
1714               pos++;
1715               ret = true;
1716            }
1717         }
1718
1719         return ret;
1720      }
1721
1722
1723      /**
1724       * Set the field width.
1725       */

1726      private void setFieldWidth() {
1727         int firstPos = pos;
1728         fieldWidth = 0;
1729         fieldWidthSet = false;
1730
1731         if ((pos < fmt.length()) && (fmt.charAt(pos) == '*')) {
1732            pos++;
1733
1734            if (!setFieldWidthArgPosition()) {
1735               variableFieldWidth = true;
1736               fieldWidthSet = true;
1737            }
1738         } else {
1739            while (pos < fmt.length()) {
1740               char c = fmt.charAt(pos);
1741
1742               if (Character.isDigit(c)) {
1743                  pos++;
1744               } else {
1745                  break;
1746               }
1747            }
1748
1749            if ((firstPos < pos) && (firstPos < fmt.length())) {
1750               String JavaDoc sz = fmt.substring(firstPos, pos);
1751               fieldWidth = Integer.parseInt(sz);
1752               fieldWidthSet = true;
1753            }
1754         }
1755      }
1756
1757
1758      /**
1759       * Store the digits <code>n</code> in n$ forms.
1760       *
1761       * @return DOCUMENT ME!
1762       */

1763      private boolean setFieldWidthArgPosition() {
1764         boolean ret = false;
1765         int xPos;
1766
1767         for (xPos = pos; xPos < fmt.length(); xPos++) {
1768            if (!Character.isDigit(fmt.charAt(xPos))) {
1769               break;
1770            }
1771         }
1772
1773         if ((xPos > pos) && (xPos < fmt.length())) {
1774            if (fmt.charAt(xPos) == '$') {
1775               positionalFieldWidth = true;
1776               argumentPositionForFieldWidth = Integer.parseInt(fmt.substring(pos,
1777                                                                              xPos));
1778               pos = xPos + 1;
1779               ret = true;
1780            }
1781         }
1782
1783         return ret;
1784      }
1785
1786
1787      /**
1788       * Set flag characters, one of '-+#0 or a space.
1789       */

1790      private void setFlagCharacters() {
1791         /* '-+ #0 */
1792         thousands = false;
1793         leftJustify = false;
1794         leadingSign = false;
1795         leadingSpace = false;
1796         alternateForm = false;
1797         leadingZeros = false;
1798
1799         for (; pos < fmt.length(); pos++) {
1800            char c = fmt.charAt(pos);
1801
1802            if (c == '\'') {
1803               thousands = true;
1804            } else if (c == '-') {
1805               leftJustify = true;
1806               leadingZeros = false;
1807            } else if (c == '+') {
1808               leadingSign = true;
1809               leadingSpace = false;
1810            } else if (c == ' ') {
1811               if (!leadingSign) {
1812                  leadingSpace = true;
1813               }
1814            } else if (c == '#') {
1815               alternateForm = true;
1816            } else if (c == '0') {
1817               if (!leftJustify) {
1818                  leadingZeros = true;
1819               }
1820            } else {
1821               break;
1822            }
1823         }
1824      }
1825
1826
1827      /**
1828       * Check for an h, l, or L in a format. An L is used to control the
1829       * minimum number of digits in an exponent when using floating point
1830       * formats. An l or h is used to control conversion of the input to a
1831       * long or short, respectively, before formatting. If any of these is
1832       * present, store them.
1833       */

1834      private void setOptionalHL() {
1835         optionalh = false;
1836         optionall = false;
1837         optionalL = false;
1838
1839         if (pos < fmt.length()) {
1840            char c = fmt.charAt(pos);
1841
1842            if (c == 'h') {
1843               optionalh = true;
1844               pos++;
1845            } else if (c == 'l') {
1846               optionall = true;
1847               pos++;
1848            } else if (c == 'L') {
1849               optionalL = true;
1850               pos++;
1851            }
1852         }
1853      }
1854
1855
1856      /**
1857       * Set the precision.
1858       */

1859      private void setPrecision() {
1860         int firstPos = pos;
1861         precisionSet = false;
1862
1863         if ((pos < fmt.length()) && (fmt.charAt(pos) == '.')) {
1864            pos++;
1865
1866            if ((pos < fmt.length()) && (fmt.charAt(pos) == '*')) {
1867               pos++;
1868
1869               if (!setPrecisionArgPosition()) {
1870                  variablePrecision = true;
1871                  precisionSet = true;
1872               }
1873
1874               return;
1875            } else {
1876               while (pos < fmt.length()) {
1877                  char c = fmt.charAt(pos);
1878
1879                  if (Character.isDigit(c)) {
1880                     pos++;
1881                  } else {
1882                     break;
1883                  }
1884               }
1885
1886               if (pos > (firstPos + 1)) {
1887                  String JavaDoc sz = fmt.substring(firstPos + 1, pos);
1888                  precision = Integer.parseInt(sz);
1889                  precisionSet = true;
1890               }
1891            }
1892         }
1893      }
1894
1895
1896      /**
1897       * Store the digits <code>n</code> in n$ forms.
1898       *
1899       * @return DOCUMENT ME!
1900       */

1901      private boolean setPrecisionArgPosition() {
1902         boolean ret = false;
1903         int xPos;
1904
1905         for (xPos = pos; xPos < fmt.length(); xPos++) {
1906            if (!Character.isDigit(fmt.charAt(xPos))) {
1907               break;
1908            }
1909         }
1910
1911         if ((xPos > pos) && (xPos < fmt.length())) {
1912            if (fmt.charAt(xPos) == '$') {
1913               positionalPrecision = true;
1914               argumentPositionForPrecision = Integer.parseInt(fmt.substring(pos,
1915                                                                             xPos));
1916               pos = xPos + 1;
1917               ret = true;
1918            }
1919         }
1920
1921         return ret;
1922      }
1923
1924
1925      /**
1926       * Apply zero or blank, left or right padding.
1927       *
1928       * @param ca4 array of characters before padding is finished
1929       * @param noDigits NaN or signed Inf
1930       *
1931       * @return a padded array of characters
1932       */

1933      private char[] applyFloatPadding(char[] ca4,
1934                                       boolean noDigits) {
1935         char[] ca5 = ca4;
1936
1937         if (fieldWidthSet) {
1938            int i;
1939            int j;
1940            int nBlanks;
1941
1942            if (leftJustify) {
1943               nBlanks = fieldWidth - ca4.length;
1944
1945               if (nBlanks > 0) {
1946                  ca5 = new char[ca4.length + nBlanks];
1947
1948                  for (i = 0; i < ca4.length; i++)
1949                     ca5[i] = ca4[i];
1950
1951                  for (j = 0; j < nBlanks; j++, i++)
1952                     ca5[i] = ' ';
1953               }
1954            } else if (!leadingZeros || noDigits) {
1955               nBlanks = fieldWidth - ca4.length;
1956
1957               if (nBlanks > 0) {
1958                  ca5 = new char[ca4.length + nBlanks];
1959
1960                  for (i = 0; i < nBlanks; i++)
1961                     ca5[i] = ' ';
1962
1963                  for (j = 0; j < ca4.length; i++, j++)
1964                     ca5[i] = ca4[j];
1965               }
1966            } else if (leadingZeros) {
1967               nBlanks = fieldWidth - ca4.length;
1968
1969               if (nBlanks > 0) {
1970                  ca5 = new char[ca4.length + nBlanks];
1971                  i = 0;
1972                  j = 0;
1973
1974                  if (ca4[0] == '-') {
1975                     ca5[0] = '-';
1976                     i++;
1977                     j++;
1978                  }
1979
1980                  for (int k = 0; k < nBlanks; i++, k++)
1981                     ca5[i] = '0';
1982
1983                  for (; j < ca4.length; i++, j++)
1984                     ca5[i] = ca4[j];
1985               }
1986            }
1987         }
1988
1989         return ca5;
1990      }
1991
1992
1993      /**
1994       * Check to see if the digits that are going to be truncated because of
1995       * the precision should force a round in the preceding digits.
1996       *
1997       * @param ca1 the array of digits
1998       * @param icarry the index of the first digit that is to be truncated
1999       * from the print
2000       *
2001       * @return <code>true</code> if the truncation forces a round that will
2002       * change the print
2003       */

2004      private boolean checkForCarry(char[] ca1,
2005                                    int icarry) {
2006         boolean carry = false;
2007
2008         if (icarry < ca1.length) {
2009            if ((ca1[icarry] == '6')
2010                      || (ca1[icarry] == '7')
2011                      || (ca1[icarry] == '8')
2012                      || (ca1[icarry] == '9')) {
2013               carry = true;
2014            } else if (ca1[icarry] == '5') {
2015               int ii = icarry + 1;
2016
2017               for (; ii < ca1.length; ii++)
2018                  if (ca1[ii] != '0') {
2019                     break;
2020                  }
2021
2022               carry = ii < ca1.length;
2023
2024               if (!carry && (icarry > 0)) {
2025                  carry = ((ca1[icarry - 1] == '1') || (ca1[icarry - 1] == '3')
2026                          || (ca1[icarry - 1] == '5')
2027                          || (ca1[icarry - 1] == '7')
2028                          || (ca1[icarry - 1] == '9'));
2029               }
2030            }
2031         }
2032
2033         return carry;
2034      }
2035
2036
2037      /**
2038       * For e format, the flag character '-', means that the output should be
2039       * left justified within the field. The default is to pad with blanks
2040       * on the left. '+' character means that the conversion will always
2041       * begin with a sign (+ or -). The blank flag character means that a
2042       * non-negative input will be preceded with a blank. If both a '+' and
2043       * a ' ' are specified, the blank flag is ignored. The '0' flag
2044       * character implies that padding to the field width will be done with
2045       * zeros instead of blanks. The field width is treated as the minimum
2046       * number of characters to be printed. The default is to add no
2047       * padding. Padding is with blanks by default. The precision, if set,
2048       * is the minimum number of digits to appear after the radix character.
2049       * Padding is with trailing 0s. The behavior is like printf. One
2050       * (hopefully the only) exception is that the minimum number of exponent
2051       * digits is 3 instead of 2 for e and E formats when the optional L is
2052       * used before the e, E, g, or G conversion character. The optional L
2053       * does not imply conversion to a long long double.
2054       *
2055       * @param x DOCUMENT ME!
2056       * @param eChar DOCUMENT ME!
2057       *
2058       * @return DOCUMENT ME!
2059       */

2060      private char[] eFormatDigits(double x,
2061                                   char eChar) {
2062         char[] ca1;
2063         char[] ca2;
2064         char[] ca3;
2065
2066         // int defaultDigits=6;
2067
String JavaDoc sx;
2068
2069         // int defaultDigits=6;
2070
int i;
2071         int j;
2072         int k;
2073         int p;
2074         int expon = 0;
2075         int ePos;
2076         int rPos;
2077         int eSize;
2078         boolean minusSign = false;
2079
2080         if (x > 0.0) {
2081            sx = Double.toString(x);
2082         } else if (x < 0.0) {
2083            sx = Double.toString(-x);
2084            minusSign = true;
2085         } else {
2086            sx = Double.toString(x);
2087
2088            if (sx.charAt(0) == '-') {
2089               minusSign = true;
2090               sx = sx.substring(1);
2091            }
2092         }
2093
2094         ePos = sx.indexOf('E');
2095
2096         if (ePos == -1) {
2097            ePos = sx.indexOf('e');
2098         }
2099
2100         rPos = sx.indexOf('.');
2101
2102         if (ePos != -1) {
2103            int ie = ePos + 1;
2104            expon = 0;
2105
2106            if (sx.charAt(ie) == '-') {
2107               for (++ie; ie < sx.length(); ie++)
2108                  if (sx.charAt(ie) != '0') {
2109                     break;
2110                  }
2111
2112               if (ie < sx.length()) {
2113                  expon = -Integer.parseInt(sx.substring(ie));
2114               }
2115            } else {
2116               if (sx.charAt(ie) == '+') {
2117                  ++ie;
2118               }
2119
2120               for (; ie < sx.length(); ie++)
2121                  if (sx.charAt(ie) != '0') {
2122                     break;
2123                  }
2124
2125               if (ie < sx.length()) {
2126                  expon = Integer.parseInt(sx.substring(ie));
2127               }
2128            }
2129         }
2130
2131         if (rPos != -1) {
2132            expon += (rPos - 1);
2133         }
2134
2135         if (precisionSet) {
2136            p = precision;
2137         } else {
2138            p = DEFAULTDIGITS - 1;
2139         }
2140
2141         if ((rPos != -1) && (ePos != -1)) {
2142            ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1, ePos))
2143                  .toCharArray();
2144         } else if (rPos != -1) {
2145            ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1)).toCharArray();
2146         } else if (ePos != -1) {
2147            ca1 = sx.substring(0, ePos)
2148                    .toCharArray();
2149         } else {
2150            ca1 = sx.toCharArray();
2151         }
2152
2153         boolean carry = false;
2154         int i0 = 0;
2155
2156         if (ca1[0] != '0') {
2157            i0 = 0;
2158         } else {
2159            for (i0 = 0; i0 < ca1.length; i0++)
2160               if (ca1[i0] != '0') {
2161                  break;
2162               }
2163         }
2164
2165         if ((i0 + p) < (ca1.length - 1)) {
2166            carry = checkForCarry(ca1, i0 + p + 1);
2167
2168            if (carry) {
2169               carry = startSymbolicCarry(ca1, i0 + p, i0);
2170            }
2171
2172            if (carry) {
2173               ca2 = new char[i0 + p + 1];
2174               ca2[i0] = '1';
2175
2176               for (j = 0; j < i0; j++)
2177                  ca2[j] = '0';
2178
2179               for (i = i0, j = i0 + 1; j < (p + 1); i++, j++)
2180                  ca2[j] = ca1[i];
2181
2182               expon++;
2183               ca1 = ca2;
2184            }
2185         }
2186
2187         if ((Math.abs(expon) < 100) && !optionalL) {
2188            eSize = 4;
2189         } else {
2190            eSize = 5;
2191         }
2192
2193         if (alternateForm || !precisionSet || (precision != 0)) {
2194            ca2 = new char[2 + p + eSize];
2195         } else {
2196            ca2 = new char[1 + eSize];
2197         }
2198
2199         if (ca1[0] != '0') {
2200            ca2[0] = ca1[0];
2201            j = 1;
2202         } else {
2203            for (j = 1; j < ((ePos == -1) ? ca1.length
2204                                                : ePos); j++)
2205               if (ca1[j] != '0') {
2206                  break;
2207               }
2208
2209            if (((ePos != -1) && (j < ePos))
2210                      || ((ePos == -1) && (j < ca1.length))) {
2211               ca2[0] = ca1[j];
2212               expon -= j;
2213               j++;
2214            } else {
2215               ca2[0] = '0';
2216               j = 2;
2217            }
2218         }
2219
2220         if (alternateForm || !precisionSet || (precision != 0)) {
2221            ca2[1] = '.';
2222            i = 2;
2223         } else {
2224            i = 1;
2225         }
2226
2227         for (k = 0; (k < p) && (j < ca1.length); j++, i++, k++)
2228            ca2[i] = ca1[j];
2229
2230         for (; i < (ca2.length - eSize); i++)
2231            ca2[i] = '0';
2232
2233         ca2[i++] = eChar;
2234
2235         if (expon < 0) {
2236            ca2[i++] = '-';
2237         } else {
2238            ca2[i++] = '+';
2239         }
2240
2241         expon = Math.abs(expon);
2242
2243         if (expon >= 100) {
2244            switch (expon / 100) {
2245               case 1:
2246                  ca2[i] = '1';
2247
2248                  break;
2249
2250               case 2:
2251                  ca2[i] = '2';
2252
2253                  break;
2254
2255               case 3:
2256                  ca2[i] = '3';
2257
2258                  break;
2259
2260               case 4:
2261                  ca2[i] = '4';
2262
2263                  break;
2264
2265               case 5:
2266                  ca2[i] = '5';
2267
2268                  break;
2269
2270               case 6:
2271                  ca2[i] = '6';
2272
2273                  break;
2274
2275               case 7:
2276                  ca2[i] = '7';
2277
2278                  break;
2279
2280               case 8:
2281                  ca2[i] = '8';
2282
2283                  break;
2284
2285               case 9:
2286                  ca2[i] = '9';
2287
2288                  break;
2289            }
2290
2291            i++;
2292         }
2293
2294         switch ((expon % 100) / 10) {
2295            case 0:
2296               ca2[i] = '0';
2297
2298               break;
2299
2300            case 1:
2301               ca2[i] = '1';
2302
2303               break;
2304
2305            case 2:
2306               ca2[i] = '2';
2307
2308               break;
2309
2310            case 3:
2311               ca2[i] = '3';
2312
2313               break;
2314
2315            case 4:
2316               ca2[i] = '4';
2317
2318               break;
2319
2320            case 5:
2321               ca2[i] = '5';
2322
2323               break;
2324
2325            case 6:
2326               ca2[i] = '6';
2327
2328               break;
2329
2330            case 7:
2331               ca2[i] = '7';
2332
2333               break;
2334
2335            case 8:
2336               ca2[i] = '8';
2337
2338               break;
2339
2340            case 9:
2341               ca2[i] = '9';
2342
2343               break;
2344         }
2345
2346         i++;
2347
2348         switch (expon % 10) {
2349            case 0:
2350               ca2[i] = '0';
2351
2352               break;
2353
2354            case 1:
2355               ca2[i] = '1';
2356
2357               break;
2358
2359            case 2:
2360               ca2[i] = '2';
2361
2362               break;
2363
2364            case 3:
2365               ca2[i] = '3';
2366
2367               break;
2368
2369            case 4:
2370               ca2[i] = '4';
2371
2372               break;
2373
2374            case 5:
2375               ca2[i] = '5';
2376
2377               break;
2378
2379            case 6:
2380               ca2[i] = '6';
2381
2382               break;
2383
2384            case 7:
2385               ca2[i] = '7';
2386
2387               break;
2388
2389            case 8:
2390               ca2[i] = '8';
2391
2392               break;
2393
2394            case 9:
2395               ca2[i] = '9';
2396
2397               break;
2398         }
2399
2400         int nZeros = 0;
2401
2402         if (!leftJustify && leadingZeros) {
2403            int xThousands = 0;
2404
2405            if (thousands) {
2406               int xlead = 0;
2407
2408               if ((ca2[0] == '+') || (ca2[0] == '-') || (ca2[0] == ' ')) {
2409                  xlead = 1;
2410               }
2411
2412               int xdp = xlead;
2413
2414               for (; xdp < ca2.length; xdp++)
2415                  if (ca2[xdp] == '.') {
2416                     break;
2417                  }
2418
2419               xThousands = (xdp - xlead) / 3;
2420            }
2421
2422            if (fieldWidthSet) {
2423               nZeros = fieldWidth - ca2.length;
2424            }
2425
2426            if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
2427               nZeros--;
2428            }
2429
2430            nZeros -= xThousands;
2431
2432            if (nZeros < 0) {
2433               nZeros = 0;
2434            }
2435         }
2436
2437         j = 0;
2438
2439         if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
2440            ca3 = new char[ca2.length + nZeros + 1];
2441            j++;
2442         } else {
2443            ca3 = new char[ca2.length + nZeros];
2444         }
2445
2446         if (!minusSign) {
2447            if (leadingSign) {
2448               ca3[0] = '+';
2449            }
2450
2451            if (leadingSpace) {
2452               ca3[0] = ' ';
2453            }
2454         } else {
2455            ca3[0] = '-';
2456         }
2457
2458         for (k = 0; k < nZeros; j++, k++)
2459            ca3[j] = '0';
2460
2461         for (i = 0; (i < ca2.length) && (j < ca3.length); i++, j++)
2462            ca3[j] = ca2[i];
2463
2464         int lead = 0;
2465
2466         if ((ca3[0] == '+') || (ca3[0] == '-') || (ca3[0] == ' ')) {
2467            lead = 1;
2468         }
2469
2470         int dp = lead;
2471
2472         for (; dp < ca3.length; dp++)
2473            if (ca3[dp] == '.') {
2474               break;
2475            }
2476
2477         int nThousands = dp / 3;
2478
2479         // Localize the decimal point.
2480
if (dp < ca3.length) {
2481            ca3[dp] = dfs.getDecimalSeparator();
2482         }
2483
2484         char[] ca4 = ca3;
2485
2486         if (thousands && (nThousands > 0)) {
2487            ca4 = new char[ca3.length + nThousands + lead];
2488            ca4[0] = ca3[0];
2489
2490            for (i = lead, k = lead; i < dp; i++) {
2491               if ((i > 0) && (((dp - i) % 3) == 0)) {
2492                  // ca4[k]=',';
2493
ca4[k] = dfs.getGroupingSeparator();
2494                  ca4[k + 1] = ca3[i];
2495                  k += 2;
2496               } else {
2497                  ca4[k] = ca3[i];
2498                  k++;
2499               }
2500            }
2501
2502            for (; i < ca3.length; i++, k++)
2503               ca4[k] = ca3[i];
2504         }
2505
2506         return ca4;
2507      }
2508
2509
2510      /**
2511       * An intermediate routine on the way to creating an e format String.
2512       * The method decides whether the input double value is an infinity,
2513       * not-a-number, or a finite double and formats each type of input
2514       * appropriately.
2515       *
2516       * @param x the double value to be formatted.
2517       * @param eChar an 'e' or 'E' to use in the converted double value.
2518       *
2519       * @return the converted double value.
2520       */

2521      private String JavaDoc eFormatString(double x,
2522                                   char eChar) {
2523         char[] ca4;
2524         char[] ca5;
2525
2526         if (Double.isInfinite(x)) {
2527            if (x == Double.POSITIVE_INFINITY) {
2528               if (leadingSign) {
2529                  ca4 = "+Inf".toCharArray();
2530               } else if (leadingSpace) {
2531                  ca4 = " Inf".toCharArray();
2532               } else {
2533                  ca4 = "Inf".toCharArray();
2534               }
2535            } else {
2536               ca4 = "-Inf".toCharArray();
2537            }
2538         } else if (Double.isNaN(x)) {
2539            if (leadingSign) {
2540               ca4 = "+NaN".toCharArray();
2541            } else if (leadingSpace) {
2542               ca4 = " NaN".toCharArray();
2543            } else {
2544               ca4 = "NaN".toCharArray();
2545            }
2546         } else {
2547            ca4 = eFormatDigits(x, eChar);
2548         }
2549
2550         ca5 = applyFloatPadding(ca4, false);
2551
2552         return new String JavaDoc(ca5);
2553      }
2554
2555
2556      /**
2557       * For f format, the flag character '-', means that the output should be
2558       * left justified within the field. The default is to pad with blanks
2559       * on the left. '+' character means that the conversion will always
2560       * begin with a sign (+ or -). The blank flag character means that a
2561       * non-negative input will be preceded with a blank. If both a '+' and
2562       * a ' ' are specified, the blank flag is ignored. The '0' flag
2563       * character implies that padding to the field width will be done with
2564       * zeros instead of blanks. The field width is treated as the minimum
2565       * number of characters to be printed. The default is to add no
2566       * padding. Padding is with blanks by default. The precision, if set,
2567       * is the number of digits to appear after the radix character. Padding
2568       * is with trailing 0s.
2569       *
2570       * @param x DOCUMENT ME!
2571       *
2572       * @return DOCUMENT ME!
2573       */

2574      private char[] fFormatDigits(double x) {
2575         // int defaultDigits=6;
2576
String JavaDoc sx;
2577
2578         // int defaultDigits=6;
2579
int i;
2580         int j;
2581         int k;
2582         int n1In;
2583         int n2In;
2584         int expon = 0;
2585         boolean minusSign = false;
2586
2587         if (x > 0.0) {
2588            sx = Double.toString(x);
2589         } else if (x < 0.0) {
2590            sx = Double.toString(-x);
2591            minusSign = true;
2592         } else {
2593            sx = Double.toString(x);
2594
2595            if (sx.charAt(0) == '-') {
2596               minusSign = true;
2597               sx = sx.substring(1);
2598            }
2599         }
2600
2601         int ePos = sx.indexOf('E');
2602         int rPos = sx.indexOf('.');
2603
2604         if (rPos != -1) {
2605            n1In = rPos;
2606         } else if (ePos != -1) {
2607            n1In = ePos;
2608         } else {
2609            n1In = sx.length();
2610         }
2611
2612         if (rPos != -1) {
2613            if (ePos != -1) {
2614               n2In = ePos - rPos - 1;
2615            } else {
2616               n2In = sx.length() - rPos - 1;
2617            }
2618         } else {
2619            n2In = 0;
2620         }
2621
2622         if (ePos != -1) {
2623            int ie = ePos + 1;
2624            expon = 0;
2625
2626            if (sx.charAt(ie) == '-') {
2627               for (++ie; ie < sx.length(); ie++)
2628                  if (sx.charAt(ie) != '0') {
2629                     break;
2630                  }
2631
2632               if (ie < sx.length()) {
2633                  expon = -Integer.parseInt(sx.substring(ie));
2634               }
2635            } else {
2636               if (sx.charAt(ie) == '+') {
2637                  ++ie;
2638               }
2639
2640               for (; ie < sx.length(); ie++)
2641                  if (sx.charAt(ie) != '0') {
2642                     break;
2643                  }
2644
2645               if (ie < sx.length()) {
2646                  expon = Integer.parseInt(sx.substring(ie));
2647               }
2648            }
2649         }
2650
2651         int p;
2652
2653         if (precisionSet) {
2654            p = precision;
2655         } else {
2656            p = DEFAULTDIGITS - 1;
2657         }
2658
2659         char[] ca1 = sx.toCharArray();
2660         char[] ca2 = new char[n1In + n2In];
2661         char[] ca3;
2662         char[] ca4;
2663         char[] ca5;
2664
2665         for (j = 0; j < n1In; j++)
2666            ca2[j] = ca1[j];
2667
2668         i = j + 1;
2669
2670         for (k = 0; k < n2In; j++, i++, k++)
2671            ca2[j] = ca1[i];
2672
2673         if ((n1In + expon) <= 0) {
2674            ca3 = new char[-expon + n2In];
2675
2676            for (j = 0, k = 0; k < (-n1In - expon); k++, j++)
2677               ca3[j] = '0';
2678
2679            for (i = 0; i < (n1In + n2In); i++, j++)
2680               ca3[j] = ca2[i];
2681         } else {
2682            ca3 = ca2;
2683         }
2684
2685         boolean carry = false;
2686
2687         if (p < (-expon + n2In)) {
2688            if (expon < 0) {
2689               i = p;
2690            } else {
2691               i = p + n1In;
2692            }
2693
2694            carry = checkForCarry(ca3, i);
2695
2696            if (carry) {
2697               carry = startSymbolicCarry(ca3, i - 1, 0);
2698            }
2699         }
2700
2701         if ((n1In + expon) <= 0) {
2702            ca4 = new char[2 + p];
2703
2704            if (!carry) {
2705               ca4[0] = '0';
2706            } else {
2707               ca4[0] = '1';
2708            }
2709
2710            if (alternateForm || !precisionSet || (precision != 0)) {
2711               ca4[1] = '.';
2712
2713               for (i = 0, j = 2; i < Math.min(p, ca3.length); i++, j++)
2714                  ca4[j] = ca3[i];
2715
2716               for (; j < ca4.length; j++)
2717                  ca4[j] = '0';
2718            }
2719         } else {
2720            if (!carry) {
2721               if (alternateForm || !precisionSet || (precision != 0)) {
2722                  ca4 = new char[n1In + expon + p + 1];
2723               } else {
2724                  ca4 = new char[n1In + expon];
2725               }
2726
2727               j = 0;
2728            } else {
2729               if (alternateForm || !precisionSet || (precision != 0)) {
2730                  ca4 = new char[n1In + expon + p + 2];
2731               } else {
2732                  ca4 = new char[n1In + expon + 1];
2733               }
2734
2735               ca4[0] = '1';
2736               j = 1;
2737            }
2738
2739            for (i = 0; i < Math.min(n1In + expon, ca3.length); i++, j++)
2740               ca4[j] = ca3[i];
2741
2742            for (; i < (n1In + expon); i++, j++)
2743               ca4[j] = '0';
2744
2745            if (alternateForm || !precisionSet || (precision != 0)) {
2746               ca4[j] = '.';
2747               j++;
2748
2749               for (k = 0; (i < ca3.length) && (k < p); i++, j++, k++)
2750                  ca4[j] = ca3[i];
2751
2752               for (; j < ca4.length; j++)
2753                  ca4[j] = '0';
2754            }
2755         }
2756
2757         int nZeros = 0;
2758
2759         if (!leftJustify && leadingZeros) {
2760            int xThousands = 0;
2761
2762            if (thousands) {
2763               int xlead = 0;
2764
2765               if ((ca4[0] == '+') || (ca4[0] == '-') || (ca4[0] == ' ')) {
2766                  xlead = 1;
2767               }
2768
2769               int xdp = xlead;
2770
2771               for (; xdp < ca4.length; xdp++)
2772                  if (ca4[xdp] == '.') {
2773                     break;
2774                  }
2775
2776               xThousands = (xdp - xlead) / 3;
2777            }
2778
2779            if (fieldWidthSet) {
2780               nZeros = fieldWidth - ca4.length;
2781            }
2782
2783            if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
2784               nZeros--;
2785            }
2786
2787            nZeros -= xThousands;
2788
2789            if (nZeros < 0) {
2790               nZeros = 0;
2791            }
2792         }
2793
2794         j = 0;
2795
2796         if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
2797            ca5 = new char[ca4.length + nZeros + 1];
2798            j++;
2799         } else {
2800            ca5 = new char[ca4.length + nZeros];
2801         }
2802
2803         if (!minusSign) {
2804            if (leadingSign) {
2805               ca5[0] = '+';
2806            }
2807
2808            if (leadingSpace) {
2809               ca5[0] = ' ';
2810            }
2811         } else {
2812            ca5[0] = '-';
2813         }
2814
2815         for (i = 0; i < nZeros; i++, j++)
2816            ca5[j] = '0';
2817
2818         for (i = 0; i < ca4.length; i++, j++)
2819            ca5[j] = ca4[i];
2820
2821         int lead = 0;
2822
2823         if ((ca5[0] == '+') || (ca5[0] == '-') || (ca5[0] == ' ')) {
2824            lead = 1;
2825         }
2826
2827         int dp = lead;
2828
2829         for (; dp < ca5.length; dp++)
2830            if (ca5[dp] == '.') {
2831               break;
2832            }
2833
2834         int nThousands = (dp - lead) / 3;
2835
2836         // Localize the decimal point.
2837
if (dp < ca5.length) {
2838            ca5[dp] = dfs.getDecimalSeparator();
2839         }
2840
2841         char[] ca6 = ca5;
2842
2843         if (thousands && (nThousands > 0)) {
2844            ca6 = new char[ca5.length + nThousands + lead];
2845            ca6[0] = ca5[0];
2846
2847            for (i = lead, k = lead; i < dp; i++) {
2848               if ((i > 0) && (((dp - i) % 3) == 0)) {
2849                  // ca6[k]=',';
2850
ca6[k] = dfs.getGroupingSeparator();
2851                  ca6[k + 1] = ca5[i];
2852                  k += 2;
2853               } else {
2854                  ca6[k] = ca5[i];
2855                  k++;
2856               }
2857            }
2858
2859            for (; i < ca5.length; i++, k++) {
2860               ca6[k] = ca5[i];
2861            }
2862         }
2863
2864         return ca6;
2865      }
2866
2867
2868      /**
2869       * An intermediate routine on the way to creating an f format String.
2870       * The method decides whether the input double value is an infinity,
2871       * not-a-number, or a finite double and formats each type of input
2872       * appropriately.
2873       *
2874       * @param x the double value to be formatted.
2875       *
2876       * @return the converted double value.
2877       */

2878      private String JavaDoc fFormatString(double x) {
2879         char[] ca6;
2880         char[] ca7;
2881
2882         if (Double.isInfinite(x)) {
2883            if (x == Double.POSITIVE_INFINITY) {
2884               if (leadingSign) {
2885                  ca6 = "+Inf".toCharArray();
2886               } else if (leadingSpace) {
2887                  ca6 = " Inf".toCharArray();
2888               } else {
2889                  ca6 = "Inf".toCharArray();
2890               }
2891            } else {
2892               ca6 = "-Inf".toCharArray();
2893            }
2894         } else if (Double.isNaN(x)) {
2895            if (leadingSign) {
2896               ca6 = "+NaN".toCharArray();
2897            } else if (leadingSpace) {
2898               ca6 = " NaN".toCharArray();
2899            } else {
2900               ca6 = "NaN".toCharArray();
2901            }
2902         } else {
2903            ca6 = fFormatDigits(x);
2904         }
2905
2906         ca7 = applyFloatPadding(ca6, false);
2907
2908         return new String JavaDoc(ca7);
2909      }
2910
2911
2912      /**
2913       * Format method for the c conversion character and char argument. The
2914       * only flag character that affects c format is the '-', meaning that
2915       * the output should be left justified within the field. The default is
2916       * to pad with blanks on the left. The field width is treated as the
2917       * minimum number of characters to be printed. Padding is with blanks
2918       * by default. The default width is 1. The precision, if set, is
2919       * ignored.
2920       *
2921       * @param x the char to format.
2922       *
2923       * @return the formatted String.
2924       */

2925      private String JavaDoc printCFormat(char x) {
2926         int nPrint = 1;
2927         int width = fieldWidth;
2928
2929         if (!fieldWidthSet) {
2930            width = nPrint;
2931         }
2932
2933         char[] ca = new char[width];
2934         int i = 0;
2935
2936         if (leftJustify) {
2937            ca[0] = x;
2938
2939            for (i = 1; i <= (width - nPrint); i++)
2940               ca[i] = ' ';
2941         } else {
2942            for (i = 0; i < (width - nPrint); i++)
2943               ca[i] = ' ';
2944
2945            ca[i] = x;
2946         }
2947
2948         return new String JavaDoc(ca);
2949      }
2950
2951
2952      /**
2953       * Format method for the d conversion specifer and short argument. For d
2954       * format, the flag character '-', means that the output should be left
2955       * justified within the field. The default is to pad with blanks on the
2956       * left. A '+' character means that the conversion will always begin
2957       * with a sign (+ or -). The blank flag character means that a
2958       * non-negative input will be preceded with a blank. If both a '+' and
2959       * a ' ' are specified, the blank flag is ignored. The '0' flag
2960       * character implies that padding to the field width will be done with
2961       * zeros instead of blanks. The field width is treated as the minimum
2962       * number of characters to be printed. The default is to add no
2963       * padding. Padding is with blanks by default. The precision, if set,
2964       * is the minimum number of digits to appear. Padding is with leading
2965       * 0s.
2966       *
2967       * @param x the short to format.
2968       *
2969       * @return the formatted String.
2970       */

2971      private String JavaDoc printDFormat(short x) {
2972         return printDFormat(Short.toString(x));
2973      }
2974
2975
2976      /**
2977       * Format method for the d conversion character and long argument. For d
2978       * format, the flag character '-', means that the output should be left
2979       * justified within the field. The default is to pad with blanks on the
2980       * left. A '+' character means that the conversion will always begin
2981       * with a sign (+ or -). The blank flag character means that a
2982       * non-negative input will be preceded with a blank. If both a '+' and
2983       * a ' ' are specified, the blank flag is ignored. The '0' flag
2984       * character implies that padding to the field width will be done with
2985       * zeros instead of blanks. The field width is treated as the minimum
2986       * number of characters to be printed. The default is to add no
2987       * padding. Padding is with blanks by default. The precision, if set,
2988       * is the minimum number of digits to appear. Padding is with leading
2989       * 0s.
2990       *
2991       * @param x the long to format.
2992       *
2993       * @return the formatted String.
2994       */

2995      private String JavaDoc printDFormat(long x) {
2996         return printDFormat(Long.toString(x));
2997      }
2998
2999
3000      /**
3001       * Format method for the d conversion character and int argument. For d
3002       * format, the flag character '-', means that the output should be left
3003       * justified within the field. The default is to pad with blanks on the
3004       * left. A '+' character means that the conversion will always begin
3005       * with a sign (+ or -). The blank flag character means that a
3006       * non-negative input will be preceded with a blank. If both a '+' and
3007       * a ' ' are specified, the blank flag is ignored. The '0' flag
3008       * character implies that padding to the field width will be done with
3009       * zeros instead of blanks. The field width is treated as the minimum
3010       * number of characters to be printed. The default is to add no
3011       * padding. Padding is with blanks by default. The precision, if set,
3012       * is the minimum number of digits to appear. Padding is with leading
3013       * 0s.
3014       *
3015       * @param x the int to format.
3016       *
3017       * @return the formatted String.
3018       */

3019      private String JavaDoc printDFormat(int x) {
3020         return printDFormat(Integer.toString(x));
3021      }
3022
3023
3024      /**
3025       * Utility method for formatting using the d conversion character.
3026       *
3027       * @param sx the String to format, the result of converting a short, int,
3028       * or long to a String.
3029       *
3030       * @return the formatted String.
3031       */

3032      private String JavaDoc printDFormat(String JavaDoc sx) {
3033         int nLeadingZeros = 0;
3034         int nBlanks = 0;
3035         int n = 0;
3036         int i = 0;
3037         int jFirst = 0;
3038         boolean neg = sx.charAt(0) == '-';
3039
3040         if (sx.equals("0") && precisionSet && (precision == 0)) {
3041            sx = "";
3042         }
3043
3044         if (!neg) {
3045            if (precisionSet && (sx.length() < precision)) {
3046               nLeadingZeros = precision - sx.length();
3047            }
3048         } else {
3049            if (precisionSet && ((sx.length() - 1) < precision)) {
3050               nLeadingZeros = precision - sx.length() + 1;
3051            }
3052         }
3053
3054         if (nLeadingZeros < 0) {
3055            nLeadingZeros = 0;
3056         }
3057
3058         if (fieldWidthSet) {
3059            nBlanks = fieldWidth - nLeadingZeros - sx.length();
3060
3061            if (!neg && (leadingSign || leadingSpace)) {
3062               nBlanks--;
3063            }
3064         }
3065
3066         if (nBlanks < 0) {
3067            nBlanks = 0;
3068         }
3069
3070         if (leadingSign) {
3071            n++;
3072         } else if (leadingSpace) {
3073            n++;
3074         }
3075
3076         n += nBlanks;
3077         n += nLeadingZeros;
3078         n += sx.length();
3079
3080         char[] ca = new char[n];
3081
3082         if (leftJustify) {
3083            if (neg) {
3084               ca[i++] = '-';
3085            } else if (leadingSign) {
3086               ca[i++] = '+';
3087            } else if (leadingSpace) {
3088               ca[i++] = ' ';
3089            }
3090
3091            char[] csx = sx.toCharArray();
3092            jFirst = neg ? 1
3093                         : 0;
3094
3095            for (int j = 0; j < nLeadingZeros; i++, j++)
3096               ca[i] = '0';
3097
3098            for (int j = jFirst; j < csx.length; j++, i++)
3099               ca[i] = csx[j];
3100
3101            for (int j = 0; j < nBlanks; i++, j++)
3102               ca[i] = ' ';
3103         } else {
3104            if (!leadingZeros) {
3105               for (i = 0; i < nBlanks; i++)
3106                  ca[i] = ' ';
3107
3108               if (neg) {
3109                  ca[i++] = '-';
3110               } else if (leadingSign) {
3111                  ca[i++] = '+';
3112               } else if (leadingSpace) {
3113                  ca[i++] = ' ';
3114               }
3115            } else {
3116               if (neg) {
3117                  ca[i++] = '-';
3118               } else if (leadingSign) {
3119                  ca[i++] = '+';
3120               } else if (leadingSpace) {
3121                  ca[i++] = ' ';
3122               }
3123
3124               for (int j = 0; j < nBlanks; j++, i++)
3125                  ca[i] = '0';
3126            }
3127
3128            for (int j = 0; j < nLeadingZeros; j++, i++)
3129               ca[i] = '0';
3130
3131            char[] csx = sx.toCharArray();
3132            jFirst = neg ? 1
3133                         : 0;
3134
3135            for (int j = jFirst; j < csx.length; j++, i++)
3136               ca[i] = csx[j];
3137         }
3138
3139         return new String JavaDoc(ca);
3140      }
3141
3142
3143      /**
3144       * Format method for the e or E conversion character.
3145       *
3146       * @param x the double to format.
3147       *
3148       * @return the formatted String.
3149       */

3150      private String JavaDoc printEFormat(double x) {
3151         if (conversionCharacter == 'e') {
3152            return eFormatString(x, 'e');
3153         } else {
3154            return eFormatString(x, 'E');
3155         }
3156      }
3157
3158
3159      /**
3160       * Format method for the f conversion character.
3161       *
3162       * @param x the double to format.
3163       *
3164       * @return the formatted String.
3165       */

3166      private String JavaDoc printFFormat(double x) {
3167         return fFormatString(x);
3168      }
3169
3170
3171      /**
3172       * Format method for the g conversion character. For g format, the flag
3173       * character '-', means that the output should be left justified within
3174       * the field. The default is to pad with blanks on the left. '+'
3175       * character means that the conversion will always begin with a sign (+
3176       * or -). The blank flag character means that a non-negative input will
3177       * be preceded with a blank. If both a '+' and a ' ' are specified, the
3178       * blank flag is ignored. The '0' flag character implies that padding
3179       * to the field width will be done with zeros instead of blanks. The
3180       * field width is treated as the minimum number of characters to be
3181       * printed. The default is to add no padding. Padding is with blanks
3182       * by default. The precision, if set, is the minimum number of digits to
3183       * appear after the radix character. Padding is with trailing 0s.
3184       *
3185       * @param x the double to format.
3186       *
3187       * @return the formatted String.
3188       */

3189      private String JavaDoc printGFormat(double x) {
3190         String JavaDoc sx;
3191         String JavaDoc sy;
3192         String JavaDoc sz;
3193         String JavaDoc ret;
3194         int savePrecision = precision;
3195         int i;
3196         char[] ca4;
3197         char[] ca5;
3198
3199         if (Double.isInfinite(x)) {
3200            if (x == Double.POSITIVE_INFINITY) {
3201               if (leadingSign) {
3202                  ca4 = "+Inf".toCharArray();
3203               } else if (leadingSpace) {
3204                  ca4 = " Inf".toCharArray();
3205               } else {
3206                  ca4 = "Inf".toCharArray();
3207               }
3208            } else {
3209               ca4 = "-Inf".toCharArray();
3210            }
3211         } else if (Double.isNaN(x)) {
3212            if (leadingSign) {
3213               ca4 = "+NaN".toCharArray();
3214            } else if (leadingSpace) {
3215               ca4 = " NaN".toCharArray();
3216            } else {
3217               ca4 = "NaN".toCharArray();
3218            }
3219         } else {
3220            if (!precisionSet) {
3221               precision = DEFAULTDIGITS;
3222            }
3223
3224            if (precision == 0) {
3225               precision = 1;
3226            }
3227
3228            int ePos = -1;
3229
3230            if (conversionCharacter == 'g') {
3231               sx = eFormatString(x, 'e')
3232                       .trim();
3233               ePos = sx.indexOf('e');
3234            } else {
3235               sx = eFormatString(x, 'E')
3236                       .trim();
3237               ePos = sx.indexOf('E');
3238            }
3239
3240            i = ePos + 1;
3241
3242            int expon = 0;
3243
3244            if (sx.charAt(i) == '-') {
3245               for (++i; i < sx.length(); i++)
3246                  if (sx.charAt(i) != '0') {
3247                     break;
3248                  }
3249
3250               if (i < sx.length()) {
3251                  expon = -Integer.parseInt(sx.substring(i));
3252               }
3253            } else {
3254               if (sx.charAt(i) == '+') {
3255                  ++i;
3256               }
3257
3258               for (; i < sx.length(); i++)
3259                  if (sx.charAt(i) != '0') {
3260                     break;
3261                  }
3262
3263               if (i < sx.length()) {
3264                  expon = Integer.parseInt(sx.substring(i));
3265               }
3266            }
3267
3268            // Trim trailing zeros.
3269
// If the radix character is not followed by
3270
// a digit, trim it, too.
3271
if (!alternateForm) {
3272               if ((expon >= -4) && (expon < precision)) {
3273                  sy = fFormatString(x)
3274                          .trim();
3275               } else {
3276                  sy = sx.substring(0, ePos);
3277               }
3278
3279               i = sy.length() - 1;
3280
3281               for (; i >= 0; i--)
3282                  if (sy.charAt(i) != '0') {
3283                     break;
3284                  }
3285
3286               if ((i >= 0) && (sy.charAt(i) == '.')) {
3287                  i--;
3288               }
3289
3290               if (i == -1) {
3291                  sz = "0";
3292               } else if (!Character.isDigit(sy.charAt(i))) {
3293                  sz = sy.substring(0, i + 1) + "0";
3294               } else {
3295                  sz = sy.substring(0, i + 1);
3296               }
3297
3298               if ((expon >= -4) && (expon < precision)) {
3299                  ret = sz;
3300               } else {
3301                  ret = sz + sx.substring(ePos);
3302               }
3303            } else {
3304               if ((expon >= -4) && (expon < precision)) {
3305                  ret = fFormatString(x)
3306                           .trim();
3307               } else {
3308                  ret = sx;
3309               }
3310            }
3311
3312            // leading space was trimmed off during
3313
// construction
3314
if (leadingSpace) {
3315               if (x >= 0) {
3316                  ret = " " + ret;
3317               }
3318            }
3319
3320            ca4 = ret.toCharArray();
3321         }
3322
3323         // Pad with blanks or zeros.
3324
ca5 = applyFloatPadding(ca4, false);
3325         precision = savePrecision;
3326
3327         return new String JavaDoc(ca5);
3328      }
3329
3330
3331      /**
3332       * Format method for the o conversion character and short argument. For o
3333       * format, the flag character '-', means that the output should be left
3334       * justified within the field. The default is to pad with blanks on the
3335       * left. The '#' flag character means that the output begins with a
3336       * leading 0 and the precision is increased by 1. The field width is
3337       * treated as the minimum number of characters to be printed. The
3338       * default is to add no padding. Padding is with blanks by default. The
3339       * precision, if set, is the minimum number of digits to appear.
3340       * Padding is with leading 0s.
3341       *
3342       * @param x the short to format.
3343       *
3344       * @return the formatted String.
3345       */

3346      private String JavaDoc printOFormat(short x) {
3347         String JavaDoc sx = null;
3348
3349         if (x == Short.MIN_VALUE) {
3350            sx = "100000";
3351         } else if (x < 0) {
3352            String JavaDoc t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE, 8);
3353
3354            switch (t.length()) {
3355               case 1:
3356                  sx = "10000" + t;
3357
3358                  break;
3359
3360               case 2:
3361                  sx = "1000" + t;
3362
3363                  break;
3364
3365               case 3:
3366                  sx = "100" + t;
3367
3368                  break;
3369
3370               case 4:
3371                  sx = "10" + t;
3372
3373                  break;
3374
3375               case 5:
3376                  sx = "1" + t;
3377
3378                  break;
3379            }
3380         } else {
3381            sx = Integer.toString(x, 8);
3382         }
3383
3384         return printOFormat(sx);
3385      }
3386
3387
3388      /**
3389       * Format method for the o conversion character and long argument. For o
3390       * format, the flag character '-', means that the output should be left
3391       * justified within the field. The default is to pad with blanks on the
3392       * left. The '#' flag character means that the output begins with a
3393       * leading 0 and the precision is increased by 1. The field width is
3394       * treated as the minimum number of characters to be printed. The
3395       * default is to add no padding. Padding is with blanks by default. The
3396       * precision, if set, is the minimum number of digits to appear.
3397       * Padding is with leading 0s.
3398       *
3399       * @param x the long to format.
3400       *
3401       * @return the formatted String.
3402       */

3403      private String JavaDoc printOFormat(long x) {
3404         String JavaDoc sx = null;
3405
3406         if (x == Long.MIN_VALUE) {
3407            sx = "1000000000000000000000";
3408         } else if (x < 0) {
3409            String JavaDoc t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE, 8);
3410
3411            switch (t.length()) {
3412               case 1:
3413                  sx = "100000000000000000000" + t;
3414
3415                  break;
3416
3417               case 2:
3418                  sx = "10000000000000000000" + t;
3419
3420                  break;
3421
3422               case 3:
3423                  sx = "1000000000000000000" + t;
3424
3425                  break;
3426
3427               case 4:
3428                  sx = "100000000000000000" + t;
3429
3430                  break;
3431
3432               case 5:
3433                  sx = "10000000000000000" + t;
3434
3435                  break;
3436
3437               case 6:
3438                  sx = "1000000000000000" + t;
3439
3440                  break;
3441
3442               case 7:
3443                  sx = "100000000000000" + t;
3444
3445                  break;
3446
3447               case 8:
3448                  sx = "10000000000000" + t;
3449
3450                  break;
3451
3452               case 9:
3453                  sx = "1000000000000" + t;
3454
3455                  break;
3456
3457               case 10:
3458                  sx = "100000000000" + t;
3459
3460                  break;
3461
3462               case 11:
3463                  sx = "10000000000" + t;
3464
3465                  break;
3466
3467               case 12:
3468                  sx = "1000000000" + t;
3469
3470                  break;
3471
3472               case 13:
3473                  sx = "100000000" + t;
3474
3475                  break;
3476
3477               case 14:
3478                  sx = "10000000" + t;
3479
3480                  break;
3481
3482               case 15:
3483                  sx = "1000000" + t;
3484
3485                  break;
3486
3487               case 16:
3488                  sx = "100000" + t;
3489
3490                  break;
3491
3492               case 17:
3493                  sx = "10000" + t;
3494
3495                  break;
3496
3497               case 18:
3498                  sx = "1000" + t;
3499
3500                  break;
3501
3502               case 19:
3503                  sx = "100" + t;
3504
3505                  break;
3506
3507               case 20:
3508                  sx = "10" + t;
3509
3510                  break;
3511
3512               case 21:
3513                  sx = "1" + t;
3514
3515                  break;
3516            }
3517         } else {
3518            sx = Long.toString(x, 8);
3519         }
3520
3521         return printOFormat(sx);
3522      }
3523
3524
3525      /**
3526       * Format method for the o conversion character and int argument. For o
3527       * format, the flag character '-', means that the output should be left
3528       * justified within the field. The default is to pad with blanks on the
3529       * left. The '#' flag character means that the output begins with a
3530       * leading 0 and the precision is increased by 1. The field width is
3531       * treated as the minimum number of characters to be printed. The
3532       * default is to add no padding. Padding is with blanks by default. The
3533       * precision, if set, is the minimum number of digits to appear.
3534       * Padding is with leading 0s.
3535       *
3536       * @param x the int to format.
3537       *
3538       * @return the formatted String.
3539       */

3540      private String JavaDoc printOFormat(int x) {
3541         String JavaDoc sx = null;
3542
3543         if (x == Integer.MIN_VALUE) {
3544            sx = "20000000000";
3545         } else if (x < 0) {
3546            String JavaDoc t = Integer.toString((~(-x - 1)) ^ Integer.MIN_VALUE, 8);
3547
3548            switch (t.length()) {
3549               case 1:
3550                  sx = "2000000000" + t;
3551
3552                  break;
3553
3554               case 2:
3555                  sx = "200000000" + t;
3556
3557                  break;
3558
3559               case 3:
3560                  sx = "20000000" + t;
3561
3562                  break;
3563
3564               case 4:
3565                  sx = "2000000" + t;
3566
3567                  break;
3568
3569               case 5:
3570                  sx = "200000" + t;
3571
3572                  break;
3573
3574               case 6:
3575                  sx = "20000" + t;
3576
3577                  break;
3578
3579               case 7:
3580                  sx = "2000" + t;
3581
3582                  break;
3583
3584               case 8:
3585                  sx = "200" + t;
3586
3587                  break;
3588
3589               case 9:
3590                  sx = "20" + t;
3591
3592                  break;
3593
3594               case 10:
3595                  sx = "2" + t;
3596
3597                  break;
3598
3599               case 11:
3600                  sx = "3" + t.substring(1);
3601
3602                  break;
3603            }
3604         } else {
3605            sx = Integer.toString(x, 8);
3606         }
3607
3608         return printOFormat(sx);
3609      }
3610
3611
3612      /**
3613       * Utility method for formatting using the o conversion character.
3614       *
3615       * @param sx the String to format, the result of converting a short, int,
3616       * or long to a String.
3617       *
3618       * @return the formatted String.
3619       */

3620      private String JavaDoc printOFormat(String JavaDoc sx) {
3621         int nLeadingZeros = 0;
3622         int nBlanks = 0;
3623
3624         if (sx.equals("0") && precisionSet && (precision == 0)) {
3625            sx = "";
3626         }
3627
3628         if (precisionSet) {
3629            nLeadingZeros = precision - sx.length();
3630         }
3631
3632         if (alternateForm) {
3633            nLeadingZeros++;
3634         }
3635
3636         if (nLeadingZeros < 0) {
3637            nLeadingZeros = 0;
3638         }
3639
3640         if (fieldWidthSet) {
3641            nBlanks = fieldWidth - nLeadingZeros - sx.length();
3642         }
3643
3644         if (nBlanks < 0) {
3645            nBlanks = 0;
3646         }
3647
3648         int n = nLeadingZeros + sx.length() + nBlanks;
3649         char[] ca = new char[n];
3650         int i;
3651
3652         if (leftJustify) {
3653            for (i = 0; i < nLeadingZeros; i++)
3654               ca[i] = '0';
3655
3656            char[] csx = sx.toCharArray();
3657
3658            for (int j = 0; j < csx.length; j++, i++)
3659               ca[i] = csx[j];
3660
3661            for (int j = 0; j < nBlanks; j++, i++)
3662               ca[i] = ' ';
3663         } else {
3664            if (leadingZeros) {
3665               for (i = 0; i < nBlanks; i++)
3666                  ca[i] = '0';
3667            } else {
3668               for (i = 0; i < nBlanks; i++)
3669                  ca[i] = ' ';
3670            }
3671
3672            for (int j = 0; j < nLeadingZeros; j++, i++)
3673               ca[i] = '0';
3674
3675            char[] csx = sx.toCharArray();
3676
3677            for (int j = 0; j < csx.length; j++, i++)
3678               ca[i] = csx[j];
3679         }
3680
3681         return new String JavaDoc(ca);
3682      }
3683
3684
3685      /**
3686       * Format method for the s conversion character and String argument. The
3687       * only flag character that affects s format is the '-', meaning that
3688       * the output should be left justified within the field. The default is
3689       * to pad with blanks on the left. The field width is treated as the
3690       * minimum number of characters to be printed. The default is the
3691       * smaller of the number of characters in the the input and the
3692       * precision. Padding is with blanks by default. The precision, if set,
3693       * specifies the maximum number of characters to be printed from the
3694       * string. A null digit string is treated as a 0. The default is not
3695       * to set a maximum number of characters to be printed.
3696       *
3697       * @param x the String to format.
3698       *
3699       * @return the formatted String.
3700       */

3701      private String JavaDoc printSFormat(String JavaDoc x) {
3702         int nPrint = x.length();
3703         int width = fieldWidth;
3704
3705         if (precisionSet && (nPrint > precision)) {
3706            nPrint = precision;
3707         }
3708
3709         if (!fieldWidthSet) {
3710            width = nPrint;
3711         }
3712
3713         int n = 0;
3714
3715         if (width > nPrint) {
3716            n += (width - nPrint);
3717         }
3718
3719         if (nPrint >= x.length()) {
3720            n += x.length();
3721         } else {
3722            n += nPrint;
3723         }
3724
3725         char[] ca = new char[n];
3726         int i = 0;
3727
3728         if (leftJustify) {
3729            if (nPrint >= x.length()) {
3730               char[] csx = x.toCharArray();
3731
3732               for (i = 0; i < x.length(); i++)
3733                  ca[i] = csx[i];
3734            } else {
3735               char[] csx = x.substring(0, nPrint)
3736                             .toCharArray();
3737
3738               for (i = 0; i < nPrint; i++)
3739                  ca[i] = csx[i];
3740            }
3741
3742            for (int j = 0; j < (width - nPrint); j++, i++)
3743               ca[i] = ' ';
3744         } else {
3745            for (i = 0; i < (width - nPrint); i++)
3746               ca[i] = ' ';
3747
3748            if (nPrint >= x.length()) {
3749               char[] csx = x.toCharArray();
3750
3751               for (int j = 0; j < x.length(); i++, j++)
3752                  ca[i] = csx[j];
3753            } else {
3754               char[] csx = x.substring(0, nPrint)
3755                             .toCharArray();
3756
3757               for (int j = 0; j < nPrint; i++, j++)
3758                  ca[i] = csx[j];
3759            }
3760         }
3761
3762         return new String JavaDoc(ca);
3763      }
3764
3765
3766      /**
3767       * Format method for the x conversion character and short argument. For x
3768       * format, the flag character '-', means that the output should be left
3769       * justified within the field. The default is to pad with blanks on the
3770       * left. The '#' flag character means to lead with '0x'. The field
3771       * width is treated as the minimum number of characters to be printed.
3772       * The default is to add no padding. Padding is with blanks by default.
3773       * The precision, if set, is the minimum number of digits to appear.
3774       * Padding is with leading 0s.
3775       *
3776       * @param x the short to format.
3777       *
3778       * @return the formatted String.
3779       */

3780      private String JavaDoc printXFormat(short x) {
3781         String JavaDoc sx = null;
3782
3783         if (x == Short.MIN_VALUE) {
3784            sx = "8000";
3785         } else if (x < 0) {
3786            String JavaDoc t;
3787
3788            if (x == Short.MIN_VALUE) {
3789               t = "0";
3790            } else {
3791               t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE, 16);
3792
3793               if ((t.charAt(0) == 'F') || (t.charAt(0) == 'f')) {
3794                  t = t.substring(16, 32);
3795               }
3796            }
3797
3798            switch (t.length()) {
3799               case 1:
3800                  sx = "800" + t;
3801
3802                  break;
3803
3804               case 2:
3805                  sx = "80" + t;
3806
3807                  break;
3808
3809               case 3:
3810                  sx = "8" + t;
3811
3812                  break;
3813
3814               case 4:
3815
3816                  switch (t.charAt(0)) {
3817                     case '1':
3818                        sx = "9" + t.substring(1, 4);
3819
3820                        break;
3821
3822                     case '2':
3823                        sx = "a" + t.substring(1, 4);
3824
3825                        break;
3826
3827                     case '3':
3828                        sx = "b" + t.substring(1, 4);
3829
3830                        break;
3831
3832                     case '4':
3833                        sx = "c" + t.substring(1, 4);
3834
3835                        break;
3836
3837                     case '5':
3838                        sx = "d" + t.substring(1, 4);
3839
3840                        break;
3841
3842                     case '6':
3843                        sx = "e" + t.substring(1, 4);
3844
3845                        break;
3846
3847                     case '7':
3848                        sx = "f" + t.substring(1, 4);
3849
3850                        break;
3851                  }
3852
3853                  break;
3854            }
3855         } else {
3856            sx = Integer.toString(x, 16);
3857         }
3858
3859         return printXFormat(sx);
3860      }
3861
3862
3863      /**
3864       * Format method for the x conversion character and long argument. For x
3865       * format, the flag character '-', means that the output should be left
3866       * justified within the field. The default is to pad with blanks on the
3867       * left. The '#' flag character means to lead with '0x'. The field
3868       * width is treated as the minimum number of characters to be printed.
3869       * The default is to add no padding. Padding is with blanks by default.
3870       * The precision, if set, is the minimum number of digits to appear.
3871       * Padding is with leading 0s.
3872       *
3873       * @param x the long to format.
3874       *
3875       * @return the formatted String.
3876       */

3877      private String JavaDoc printXFormat(long x) {
3878         String JavaDoc sx = null;
3879
3880         if (x == Long.MIN_VALUE) {
3881            sx = "8000000000000000";
3882         } else if (x < 0) {
3883            String JavaDoc t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE, 16);
3884
3885            switch (t.length()) {
3886               case 1:
3887                  sx = "800000000000000" + t;
3888
3889                  break;
3890
3891               case 2:
3892                  sx = "80000000000000" + t;
3893
3894                  break;
3895
3896               case 3:
3897                  sx = "8000000000000" + t;
3898
3899                  break;
3900
3901               case 4:
3902                  sx = "800000000000" + t;
3903
3904                  break;
3905
3906               case 5:
3907                  sx = "80000000000" + t;
3908
3909                  break;
3910
3911               case 6:
3912                  sx = "8000000000" + t;
3913
3914                  break;
3915
3916               case 7:
3917                  sx = "800000000" + t;
3918
3919                  break;
3920
3921               case 8:
3922                  sx = "80000000" + t;
3923
3924                  break;
3925
3926               case 9:
3927                  sx = "8000000" + t;
3928
3929                  break;
3930
3931               case 10:
3932                  sx = "800000" + t;
3933
3934                  break;
3935
3936               case 11:
3937                  sx = "80000" + t;
3938
3939                  break;
3940
3941               case 12:
3942                  sx = "8000" + t;
3943
3944                  break;
3945
3946               case 13:
3947                  sx = "800" + t;
3948
3949                  break;
3950
3951               case 14:
3952                  sx = "80" + t;
3953
3954                  break;
3955
3956               case 15:
3957                  sx = "8" + t;
3958
3959                  break;
3960
3961               case 16:
3962
3963                  switch (t.charAt(0)) {
3964                     case '1':
3965                        sx = "9" + t.substring(1, 16);
3966
3967                        break;
3968
3969                     case '2':
3970                        sx = "a" + t.substring(1, 16);
3971
3972                        break;
3973
3974                     case '3':
3975                        sx = "b" + t.substring(1, 16);
3976
3977                        break;
3978
3979                     case '4':
3980                        sx = "c" + t.substring(1, 16);
3981
3982                        break;
3983
3984                     case '5':
3985                        sx = "d" + t.substring(1, 16);
3986
3987                        break;
3988
3989                     case '6':
3990                        sx = "e" + t.substring(1, 16);
3991
3992                        break;
3993
3994                     case '7':
3995                        sx = "f" + t.substring(1, 16);
3996
3997                        break;
3998                  }
3999
4000                  break;
4001            }
4002         } else {
4003            sx = Long.toString(x, 16);
4004         }
4005
4006         return printXFormat(sx);
4007      }
4008
4009
4010      /**
4011       * Format method for the x conversion character and int argument. For x
4012       * format, the flag character '-', means that the output should be left
4013       * justified within the field. The default is to pad with blanks on the
4014       * left. The '#' flag character means to lead with '0x'. The field
4015       * width is treated as the minimum number of characters to be printed.
4016       * The default is to add no padding. Padding is with blanks by default.
4017       * The precision, if set, is the minimum number of digits to appear.
4018       * Padding is with leading 0s.
4019       *
4020       * @param x the int to format.
4021       *
4022       * @return the formatted String.
4023       */

4024      private String JavaDoc printXFormat(int x) {
4025         String JavaDoc sx = null;
4026
4027         if (x == Integer.MIN_VALUE) {
4028            sx = "80000000";
4029         } else if (x < 0) {
4030            String JavaDoc t = Integer.toString((~(-x - 1)) ^ Integer.MIN_VALUE, 16);
4031
4032            switch (t.length()) {
4033               case 1:
4034                  sx = "8000000" + t;
4035
4036                  break;
4037
4038               case 2:
4039                  sx = "800000" + t;
4040
4041                  break;
4042
4043               case 3:
4044                  sx = "80000" + t;
4045
4046                  break;
4047
4048               case 4:
4049                  sx = "8000" + t;
4050
4051                  break;
4052
4053               case 5:
4054                  sx = "800" + t;
4055
4056                  break;
4057
4058               case 6:
4059                  sx = "80" + t;
4060
4061                  break;
4062
4063               case 7:
4064                  sx = "8" + t;
4065
4066                  break;
4067
4068               case 8:
4069
4070                  switch (t.charAt(0)) {
4071                     case '1':
4072                        sx = "9" + t.substring(1, 8);
4073
4074                        break;
4075
4076                     case '2':
4077                        sx = "a" + t.substring(1, 8);
4078
4079                        break;
4080
4081                     case '3':
4082                        sx = "b" + t.substring(1, 8);
4083
4084                        break;
4085
4086                     case '4':
4087                        sx = "c" + t.substring(1, 8);
4088
4089                        break;
4090
4091                     case '5':
4092                        sx = "d" + t.substring(1, 8);
4093
4094                        break;
4095
4096                     case '6':
4097                        sx = "e" + t.substring(1, 8);
4098
4099                        break;
4100
4101                     case '7':
4102                        sx = "f" + t.substring(1, 8);
4103
4104                        break;
4105                  }
4106
4107                  break;
4108            }
4109         } else {
4110            sx = Integer.toString(x, 16);
4111         }
4112
4113         return printXFormat(sx);
4114      }
4115
4116
4117      /**
4118       * Utility method for formatting using the x conversion character.
4119       *
4120       * @param sx the String to format, the result of converting a short, int,
4121       * or long to a String.
4122       *
4123       * @return the formatted String.
4124       */

4125      private String JavaDoc printXFormat(String JavaDoc sx) {
4126         int nLeadingZeros = 0;
4127         int nBlanks = 0;
4128
4129         if (sx.equals("0") && precisionSet && (precision == 0)) {
4130            sx = "";
4131         }
4132
4133         if (precisionSet) {
4134            nLeadingZeros = precision - sx.length();
4135         }
4136
4137         if (nLeadingZeros < 0) {
4138            nLeadingZeros = 0;
4139         }
4140
4141         if (fieldWidthSet) {
4142            nBlanks = fieldWidth - nLeadingZeros - sx.length();
4143
4144            if (alternateForm) {
4145               nBlanks = nBlanks - 2;
4146            }
4147         }
4148
4149         if (nBlanks < 0) {
4150            nBlanks = 0;
4151         }
4152
4153         int n = 0;
4154
4155         if (alternateForm) {
4156            n += 2;
4157         }
4158
4159         n += nLeadingZeros;
4160         n += sx.length();
4161         n += nBlanks;
4162
4163         char[] ca = new char[n];
4164         int i = 0;
4165
4166         if (leftJustify) {
4167            if (alternateForm) {
4168               ca[i++] = '0';
4169               ca[i++] = 'x';
4170            }
4171
4172            for (int j = 0; j < nLeadingZeros; j++, i++)
4173               ca[i] = '0';
4174
4175            char[] csx = sx.toCharArray();
4176
4177            for (int j = 0; j < csx.length; j++, i++)
4178               ca[i] = csx[j];
4179
4180            for (int j = 0; j < nBlanks; j++, i++)
4181               ca[i] = ' ';
4182         } else {
4183            if (!leadingZeros) {
4184               for (int j = 0; j < nBlanks; j++, i++)
4185                  ca[i] = ' ';
4186            }
4187
4188            if (alternateForm) {
4189               ca[i++] = '0';
4190               ca[i++] = 'x';
4191            }
4192
4193            if (leadingZeros) {
4194               for (int j = 0; j < nBlanks; j++, i++)
4195                  ca[i] = '0';
4196            }
4197
4198            for (int j = 0; j < nLeadingZeros; j++, i++)
4199               ca[i] = '0';
4200
4201            char[] csx = sx.toCharArray();
4202
4203            for (int j = 0; j < csx.length; j++, i++)
4204               ca[i] = csx[j];
4205         }
4206
4207         String JavaDoc caReturn = new String JavaDoc(ca);
4208
4209         if (conversionCharacter == 'X') {
4210            caReturn = caReturn.toUpperCase();
4211         }
4212
4213         return caReturn;
4214      }
4215
4216
4217      /**
4218       * Start the symbolic carry process. The process is not quite finished
4219       * because the symbolic carry may change the length of the string and
4220       * change the exponent (in e format).
4221       *
4222       * @param ca DOCUMENT ME!
4223       * @param cLast index of the last digit changed by the round
4224       * @param cFirst index of the first digit allowed to be changed by this
4225       * phase of the round
4226       *
4227       * @return <code>true</code> if the carry forces a round that will change
4228       * the print still more
4229       */

4230      private boolean startSymbolicCarry(char[] ca,
4231                                         int cLast,
4232                                         int cFirst) {
4233         boolean carry = true;
4234
4235         for (int i = cLast; carry && (i >= cFirst); i--) {
4236            carry = false;
4237
4238            switch (ca[i]) {
4239               case '0':
4240                  ca[i] = '1';
4241
4242                  break;
4243
4244               case '1':
4245                  ca[i] = '2';
4246
4247                  break;
4248
4249               case '2':
4250                  ca[i] = '3';
4251
4252                  break;
4253
4254               case '3':
4255                  ca[i] = '4';
4256
4257                  break;
4258
4259               case '4':
4260                  ca[i] = '5';
4261
4262                  break;
4263
4264               case '5':
4265                  ca[i] = '6';
4266
4267                  break;
4268
4269               case '6':
4270                  ca[i] = '7';
4271
4272                  break;
4273
4274               case '7':
4275                  ca[i] = '8';
4276
4277                  break;
4278
4279               case '8':
4280                  ca[i] = '9';
4281
4282                  break;
4283
4284               case '9':
4285                  ca[i] = '0';
4286                  carry = true;
4287
4288                  break;
4289            }
4290         }
4291
4292         return carry;
4293      }
4294   }
4295}
4296
Popular Tags