KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jruby > util > PrintfFormat


1 /***** BEGIN LICENSE BLOCK *****
2  * Version: CPL 1.0/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Common Public
5  * License Version 1.0 (the "License"); you may not use this file
6  * except in compliance with the License. You may obtain a copy of
7  * the License at http://www.eclipse.org/legal/cpl-v10.html
8  *
9  * Software distributed under the License is distributed on an "AS
10  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11  * implied. See the License for the specific language governing
12  * rights and limitations under the License.
13  *
14  * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
15  * Copyright (C) 2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
16  * Copyright (C) 2002 Jan Arne Petersen <jpetersen@uni-bonn.de>
17  * Copyright (C) 2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
18  * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
19  * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
20  * Copyright (C) 2005 Derek Berner <derek.berner@state.nm.us>
21  * Copyright (C) 2007 Ola Bini <ola@ologix.com>
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either of the GNU General Public License Version 2 or later (the "GPL"),
25  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the CPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the CPL, the GPL or the LGPL.
34  ***** END LICENSE BLOCK *****/

35 package org.jruby.util;
36
37 import java.math.BigInteger JavaDoc;
38 import java.text.DecimalFormatSymbols JavaDoc;
39 import java.util.Enumeration JavaDoc;
40 import java.util.Locale JavaDoc;
41 import java.util.Vector JavaDoc;
42
43 import org.jruby.RubyBignum;
44 import org.jruby.RubyFixnum;
45 import org.jruby.RubyNumeric;
46 import org.jruby.RubyString;
47 import org.jruby.runtime.builtin.IRubyObject;
48
49 /**
50  * PrintfFormat is a Java implementation of the <code>sprintf</code>
51  * utility. To use it, you pass the string containing the format
52  * specifier(s) to the constructor, then call the appropriate form of
53  * the <code>sprintf</code> method. To pass more than one argument,
54  * convert any primitives to their wrapper types and place all the
55  * arguments in an array of type <code>Object</code>.
56  *<p>
57  * PrintfFormat supports all the standard flags (<code>[-+ #0]</code>),
58  * as well as the <code>'</code> (apostrophe) flag, which causes decimal
59  * integers to be grouped in a locale-dependent way (e.g, in English
60  * locales, groups of three digits separated by commas). The integer
61  * modifiers (<code>[hlL]</code>) are also accepted, but the "L" modifier
62  * is ignored as superfluous. Finally, all the standard conversion-type
63  * characters (<code>[idfgGoxXeEcsp]</code>) are supported, except for "n".
64  *<p>
65  * In addition, PrintfFormat supports positional syntax for arguments,
66  * field widths, and precisions. A format specifier that starts with
67  * a "%<i>n</i>$" sequence will be applied to the <i>n</i>th argument.
68  * A field width or precision of the form "*<i>m</i>$" will take its
69  * value from the <i>m</i>th argument. The standard variable specifier
70  * for field width and precision (<code>*</code>), which takes its value
71  * from the next argument, is also supported. However, if a variable
72  * field width or precision is encountered in a format spec that starts
73  * with a positional argument spec, the "*" will be ignored and the
74  * default value will be used instead.
75  *
76  * @author Allan Jacobs
77  * Release 1: Initial release.
78  * Release 2: Asterisk field widths and precisions
79  * %n$ and *m$
80  * Bug fixes
81  * g format fix (2 digits in e form corrupt)
82  * rounding in f format implemented
83  * round up when digit not printed is 5
84  * formatting of -0.0f
85  * round up/down when last digits are 50000...
86  */

87 public class PrintfFormat {
88     /**
89      * Constructs an array of control specifications
90      * possibly preceded, separated, or followed by
91      * ordinary strings.
92      *
93      * @param fmtArg Control string.
94      * @exception IllegalArgumentException if the control
95      * string is null, zero length, or otherwise
96      * malformed.
97      */

98     public PrintfFormat(String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
99         this(Locale.getDefault(), fmtArg);
100     }
101
102     /**
103      * Constructs an array of control specifications
104      * possibly preceded, separated, or followed by
105      * ordinary strings.
106      *
107      * @param fmtArg Control string.
108      * @exception IllegalArgumentException if the control
109      * string is null, zero length, or otherwise malformed.
110      */

111     public PrintfFormat(Locale JavaDoc locale, String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
112         dfs = new DecimalFormatSymbols JavaDoc(locale);
113         int ePos = 0;
114         ConversionSpecification sFmt = null;
115         String JavaDoc unCS = this.nonControl(fmtArg, 0);
116         if (unCS != null) {
117             sFmt = new ConversionSpecification();
118             sFmt.setLiteral(unCS);
119             vFmt.addElement(sFmt);
120         }
121         while (cPos != -1 && cPos < fmtArg.length()) {
122             for (ePos = cPos + 1; ePos < fmtArg.length(); ePos++) {
123                 char c = 0;
124                 c = fmtArg.charAt(ePos);
125                 if ("idfgGoxXeEcsbp%".indexOf(c) != -1) {
126                     break;
127                 }
128             }
129             ePos = Math.min(ePos + 1, fmtArg.length());
130             sFmt = new ConversionSpecification(fmtArg.substring(cPos, ePos));
131             vFmt.addElement(sFmt);
132             unCS = this.nonControl(fmtArg, ePos);
133             if (unCS != null) {
134                 sFmt = new ConversionSpecification();
135                 sFmt.setLiteral(unCS);
136                 vFmt.addElement(sFmt);
137             }
138         }
139     }
140
141     private String JavaDoc nonControl(String JavaDoc s, int start) {
142         cPos = s.indexOf("%", start);
143         if (cPos == -1) {
144             cPos = s.length();
145         }
146         return s.substring(start, cPos);
147     }
148
149     /**
150      * Format an array of objects. Byte, Short,
151      * Integer, Long, Float, Double, and Character
152      * arguments are treated as wrappers for primitive
153      * types.
154      *
155      * @param o The array of objects to format.
156      * @param ro The unformatted Ruby objects. If this is null, %p and friends will not work.
157      * @return The formatted String.
158      */

159     public String JavaDoc sprintf(Object JavaDoc[] o, IRubyObject[] ro) {
160         Enumeration JavaDoc e = vFmt.elements();
161         ConversionSpecification cs = null;
162         char c = 0;
163         int i = 0;
164         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
165         while (e.hasMoreElements()) {
166             cs = (ConversionSpecification) e.nextElement();
167             c = cs.getConversionCharacter();
168             if (c == '\0') {
169                 sb.append(cs.getLiteral());
170             } else if (c == '%') {
171                 sb.append("%");
172             } else {
173                 if (cs.isPositionalSpecification()) {
174                     i = cs.getArgumentPosition() - 1;
175                 }
176
177                 if (cs.isPositionalFieldWidth()) {
178                     int ifw = cs.getArgumentPositionForFieldWidth() - 1;
179                     cs.setFieldWidthWithArg(((Number JavaDoc) o[ifw]).intValue());
180                 } else if (cs.isVariableFieldWidth() && !cs.isPositionalSpecification()) {
181                     cs.setFieldWidthWithArg(((Number JavaDoc) o[i]).intValue());
182                     i++;
183                 }
184
185                 if (cs.isPositionalPrecision()) {
186                     int ipr = cs.getArgumentPositionForPrecision() - 1;
187                     cs.setPrecisionWithArg(((Number JavaDoc) o[ipr]).intValue());
188                 } else if (cs.isVariablePrecision() && !cs.isPositionalSpecification()) {
189                     cs.setPrecisionWithArg(((Number JavaDoc) o[i]).intValue());
190                     i++;
191                 }
192
193                 if (o[i] == null) {
194                     // total hack for 0.9.8 Rails compliance
195
// this program must die, and soon
196
switch(c) {
197                     case 'c':
198                         throw ro[i].getRuntime().newTypeError("no implicit conversion from nil to integer");
199                     case 'e':
200                     case 'E':
201                     case 'f':
202                     case 'g':
203                     case 'G':
204                         throw ro[i].getRuntime().newTypeError("can't convert nil into Float");
205                     case 'b':
206                     case 'B':
207                     case 'd':
208                     case 'i':
209                     case 'u':
210                     case 'x':
211                     case 'X':
212                         sb.append(cs.internalsprintf(0L));
213                         break;
214                     case 's':
215                         sb.append(cs.internalsprintf(""));
216                         break;
217                     case 'p':
218                         sb.append(cs.internalsprintf("nil"));
219                         break;
220                     }
221                 } else if (c == 'p' || c == 'P') {
222                     sb.append(cs.internalsprintf(ro[i].callMethod(ro[i].getRuntime().getCurrentContext(),"inspect").objAsString().toString()));
223                 } else if (c == 'c' || c == 'C') {
224                     sb.append(cs.internalsprintf(RubyNumeric.num2long(ro[i].convertToInteger())));
225                 } else if (c == 'b' || c == 'B') {
226                     if(ro[i] instanceof RubyString) {
227                         sb.append(cs.internalsprintf(RubyNumeric.num2long(RubyNumeric.str2inum(ro[i].getRuntime(),(RubyString)ro[i],0,true))));
228                     } else {
229                         IRubyObject num = ro[i].convertToInteger();
230                         if(num instanceof RubyFixnum) {
231                             sb.append(cs.internalsprintf(RubyNumeric.fix2long(num)));
232                         } else if(num instanceof RubyBignum) {
233                             sb.append(cs.internalsprintf(((RubyBignum)num).getValue()));
234                         } else {
235                             sb.append(cs.internalsprintf(RubyNumeric.num2long(num)));
236                         }
237                     }
238                 } else if (o[i] instanceof Byte JavaDoc) {
239                     sb.append(cs.internalsprintf(((Byte JavaDoc) o[i]).byteValue()));
240                 } else if (o[i] instanceof Short JavaDoc) {
241                     sb.append(cs.internalsprintf(((Short JavaDoc) o[i]).shortValue()));
242                 } else if (o[i] instanceof Integer JavaDoc) {
243                     sb.append(cs.internalsprintf(((Integer JavaDoc) o[i]).intValue()));
244                 } else if (o[i] instanceof Long JavaDoc) {
245                     sb.append(cs.internalsprintf(((Long JavaDoc) o[i]).longValue()));
246                 } else if (o[i] instanceof Float JavaDoc) {
247                     sb.append(cs.internalsprintf(((Float JavaDoc) o[i]).floatValue()));
248                 } else if (o[i] instanceof Double JavaDoc) {
249                     sb.append(cs.internalsprintf(((Double JavaDoc) o[i]).doubleValue()));
250                 } else if (o[i] instanceof Character JavaDoc) {
251                     sb.append(cs.internalsprintf(((Character JavaDoc) o[i]).charValue()));
252                 } else if (o[i] instanceof String JavaDoc) {
253                     sb.append(cs.internalsprintf((String JavaDoc) o[i]));
254                 } else {
255                     sb.append(cs.internalsprintf(o[i]));
256                 }
257                 i++;
258             }
259         }
260         return sb.toString();
261     }
262
263     /**
264      * Format nothing. Just use the control string.
265      *
266      * @return the formatted String.
267      */

268     public String JavaDoc sprintf() {
269         Enumeration JavaDoc e = vFmt.elements();
270         ConversionSpecification cs = null;
271         char c = 0;
272         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
273         while (e.hasMoreElements()) {
274             cs = (ConversionSpecification) e.nextElement();
275             c = cs.getConversionCharacter();
276             if (c == '\0') {
277                 sb.append(cs.getLiteral());
278             } else if (c == '%') {
279                 sb.append("%");
280             }
281         }
282         return sb.toString();
283     }
284
285     /**
286      * Format an int.
287      *
288      * @param x The int to format.
289      * @return The formatted String.
290      * @exception IllegalArgumentException if the
291      * conversion character is f, e, E, g, G, s,
292      * or S.
293      */

294     public String JavaDoc sprintf(int x) throws IllegalArgumentException JavaDoc {
295         Enumeration JavaDoc e = vFmt.elements();
296         ConversionSpecification cs = null;
297         char c = 0;
298         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
299         while (e.hasMoreElements()) {
300             cs = (ConversionSpecification) e.nextElement();
301             c = cs.getConversionCharacter();
302             if (c == '\0') {
303                 sb.append(cs.getLiteral());
304             } else if (c == '%') {
305                 sb.append("%");
306             } else {
307                 sb.append(cs.internalsprintf(x));
308             }
309         }
310         return sb.toString();
311     }
312
313     /**
314      * Format a long.
315      *
316      * @param x The long to format.
317      * @return The formatted String.
318      * @exception IllegalArgumentException if the
319      * conversion character is f, e, E, g, G, s,
320      * or S.
321      */

322     public String JavaDoc sprintf(long x) throws IllegalArgumentException JavaDoc {
323         Enumeration JavaDoc e = vFmt.elements();
324         ConversionSpecification cs = null;
325         char c = 0;
326         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
327         while (e.hasMoreElements()) {
328             cs = (ConversionSpecification) e.nextElement();
329             c = cs.getConversionCharacter();
330             if (c == '\0') {
331                 sb.append(cs.getLiteral());
332             } else if (c == '%') {
333                 sb.append("%");
334             } else {
335                 sb.append(cs.internalsprintf(x));
336             }
337         }
338         return sb.toString();
339     }
340
341     /**
342      * Format a double.
343      *
344      * @param x The double to format.
345      * @return The formatted String.
346      * @exception IllegalArgumentException if the
347      * conversion character is c, C, s, S,
348      * d, d, x, X, or o.
349      */

350     public String JavaDoc sprintf(double x) throws IllegalArgumentException JavaDoc {
351         Enumeration JavaDoc e = vFmt.elements();
352         ConversionSpecification cs = null;
353         char c = 0;
354         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
355         while (e.hasMoreElements()) {
356             cs = (ConversionSpecification) e.nextElement();
357             c = cs.getConversionCharacter();
358             if (c == '\0') {
359                 sb.append(cs.getLiteral());
360             } else if (c == '%') {
361                 sb.append("%");
362             } else {
363                 sb.append(cs.internalsprintf(x));
364             }
365         }
366         return sb.toString();
367     }
368
369     /**
370      * Format a String.
371      *
372      * @param x The String to format.
373      * @return The formatted String.
374      * @exception IllegalArgumentException if the
375      * conversion character is neither s nor S.
376      */

377     public String JavaDoc sprintf(String JavaDoc x) throws IllegalArgumentException JavaDoc {
378         Enumeration JavaDoc e = vFmt.elements();
379         ConversionSpecification cs = null;
380         char c = 0;
381         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
382         while (e.hasMoreElements()) {
383             cs = (ConversionSpecification) e.nextElement();
384             c = cs.getConversionCharacter();
385             if (c == '\0') {
386                 sb.append(cs.getLiteral());
387             } else if (c == '%') {
388                 sb.append("%");
389             } else {
390                 sb.append(cs.internalsprintf(x));
391             }
392         }
393         return sb.toString();
394     }
395
396     /**
397      * Format an Object. Convert wrapper types to
398      * their primitive equivalents and call the
399      * appropriate internal formatting method. Convert
400      * Strings using an internal formatting method for
401      * Strings. Otherwise use the default formatter
402      * (use toString).
403      *
404      * @param x the Object to format.
405      * @return the formatted String.
406      * @exception IllegalArgumentException if the
407      * conversion character is inappropriate for
408      * formatting an unwrapped value.
409      */

410     public String JavaDoc sprintf(Object JavaDoc x) throws IllegalArgumentException JavaDoc {
411         Enumeration JavaDoc e = vFmt.elements();
412         ConversionSpecification cs = null;
413         char c = 0;
414         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
415         while (e.hasMoreElements()) {
416             cs = (ConversionSpecification) e.nextElement();
417             c = cs.getConversionCharacter();
418             if (c == '\0') {
419                 sb.append(cs.getLiteral());
420             } else if (c == '%') {
421                 sb.append("%");
422             } else {
423                 if (x instanceof Byte JavaDoc) {
424                     sb.append(cs.internalsprintf(((Byte JavaDoc) x).byteValue()));
425                 } else if (x instanceof Short JavaDoc) {
426                     sb.append(cs.internalsprintf(((Short JavaDoc) x).shortValue()));
427                 } else if (x instanceof Integer JavaDoc) {
428                     sb.append(cs.internalsprintf(((Integer JavaDoc) x).intValue()));
429                 } else if (x instanceof Long JavaDoc) {
430                     sb.append(cs.internalsprintf(((Long JavaDoc) x).longValue()));
431                 } else if (x instanceof Float JavaDoc) {
432                     sb.append(cs.internalsprintf(((Float JavaDoc) x).floatValue()));
433                 } else if (x instanceof Double JavaDoc) {
434                     sb.append(cs.internalsprintf(((Double JavaDoc) x).doubleValue()));
435                 } else if (x instanceof Character JavaDoc) {
436                     sb.append(cs.internalsprintf(((Character JavaDoc) x).charValue()));
437                 } else if (x instanceof String JavaDoc) {
438                     sb.append(cs.internalsprintf((String JavaDoc) x));
439                 } else {
440                     sb.append(cs.internalsprintf(x));
441                 }
442             }
443         }
444         return sb.toString();
445     }
446
447     /**
448      *<p>
449      * ConversionSpecification allows the formatting of
450      * a single primitive or object embedded within a
451      * string. The formatting is controlled by a
452      * format string. Only one Java primitive or
453      * object can be formatted at a time.
454      *<p>
455      * The behavior is like printf. One (hopefully the
456      * only) exception is that the minimum number of
457      * exponent digits is 3 instead of 2 for e and E
458      * formats when the optional L is used before the
459      * e, E, g, or G conversion character. The
460      * optional L does not imply conversion to a long
461      * long double.
462      */

463     private class ConversionSpecification {
464         /**
465          * Constructor. Used to prepare an instance
466          * to hold a literal, not a control string.
467          */

468         ConversionSpecification() {
469         }
470
471         /**
472          * Constructor for a conversion specification.
473          * The argument must begin with a % and end
474          * with the conversion character for the
475          * conversion specification.
476          *
477          * @param fmtArg String specifying the
478          * conversion specification.
479          * @exception IllegalArgumentException if the
480          * input string is null, zero length, or
481          * otherwise malformed.
482          */

483         ConversionSpecification(String JavaDoc fmtArg) throws IllegalArgumentException JavaDoc {
484             if (fmtArg == null) {
485                 throw new NullPointerException JavaDoc();
486             }
487             if (fmtArg.length() == 0) {
488                 throw new IllegalArgumentException JavaDoc("Control strings must have positive lengths.");
489             }
490             if (fmtArg.charAt(0) == '%') {
491                 fmt = fmtArg;
492                 pos = 1;
493                 setArgPosition();
494                 setFlagCharacters();
495                 setFieldWidth();
496                 setPrecision();
497                 setOptionalHL();
498                 if (setConversionCharacter()) {
499                     if (pos == fmtArg.length()) {
500                         if (leadingZeros && leftJustify) {
501                             leadingZeros = false;
502                         }
503                         if (precisionSet && leadingZeros) {
504                             if ("diox".indexOf(conversionCharacter) != -1) {
505                                 leadingZeros = false;
506                             }
507                         }
508                     } else {
509                         throw new IllegalArgumentException JavaDoc("Malformed conversion specification=" + fmtArg);
510                     }
511                 } else {
512                     throw new IllegalArgumentException JavaDoc("Malformed conversion specification=" + fmtArg);
513                 }
514             } else {
515                 throw new IllegalArgumentException JavaDoc("Control strings must begin with %.");
516             }
517         }
518
519         void setLiteral(String JavaDoc s) {
520             fmt = s;
521         }
522
523         String JavaDoc getLiteral() {
524             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
525             int i = 0;
526             while (i < fmt.length()) {
527                 if (fmt.charAt(i) == '\\') {
528                     i++;
529                     if (i < fmt.length()) {
530                         char c = fmt.charAt(i);
531                         switch (c) {
532                             case 'a' :
533                                 sb.append((char) 0x07);
534                                 break;
535                             case 'b' :
536                                 sb.append('\b');
537                                 break;
538                             case 'f' :
539                                 sb.append('\f');
540                                 break;
541                             case 'n' :
542                                 sb.append('\n');
543                                 break;
544                             case 'r' :
545                                 sb.append('\r');
546                                 break;
547                             case 't' :
548                                 sb.append('\t');
549                                 break;
550                             case 'v' :
551                                 sb.append((char) 0x0b);
552                                 break;
553                             case '\\' :
554                                 sb.append('\\');
555                                 break;
556                         }
557                         i++;
558                     } else {
559                         sb.append('\\');
560                     }
561                 } else {
562                     i++;
563                 }
564             }
565             return fmt;
566         }
567
568         char getConversionCharacter() {
569             return conversionCharacter;
570         }
571
572         boolean isVariableFieldWidth() {
573             return variableFieldWidth;
574         }
575
576         void setFieldWidthWithArg(int fw) {
577             if (fw < 0) {
578                 leftJustify = true;
579             }
580             fieldWidthSet = true;
581             fieldWidth = Math.abs(fw);
582         }
583
584         boolean isVariablePrecision() {
585             return variablePrecision;
586         }
587
588         void setPrecisionWithArg(int pr) {
589             precisionSet = true;
590             precision = Math.max(pr, 0);
591         }
592
593         String JavaDoc internalsprintf(int s) throws IllegalArgumentException JavaDoc {
594             String JavaDoc s2 = "";
595             switch (conversionCharacter) {
596                 case 'd' :
597                 case 'i' :
598                     if (optionalh) {
599                         s2 = printDFormat((short) s);
600                     } else if (optionall) {
601                         s2 = printDFormat((long) s);
602                     } else {
603                         s2 = printDFormat(s);
604                     }
605                     break;
606                 case 'x' :
607                 case 'X' :
608                     if (optionalh) {
609                         s2 = printXFormat((short) s);
610                     } else if (optionall) {
611                         s2 = printXFormat((long) s);
612                     } else {
613                         s2 = printXFormat(s);
614                     }
615                     break;
616                 case 'o' :
617                     if (optionalh) {
618                         s2 = printOFormat((short) s);
619                     } else if (optionall) {
620                         s2 = printOFormat((long) s);
621                     } else {
622                         s2 = printOFormat(s);
623                     }
624                     break;
625                 case 'c' :
626                 case 'C' :
627                     s2 = printCFormat((char) s);
628                     break;
629                 case 's':
630                 case 'S':
631                     s2 = printSFormat(String.valueOf(s));
632                     break;
633                 default :
634                     throw new IllegalArgumentException JavaDoc("Cannot format a int with a format using a " + conversionCharacter + " conversion character.");
635             }
636             return s2;
637         }
638
639         String JavaDoc internalsprintf(long s) throws IllegalArgumentException JavaDoc {
640             String JavaDoc s2 = "";
641             switch (conversionCharacter) {
642                 case 'd' :
643                 case 'i' :
644                     if (optionalh) {
645                         s2 = printDFormat((short) s);
646                     } else if (optionall) {
647                         s2 = printDFormat(s);
648                     } else {
649                         s2 = printDFormat((int) s);
650                     }
651                     break;
652                 case 'x' :
653                 case 'X' :
654                     if (optionalh) {
655                         s2 = printXFormat((short) s);
656                     } else if (optionall) {
657                         s2 = printXFormat(s);
658                     } else {
659                         s2 = printXFormat((int) s);
660                     }
661                     break;
662                 case 'o' :
663                     if (optionalh) {
664                         s2 = printOFormat((short) s);
665                     } else if (optionall) {
666                         s2 = printOFormat(s);
667                     } else {
668                         s2 = printOFormat((int) s);
669                     }
670                     break;
671                 case 'c' :
672                 case 'C' :
673                     s2 = printCFormat((char) s);
674                     break;
675                 case 's' :
676                 case 'S' :
677                     s2 = printSFormat(String.valueOf(s));
678                     break;
679                 case 'b' :
680                     s2 = printBFormat(s);
681                     break;
682                 case 'f' :
683                     s2 = printFFormat(s);
684                     break;
685                 case 'E' :
686                 case 'e' :
687                     s2 = printEFormat(s);
688                     break;
689                 case 'G' :
690                 case 'g' :
691                     s2 = printGFormat(s);
692                     break;
693                 default :
694                     throw new IllegalArgumentException JavaDoc("Cannot format a long with a format using a " + conversionCharacter + " conversion character.");
695             }
696             return s2;
697         }
698
699         String JavaDoc internalsprintf(BigInteger JavaDoc s) throws IllegalArgumentException JavaDoc {
700             String JavaDoc s2 = "";
701             switch (conversionCharacter) {
702                 case 'd' :
703                 case 'i' :
704                     s2 = printDFormat(s);
705                     break;
706                 case 'x' :
707                 case 'X' :
708                     s2 = printXFormat(s);
709                     break;
710                 case 'o' :
711                     s2 = printOFormat(s);
712                     break;
713                 case 's' :
714                 case 'S' :
715                     s2 = printSFormat(s.toString());
716                     break;
717                 case 'b' :
718                     s2 = printBFormat(s);
719                     break;
720                 case 'f' :
721                     s2 = printFFormat(s);
722                     break;
723                 case 'E' :
724                 case 'e' :
725                     s2 = printEFormat(s);
726                     break;
727                 case 'G' :
728                 case 'g' :
729                     s2 = printGFormat(s);
730                     break;
731                 default :
732                     throw new IllegalArgumentException JavaDoc("Cannot format a BigInteger with a format using a " + conversionCharacter + " conversion character.");
733             }
734             return s2;
735         }
736
737         String JavaDoc internalsprintf(double s) throws IllegalArgumentException JavaDoc {
738             String JavaDoc s2 = "";
739             switch (conversionCharacter) {
740                 case 'f' :
741                     s2 = printFFormat(s);
742                     break;
743                 case 'E' :
744                 case 'e' :
745                     s2 = printEFormat(s);
746                     break;
747                 case 'G' :
748                 case 'g' :
749                     s2 = printGFormat(s);
750                     break;
751                 case 's':
752                 case 'S':
753                     s2 = printSFormat(String.valueOf(s));
754                     break;
755                 case 'd':
756                 case 'D':
757                 case 'i':
758                 case 'I':
759                     s2 = printDFormat((long)s);
760                     break;
761                 case 'c':
762                 case 'C':
763                     s2 = printCFormat((char)s);
764                     break;
765                 default :
766                     throw new IllegalArgumentException JavaDoc("Cannot format a double with a format using a " + conversionCharacter + " conversion character.");
767             }
768             return s2;
769         }
770
771         String JavaDoc internalsprintf(String JavaDoc s) throws IllegalArgumentException JavaDoc {
772             String JavaDoc s2 = "";
773             switch (conversionCharacter) {
774                 case 's':
775                 case 'S':
776                 case 'p':
777                 case 'P':
778                     s2 = printSFormat(s);
779                     break;
780                 case 'f':
781                     s2 = printFFormat(Double.parseDouble(s));
782                     break;
783                 case 'G' :
784                 case 'g' :
785                     s2 = printGFormat(Double.parseDouble(s));
786                     break;
787                 case 'd':
788                 case 'D':
789                     s2 = printDFormat(s);
790                     break;
791                 default:
792                     throw new IllegalArgumentException JavaDoc("Cannot format a String with a format using a " + conversionCharacter + " conversion character.");
793             }
794             return s2;
795         }
796
797         String JavaDoc internalsprintf(Object JavaDoc s) {
798             String JavaDoc s2 = "";
799             if (conversionCharacter == 's' || conversionCharacter == 'S') {
800                 s2 = printSFormat(s == null ? "" : s.toString());
801             } else {
802                 throw new IllegalArgumentException JavaDoc("Cannot format a String with a format using a " + conversionCharacter + " conversion character.");
803             }
804             return s2;
805         }
806
807         /*
808         private void incrementAndCarry(char[] arr, int index) {
809             if(arr[index] == '9') {
810                 arr[index] = '0';
811                 if(index == 0) {
812                     System.err.println("WARNING, carry on string that won't support this. Check code in PrintfFormat.");
813                 } else {
814                     incrementAndCarry(arr, index-1);
815                 }
816             } else {
817                 arr[index] += 1;
818             }
819         }*/

820
821         private char[] fFormatDigits(double x) {
822             // int defaultDigits=6;
823
String JavaDoc sx;
824             // int defaultDigits=6;
825
int i;
826             int j;
827             int k;
828             int n1In;
829             int n2In;
830             int expon = 0;
831             boolean minusSign = false;
832             if (x > 0.0) {
833                 sx = Double.toString(x);
834             } else if (x < 0.0) {
835                 sx = Double.toString(-x);
836                 minusSign = true;
837             } else {
838                 sx = Double.toString(x);
839                 if (sx.charAt(0) == '-') {
840                     minusSign = true;
841                     sx = sx.substring(1);
842                 }
843             }
844             int ePos = sx.indexOf('E');
845             int rPos = sx.indexOf('.');
846             if (rPos != -1) {
847                 n1In = rPos;
848             } else if (ePos != -1) {
849                 n1In = ePos;
850             } else {
851                 n1In = sx.length();
852             }
853             if (rPos != -1) {
854                 if (ePos != -1) {
855                     n2In = ePos - rPos - 1;
856                 } else {
857                     n2In = sx.length() - rPos - 1;
858                 }
859             } else {
860                 n2In = 0;
861             }
862
863             if (ePos != -1) {
864                 int ie = ePos + 1;
865                 expon = 0;
866                 if (sx.charAt(ie) == '-') {
867                     for (++ie; ie < sx.length(); ie++) {
868                         if (sx.charAt(ie) != '0') {
869                             break;
870                         }
871                     }
872                     if (ie < sx.length()) {
873                         expon = -Integer.parseInt(sx.substring(ie));
874                     }
875                 } else {
876                     if (sx.charAt(ie) == '+') {
877                         ++ie;
878                     }
879                     for (; ie < sx.length(); ie++) {
880                         if (sx.charAt(ie) != '0') {
881                             break;
882                         }
883                     }
884                     if (ie < sx.length()) {
885                         expon = Integer.parseInt(sx.substring(ie));
886                     }
887                 }
888             }
889             int p;
890             if (precisionSet) {
891                 p = precision;
892             } else {
893                 p = defaultDigits - 1;
894             }
895
896             char[] ca1 = sx.toCharArray();
897             char[] ca2 = new char[n1In + n2In];
898             char[] ca3;
899             char[] ca4;
900             char[] ca5;
901             for (j = 0; j < n1In; j++) {
902                 ca2[j] = ca1[j];
903             }
904             i = j + 1;
905             for (k = 0; k < n2In; j++, i++, k++) {
906                 ca2[j] = ca1[i];
907             }
908             if (n1In + expon <= 0) {
909                 ca3 = new char[-expon + n2In];
910                 for (j = 0, k = 0; k < -n1In - expon; k++, j++) {
911                     ca3[j] = '0';
912                 }
913                 for (i = 0; i < n1In + n2In; i++, j++) {
914                     ca3[j] = ca2[i];
915                 }
916             } else {
917                 ca3 = ca2;
918             }
919             boolean carry = false;
920             if (p < -expon + n2In) {
921                 if (expon < 0) {
922                     i = p;
923                 } else {
924                     i = p + n1In + expon;
925                 }
926                 carry = checkForCarry(ca3, i);
927                 if (carry) {
928                     carry = startSymbolicCarry(ca3, i - 1, 0);
929                 }
930             }
931             if (n1In + expon <= 0) {
932                 ca4 = new char[2 + p];
933                 if (!carry) {
934                     ca4[0] = '0';
935                 } else {
936                     ca4[0] = '1';
937                 }
938                 if (alternateForm || !precisionSet || precision != 0) {
939                     ca4[1] = '.';
940                     for (i = 0, j = 2; i < Math.min(p, ca3.length); i++, j++) {
941                         ca4[j] = ca3[i];
942                     }
943                     for (; j < ca4.length; j++) {
944                         ca4[j] = '0';
945                     }
946                 }
947             } else {
948                 if (!carry) {
949                     if (alternateForm || !precisionSet || precision != 0) {
950                         ca4 = new char[n1In + expon + p + 1];
951                     } else {
952                         ca4 = new char[n1In + expon];
953                     }
954                     j = 0;
955                 } else {
956                     if (alternateForm || !precisionSet || precision != 0) {
957                         ca4 = new char[n1In + expon + p + 2];
958                     } else {
959                         ca4 = new char[n1In + expon + 1];
960                     }
961                     ca4[0] = '1';
962                     j = 1;
963                 }
964                 for (i = 0; i < Math.min(n1In + expon, ca3.length); i++, j++) {
965                     ca4[j] = ca3[i];
966                 }
967                 for (; i < n1In + expon; i++, j++) {
968                     ca4[j] = '0';
969                 }
970                 if (alternateForm || !precisionSet || precision != 0) {
971                     ca4[j] = '.';
972                     j++;
973                     for (k = 0; i < ca3.length && k < p; i++, j++, k++) {
974                         ca4[j] = ca3[i];
975                     }
976                     for (; j < ca4.length; j++) {
977                         ca4[j] = '0';
978                     }
979                 }
980             }
981             int nZeros = 0;
982             if (!leftJustify && leadingZeros) {
983                 int xThousands = 0;
984                 if (thousands) {
985                     int xlead = 0;
986                     if (ca4[0] == '+' || ca4[0] == '-' || ca4[0] == ' ') {
987                         xlead = 1;
988                     }
989                     int xdp = xlead;
990                     for (; xdp < ca4.length; xdp++) {
991                         if (ca4[xdp] == '.') {
992                             break;
993                         }
994                     }
995                     xThousands = (xdp - xlead) / 3;
996                 }
997                 if (fieldWidthSet) {
998                     nZeros = fieldWidth - ca4.length;
999                 }
1000                if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
1001                    nZeros--;
1002                }
1003                nZeros -= xThousands;
1004                if (nZeros < 0) {
1005                    nZeros = 0;
1006                }
1007            }
1008            j = 0;
1009            if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
1010                ca5 = new char[ca4.length + nZeros + 1];
1011                j++;
1012            } else {
1013                ca5 = new char[ca4.length + nZeros];
1014            }
1015            if (!minusSign) {
1016                if (leadingSign) {
1017                    ca5[0] = '+';
1018                }
1019                if (leadingSpace) {
1020                    ca5[0] = ' ';
1021                }
1022            } else {
1023                ca5[0] = '-';
1024            }
1025            for (i = 0; i < nZeros; i++, j++) {
1026                ca5[j] = '0';
1027            }
1028            for (i = 0; i < ca4.length; i++, j++) {
1029                ca5[j] = ca4[i];
1030            }
1031
1032            int lead = 0;
1033            if (ca5[0] == '+' || ca5[0] == '-' || ca5[0] == ' ') {
1034                lead = 1;
1035            }
1036            int dp = lead;
1037            for (; dp < ca5.length; dp++) {
1038                if (ca5[dp] == '.') {
1039                    break;
1040                }
1041            }
1042            int nThousands = (dp - lead) / 3;
1043            // Localize the decimal point.
1044
if (dp < ca5.length) {
1045                ca5[dp] = dfs.getDecimalSeparator();
1046            }
1047            char[] ca6 = ca5;
1048            if (thousands && nThousands > 0) {
1049                ca6 = new char[ca5.length + nThousands + lead];
1050                ca6[0] = ca5[0];
1051                for (i = lead, k = lead; i < dp; i++) {
1052                    if (i > 0 && (dp - i) % 3 == 0) {
1053                        // ca6[k]=',';
1054
ca6[k] = dfs.getGroupingSeparator();
1055                        ca6[k + 1] = ca5[i];
1056                        k += 2;
1057                    } else {
1058                        ca6[k] = ca5[i];
1059                        k++;
1060                    }
1061                }
1062                for (; i < ca5.length; i++, k++) {
1063                    ca6[k] = ca5[i];
1064                }
1065            }
1066            return ca6;
1067        }
1068
1069        private String JavaDoc fFormatString(double x) {
1070            char[] ca6;
1071            char[] ca7;
1072            if (Double.isInfinite(x)) {
1073                if (x == Double.POSITIVE_INFINITY) {
1074                    if (leadingSign) {
1075                        ca6 = "+Inf".toCharArray();
1076                    } else if (leadingSpace) {
1077                        ca6 = " Inf".toCharArray();
1078                    } else {
1079                        ca6 = "Inf".toCharArray();
1080                    }
1081                } else {
1082                    ca6 = "-Inf".toCharArray();
1083                }
1084            } else if (Double.isNaN(x)) {
1085                if (leadingSign) {
1086                    ca6 = "+NaN".toCharArray();
1087                } else if (leadingSpace) {
1088                    ca6 = " NaN".toCharArray();
1089                } else {
1090                    ca6 = "NaN".toCharArray();
1091                }
1092            } else {
1093                ca6 = fFormatDigits(x);
1094            }
1095            ca7 = applyFloatPadding(ca6, false);
1096            return new String JavaDoc(ca7);
1097        }
1098
1099        private char[] eFormatDigits(double x, char eChar) {
1100            char[] ca1, ca2, ca3;
1101            // int defaultDigits=6;
1102
String JavaDoc sx;
1103            // int defaultDigits=6;
1104
int i, j, k, p;
1105            int expon = 0;
1106            int ePos, rPos, eSize;
1107            boolean minusSign = false;
1108            if (x > 0.0) {
1109                sx = Double.toString(x);
1110            } else if (x < 0.0) {
1111                sx = Double.toString(-x);
1112                minusSign = true;
1113            } else {
1114                sx = Double.toString(x);
1115                if (sx.charAt(0) == '-') {
1116                    minusSign = true;
1117                    sx = sx.substring(1);
1118                }
1119            }
1120            ePos = sx.indexOf('E');
1121            if (ePos == -1) {
1122                ePos = sx.indexOf('e');
1123            }
1124            rPos = sx.indexOf('.');
1125            if (ePos != -1) {
1126                int ie = ePos + 1;
1127                expon = 0;
1128                if (sx.charAt(ie) == '-') {
1129                    for (++ie; ie < sx.length(); ie++) {
1130                        if (sx.charAt(ie) != '0') {
1131                            break;
1132                        }
1133                    }
1134                    if (ie < sx.length()) {
1135                        expon = -Integer.parseInt(sx.substring(ie));
1136                    }
1137                } else {
1138                    if (sx.charAt(ie) == '+') {
1139                        ++ie;
1140                    }
1141                    for (; ie < sx.length(); ie++) {
1142                        if (sx.charAt(ie) != '0') {
1143                            break;
1144                        }
1145                    }
1146                    if (ie < sx.length()) {
1147                        expon = Integer.parseInt(sx.substring(ie));
1148                    }
1149                }
1150            }
1151            if (rPos != -1) {
1152                expon += rPos - 1;
1153            }
1154            if (precisionSet) {
1155                p = precision;
1156            } else {
1157                p = defaultDigits - 1;
1158            }
1159            if (rPos != -1 && ePos != -1) {
1160                ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1, ePos)).toCharArray();
1161            } else if (rPos != -1) {
1162                ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1)).toCharArray();
1163            } else if (ePos != -1) {
1164                ca1 = sx.substring(0, ePos).toCharArray();
1165            } else {
1166                ca1 = sx.toCharArray();
1167            }
1168            boolean carry = false;
1169            int i0 = 0;
1170            if (ca1[0] != '0') {
1171                i0 = 0;
1172            } else {
1173                for (i0 = 0; i0 < ca1.length; i0++) {
1174                    if (ca1[i0] != '0') {
1175                        break;
1176                    }
1177                }
1178            }
1179            if (i0 + p < ca1.length - 1) {
1180                carry = checkForCarry(ca1, i0 + p + 1);
1181                if (carry) {
1182                    carry = startSymbolicCarry(ca1, i0 + p, i0);
1183                }
1184                if (carry) {
1185                    ca2 = new char[i0 + p + 1];
1186                    ca2[i0] = '1';
1187                    for (j = 0; j < i0; j++) {
1188                        ca2[j] = '0';
1189                    }
1190                    for (i = i0, j = i0 + 1; j < p + 1; i++, j++) {
1191                        ca2[j] = ca1[i];
1192                    }
1193                    expon++;
1194                    ca1 = ca2;
1195                }
1196            }
1197            if (Math.abs(expon) < 100 && !optionalL) {
1198                eSize = 4;
1199            } else {
1200                eSize = 5;
1201            }
1202            if (alternateForm || !precisionSet || precision != 0) {
1203                ca2 = new char[2 + p + eSize];
1204            } else {
1205                ca2 = new char[1 + eSize];
1206            }
1207            if (ca1[0] != '0') {
1208                ca2[0] = ca1[0];
1209                j = 1;
1210            } else {
1211                for (j = 1; j < (ePos == -1 ? ca1.length : ePos); j++) {
1212                    if (ca1[j] != '0') {
1213                        break;
1214                    }
1215                }
1216                if ((ePos != -1 && j < ePos) || (ePos == -1 && j < ca1.length)) {
1217                    ca2[0] = ca1[j];
1218                    expon -= j;
1219                    j++;
1220                } else {
1221                    ca2[0] = '0';
1222                    j = 2;
1223                }
1224            }
1225            if (alternateForm || !precisionSet || precision != 0) {
1226                ca2[1] = '.';
1227                i = 2;
1228            } else {
1229                i = 1;
1230            }
1231            for (k = 0; k < p && j < ca1.length; j++, i++, k++) {
1232                ca2[i] = ca1[j];
1233            }
1234            for (; i < ca2.length - eSize; i++) {
1235                ca2[i] = '0';
1236            }
1237            ca2[i++] = eChar;
1238            if (expon < 0) {
1239                ca2[i++] = '-';
1240            } else {
1241                ca2[i++] = '+';
1242            }
1243            expon = Math.abs(expon);
1244            if (expon >= 100) {
1245                switch (expon / 100) {
1246                    case 1 :
1247                        ca2[i] = '1';
1248                        break;
1249                    case 2 :
1250                        ca2[i] = '2';
1251                        break;
1252                    case 3 :
1253                        ca2[i] = '3';
1254                        break;
1255                    case 4 :
1256                        ca2[i] = '4';
1257                        break;
1258                    case 5 :
1259                        ca2[i] = '5';
1260                        break;
1261                    case 6 :
1262                        ca2[i] = '6';
1263                        break;
1264                    case 7 :
1265                        ca2[i] = '7';
1266                        break;
1267                    case 8 :
1268                        ca2[i] = '8';
1269                        break;
1270                    case 9 :
1271                        ca2[i] = '9';
1272                        break;
1273                }
1274                i++;
1275            }
1276            switch ((expon % 100) / 10) {
1277                case 0 :
1278                    ca2[i] = '0';
1279                    break;
1280                case 1 :
1281                    ca2[i] = '1';
1282                    break;
1283                case 2 :
1284                    ca2[i] = '2';
1285                    break;
1286                case 3 :
1287                    ca2[i] = '3';
1288                    break;
1289                case 4 :
1290                    ca2[i] = '4';
1291                    break;
1292                case 5 :
1293                    ca2[i] = '5';
1294                    break;
1295                case 6 :
1296                    ca2[i] = '6';
1297                    break;
1298                case 7 :
1299                    ca2[i] = '7';
1300                    break;
1301                case 8 :
1302                    ca2[i] = '8';
1303                    break;
1304                case 9 :
1305                    ca2[i] = '9';
1306                    break;
1307            }
1308            i++;
1309            switch (expon % 10) {
1310                case 0 :
1311                    ca2[i] = '0';
1312                    break;
1313                case 1 :
1314                    ca2[i] = '1';
1315                    break;
1316                case 2 :
1317                    ca2[i] = '2';
1318                    break;
1319                case 3 :
1320                    ca2[i] = '3';
1321                    break;
1322                case 4 :
1323                    ca2[i] = '4';
1324                    break;
1325                case 5 :
1326                    ca2[i] = '5';
1327                    break;
1328                case 6 :
1329                    ca2[i] = '6';
1330                    break;
1331                case 7 :
1332                    ca2[i] = '7';
1333                    break;
1334                case 8 :
1335                    ca2[i] = '8';
1336                    break;
1337                case 9 :
1338                    ca2[i] = '9';
1339                    break;
1340            }
1341            int nZeros = 0;
1342            if (!leftJustify && leadingZeros) {
1343                int xThousands = 0;
1344                if (thousands) {
1345                    int xlead = 0;
1346                    if (ca2[0] == '+' || ca2[0] == '-' || ca2[0] == ' ') {
1347                        xlead = 1;
1348                    }
1349                    int xdp = xlead;
1350                    for (; xdp < ca2.length; xdp++) {
1351                        if (ca2[xdp] == '.') {
1352                            break;
1353                        }
1354                    }
1355                    xThousands = (xdp - xlead) / 3;
1356                }
1357                if (fieldWidthSet) {
1358                    nZeros = fieldWidth - ca2.length;
1359                }
1360                if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
1361                    nZeros--;
1362                }
1363                nZeros -= xThousands;
1364                if (nZeros < 0) {
1365                    nZeros = 0;
1366                }
1367            }
1368            j = 0;
1369            if ((!minusSign && (leadingSign || leadingSpace)) || minusSign) {
1370                ca3 = new char[ca2.length + nZeros + 1];
1371                j++;
1372            } else {
1373                ca3 = new char[ca2.length + nZeros];
1374            }
1375            if (!minusSign) {
1376                if (leadingSign) {
1377                    ca3[0] = '+';
1378                }
1379                if (leadingSpace) {
1380                    ca3[0] = ' ';
1381                }
1382            } else {
1383                ca3[0] = '-';
1384            }
1385            for (k = 0; k < nZeros; j++, k++) {
1386                ca3[j] = '0';
1387            }
1388            for (i = 0; i < ca2.length && j < ca3.length; i++, j++) {
1389                ca3[j] = ca2[i];
1390            }
1391
1392            int lead = 0;
1393            if (ca3[0] == '+' || ca3[0] == '-' || ca3[0] == ' ') {
1394                lead = 1;
1395            }
1396            int dp = lead;
1397            for (; dp < ca3.length; dp++) {
1398                if (ca3[dp] == '.') {
1399                    break;
1400                }
1401            }
1402            int nThousands = dp / 3;
1403            // Localize the decimal point.
1404
if (dp < ca3.length) {
1405                ca3[dp] = dfs.getDecimalSeparator();
1406            }
1407            char[] ca4 = ca3;
1408            if (thousands && nThousands > 0) {
1409                ca4 = new char[ca3.length + nThousands + lead];
1410                ca4[0] = ca3[0];
1411                for (i = lead, k = lead; i < dp; i++) {
1412                    if (i > 0 && (dp - i) % 3 == 0) {
1413                        // ca4[k]=',';
1414
ca4[k] = dfs.getGroupingSeparator();
1415                        ca4[k + 1] = ca3[i];
1416                        k += 2;
1417                    } else {
1418                        ca4[k] = ca3[i];
1419                        k++;
1420                    }
1421                }
1422                for (; i < ca3.length; i++, k++) {
1423                    ca4[k] = ca3[i];
1424                }
1425            }
1426            return ca4;
1427        }
1428
1429        private boolean checkForCarry(char[] ca1, int icarry) {
1430            boolean carry = false;
1431            if (icarry < ca1.length) {
1432                if ("6789".indexOf(ca1[icarry]) != -1) {
1433                    carry = true;
1434                } else if (ca1[icarry] == '5') {
1435                    int ii = icarry + 1;
1436                    for (; ii < ca1.length; ii++) {
1437                        if (ca1[ii] != '0') {
1438                            break;
1439                        }
1440                    }
1441                    carry = ii < ca1.length;
1442                    if (!carry && icarry > 0) {
1443                        carry = "13579".indexOf(ca1[icarry - 1]) != -1;
1444                    }
1445                }
1446            }
1447            return carry;
1448        }
1449
1450        private boolean startSymbolicCarry(char[] ca, int cLast, int cFirst) {
1451            boolean carry = true;
1452            for (int i = cLast; carry && i >= cFirst; i--) {
1453                carry = false;
1454                if ("012345678".indexOf(ca[i]) != -1) {
1455                    ca[i]++;
1456                } else {
1457                    ca[i] = '0';
1458                    carry = true;
1459                }
1460            }
1461            return carry;
1462        }
1463
1464        private String JavaDoc eFormatString(double x, char eChar) {
1465            char[] ca4;
1466            char[] ca5;
1467            if (Double.isInfinite(x)) {
1468                if (x == Double.POSITIVE_INFINITY) {
1469                    if (leadingSign) {
1470                        ca4 = "+Inf".toCharArray();
1471                    } else if (leadingSpace) {
1472                        ca4 = " Inf".toCharArray();
1473                    } else {
1474                        ca4 = "Inf".toCharArray();
1475                    }
1476                } else {
1477                    ca4 = "-Inf".toCharArray();
1478                }
1479            } else if (Double.isNaN(x)) {
1480                if (leadingSign) {
1481                    ca4 = "+NaN".toCharArray();
1482                } else if (leadingSpace) {
1483                    ca4 = " NaN".toCharArray();
1484                } else {
1485                    ca4 = "NaN".toCharArray();
1486                }
1487            } else {
1488                ca4 = eFormatDigits(x, eChar);
1489            }
1490            ca5 = applyFloatPadding(ca4, false);
1491            return new String JavaDoc(ca5);
1492        }
1493
1494        private char[] applyFloatPadding(char[] ca4, boolean noDigits) {
1495            char[] ca5 = ca4;
1496            if (fieldWidthSet) {
1497                int i, j;
1498                int nBlanks;
1499                if (leftJustify) {
1500                    nBlanks = fieldWidth - ca4.length;
1501                    if (nBlanks > 0) {
1502                        ca5 = new char[ca4.length + nBlanks];
1503                        for (i = 0; i < ca4.length; i++) {
1504                            ca5[i] = ca4[i];
1505                        }
1506                        for (j = 0; j < nBlanks; j++, i++) {
1507                            ca5[i] = ' ';
1508                        }
1509                    }
1510                } else if (!leadingZeros || noDigits) {
1511                    nBlanks = fieldWidth - ca4.length;
1512                    if (nBlanks > 0) {
1513                        ca5 = new char[ca4.length + nBlanks];
1514                        for (i = 0; i < nBlanks; i++) {
1515                            ca5[i] = ' ';
1516                        }
1517                        for (j = 0; j < ca4.length; i++, j++) {
1518                            ca5[i] = ca4[j];
1519                        }
1520                    }
1521                } else if (leadingZeros) {
1522                    nBlanks = fieldWidth - ca4.length;
1523                    if (nBlanks > 0) {
1524                        ca5 = new char[ca4.length + nBlanks];
1525                        i = 0;
1526                        j = 0;
1527                        if (ca4[0] == '-') {
1528                            ca5[0] = '-';
1529                            i++;
1530                            j++;
1531                        }
1532                        for (int k = 0; k < nBlanks; i++, k++) {
1533                            ca5[i] = '0';
1534                        }
1535                        for (; j < ca4.length; i++, j++) {
1536                            ca5[i] = ca4[j];
1537                        }
1538                    }
1539                }
1540            }
1541            return ca5;
1542        }
1543
1544        private String JavaDoc printFFormat(BigInteger JavaDoc x) {
1545            return printFFormat(x.doubleValue());
1546        }
1547
1548        private String JavaDoc printEFormat(BigInteger JavaDoc x) {
1549            return printEFormat(x.doubleValue());
1550        }
1551
1552        private String JavaDoc printGFormat(BigInteger JavaDoc x) {
1553            return printGFormat(x.doubleValue());
1554        }
1555
1556        private String JavaDoc printFFormat(double x) {
1557            return fFormatString(x);
1558        }
1559
1560        private String JavaDoc printEFormat(double x) {
1561            if (conversionCharacter == 'e') {
1562                return eFormatString(x, 'e');
1563            }
1564            return eFormatString(x, 'E');
1565        }
1566
1567        private String JavaDoc printGFormat(double x) {
1568            String JavaDoc sx, sy, sz;
1569            String JavaDoc ret;
1570            int savePrecision = precision;
1571            int i;
1572            char[] ca4, ca5;
1573            if (Double.isInfinite(x)) {
1574                if (x == Double.POSITIVE_INFINITY) {
1575                    if (leadingSign) {
1576                        ca4 = "+Inf".toCharArray();
1577                    } else if (leadingSpace) {
1578                        ca4 = " Inf".toCharArray();
1579                    } else {
1580                        ca4 = "Inf".toCharArray();
1581                    }
1582                } else {
1583                    ca4 = "-Inf".toCharArray();
1584                }
1585            } else if (Double.isNaN(x)) {
1586                if (leadingSign) {
1587                    ca4 = "+NaN".toCharArray();
1588                } else if (leadingSpace) {
1589                    ca4 = " NaN".toCharArray();
1590                } else {
1591                    ca4 = "NaN".toCharArray();
1592                }
1593            } else {
1594                if (!precisionSet) {
1595                    precision = defaultDigits;
1596                }
1597                if (precision == 0) {
1598                    precision = 1;
1599                }
1600                int ePos = -1;
1601                if (conversionCharacter == 'g') {
1602                    sx = eFormatString(x, 'e').trim();
1603                    ePos = sx.indexOf('e');
1604                } else {
1605                    sx = eFormatString(x, 'E').trim();
1606                    ePos = sx.indexOf('E');
1607                }
1608                i = ePos + 1;
1609                int expon = 0;
1610                if (sx.charAt(i) == '-') {
1611                    for (++i; i < sx.length(); i++) {
1612                        if (sx.charAt(i) != '0') {
1613                            break;
1614                        }
1615                    }
1616                    if (i < sx.length()) {
1617                        expon = -Integer.parseInt(sx.substring(i));
1618                    }
1619                } else {
1620                    if (sx.charAt(i) == '+') {
1621                        ++i;
1622                    }
1623                    for (; i < sx.length(); i++) {
1624                        if (sx.charAt(i) != '0') {
1625                            break;
1626                        }
1627                    }
1628                    if (i < sx.length()) {
1629                        expon = Integer.parseInt(sx.substring(i));
1630                    }
1631                }
1632                // Trim trailing zeros.
1633
// If the radix character is not followed by
1634
// a digit, trim it, too.
1635
if (!alternateForm) {
1636                    if (expon >= -4 && expon < precision) {
1637                        sy = fFormatString(x).trim();
1638                    } else {
1639                        sy = sx.substring(0, ePos);
1640                    }
1641                    i = sy.length() - 1;
1642                    for (; i >= 0; i--) {
1643                        if (sy.charAt(i) != '0') {
1644                            break;
1645                        }
1646                    }
1647                    if (i >= 0 && sy.charAt(i) == '.') {
1648                        i--;
1649                    }
1650                    if (i == -1) {
1651                        sz = "0";
1652                    } else if (!Character.isDigit(sy.charAt(i))) {
1653                        sz = sy.substring(0, i + 1) + "0";
1654                    } else {
1655                        sz = sy.substring(0, i + 1);
1656                    }
1657                    if (expon >= -4 && expon < precision) {
1658                        ret = sz;
1659                    } else {
1660                        ret = sz + sx.substring(ePos);
1661                    }
1662                } else {
1663                    if (expon >= -4 && expon < precision) {
1664                        ret = fFormatString(x).trim();
1665                    } else {
1666                        ret = sx;
1667                    }
1668                }
1669                // leading space was trimmed off during
1670
// construction
1671
if (leadingSpace) {
1672                    if (x >= 0) {
1673                        ret = " " + ret;
1674                    }
1675                }
1676                ca4 = ret.toCharArray();
1677            }
1678            // Pad with blanks or zeros.
1679
ca5 = applyFloatPadding(ca4, false);
1680            precision = savePrecision;
1681            return new String JavaDoc(ca5);
1682        }
1683
1684        private String JavaDoc printDFormat(short x) {
1685            return printDFormat(Short.toString(x));
1686        }
1687
1688        private String JavaDoc printDFormat(long x) {
1689            return printDFormat(Long.toString(x));
1690        }
1691
1692        private String JavaDoc printDFormat(BigInteger JavaDoc x) {
1693            return printDFormat(x.toString());
1694        }
1695
1696        private String JavaDoc printBFormat(long x) {
1697            return printBFormat(Long.toString(x,2));
1698        }
1699
1700        private String JavaDoc printBFormat(BigInteger JavaDoc x) {
1701            return printBFormat(x.toString(2));
1702        }
1703
1704        private String JavaDoc printBFormat(String JavaDoc sx) {
1705            return printAltFormat(sx,"0b",'B');
1706        }
1707
1708        private String JavaDoc printDFormat(int x) {
1709            return printDFormat(Integer.toString(x));
1710        }
1711
1712        private String JavaDoc printDFormat(String JavaDoc sx) {
1713            int nLeadingZeros = 0;
1714            int nBlanks = 0;
1715            int n = 0;
1716            int i = 0;
1717            int jFirst = 0;
1718            boolean neg = sx.charAt(0) == '-';
1719            if (sx.equals("0") && precisionSet && precision == 0) {
1720                sx = "";
1721            }
1722            if (!neg) {
1723                if (precisionSet && sx.length() < precision) {
1724                    nLeadingZeros = precision - sx.length();
1725                }
1726            } else {
1727                if (precisionSet && sx.length() - 1 < precision) {
1728                    nLeadingZeros = precision - sx.length() + 1;
1729                }
1730            }
1731            if (nLeadingZeros < 0) {
1732                nLeadingZeros = 0;
1733            }
1734            if (fieldWidthSet) {
1735                nBlanks = fieldWidth - nLeadingZeros - sx.length();
1736                if (!neg && (leadingSign || leadingSpace)) {
1737                    nBlanks--;
1738                }
1739            }
1740            if (nBlanks < 0) {
1741                nBlanks = 0;
1742            }
1743            if (!neg) {
1744                if (leadingSign) {
1745                    n++;
1746                } else if (leadingSpace) {
1747                    n++;
1748                }
1749            }
1750            n += nBlanks;
1751            n += nLeadingZeros;
1752            n += sx.length();
1753            char[] ca = new char[n];
1754            if (leftJustify) {
1755                if (neg) {
1756                    ca[i++] = '-';
1757                } else if (leadingSign) {
1758                    ca[i++] = '+';
1759                } else if (leadingSpace) {
1760                    ca[i++] = ' ';
1761                }
1762                char[] csx = sx.toCharArray();
1763                jFirst = neg ? 1 : 0;
1764                for (int j = 0; j < nLeadingZeros; i++, j++) {
1765                    ca[i] = '0';
1766                }
1767                for (int j = jFirst; j < csx.length; j++, i++) {
1768                    ca[i] = csx[j];
1769                }
1770                for (int j = 0; j < nBlanks; i++, j++) {
1771                    ca[i] = ' ';
1772                }
1773            } else {
1774                if (!leadingZeros) {
1775                    for (i = 0; i < nBlanks; i++) {
1776                        ca[i] = ' ';
1777                    }
1778                    if (neg) {
1779                        ca[i++] = '-';
1780                    } else if (leadingSign) {
1781                        ca[i++] = '+';
1782                    } else if (leadingSpace) {
1783                        ca[i++] = ' ';
1784                    }
1785                } else {
1786                    if (neg) {
1787                        ca[i++] = '-';
1788                    } else if (leadingSign) {
1789                        ca[i++] = '+';
1790                    } else if (leadingSpace) {
1791                        ca[i++] = ' ';
1792                    }
1793                    for (int j = 0; j < nBlanks; j++, i++) {
1794                        ca[i] = '0';
1795                    }
1796                }
1797                for (int j = 0; j < nLeadingZeros; j++, i++) {
1798                    ca[i] = '0';
1799                }
1800                char[] csx = sx.toCharArray();
1801                jFirst = neg ? 1 : 0;
1802                for (int j = jFirst; j < csx.length; j++, i++) {
1803                    ca[i] = csx[j];
1804                }
1805            }
1806            return new String JavaDoc(ca);
1807        }
1808
1809        private String JavaDoc printXFormat(short x) {
1810            String JavaDoc sx = null;
1811            if (x == Short.MIN_VALUE) {
1812                sx = "8000";
1813            } else if (x < 0) {
1814                String JavaDoc t;
1815                if (x == Short.MIN_VALUE) {
1816                    t = "0";
1817                } else {
1818                    t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE, 16);
1819                    if (t.charAt(0) == 'F' || t.charAt(0) == 'f') {
1820                        t = t.substring(16, 32);
1821                    }
1822                }
1823                switch (t.length()) {
1824                    case 1 :
1825                        sx = "800" + t;
1826                        break;
1827                    case 2 :
1828                        sx = "80" + t;
1829                        break;
1830                    case 3 :
1831                        sx = "8" + t;
1832                        break;
1833                    case 4 :
1834                        switch (t.charAt(0)) {
1835                            case '1' :
1836                                sx = "9" + t.substring(1, 4);
1837                                break;
1838                            case '2' :
1839                                sx = "a" + t.substring(1, 4);
1840                                break;
1841                            case '3' :
1842                                sx = "b" + t.substring(1, 4);
1843                                break;
1844                            case '4' :
1845                                sx = "c" + t.substring(1, 4);
1846                                break;
1847                            case '5' :
1848                                sx = "d" + t.substring(1, 4);
1849                                break;
1850                            case '6' :
1851                                sx = "e" + t.substring(1, 4);
1852                                break;
1853                            case '7' :
1854                                sx = "f" + t.substring(1, 4);
1855                                break;
1856                        }
1857                        break;
1858                }
1859            } else {
1860                sx = Integer.toString(x, 16);
1861            }
1862            return printXFormat(sx);
1863        }
1864
1865        private String JavaDoc printXFormat(BigInteger JavaDoc x) {
1866            return printXFormat(x.toString(16));
1867        }
1868
1869        private String JavaDoc printXFormat(long x) {
1870            String JavaDoc sx = null;
1871            if (x == Long.MIN_VALUE) {
1872                sx = "8000000000000000";
1873            } else if (x < 0) {
1874                String JavaDoc t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE, 16);
1875                switch (t.length()) {
1876                    case 1 :
1877                        sx = "800000000000000" + t;
1878                        break;
1879                    case 2 :
1880                        sx = "80000000000000" + t;
1881                        break;
1882                    case 3 :
1883                        sx = "8000000000000" + t;
1884                        break;
1885                    case 4 :
1886                        sx = "800000000000" + t;
1887                        break;
1888                    case 5 :
1889                        sx = "80000000000" + t;
1890                        break;
1891                    case 6 :
1892                        sx = "8000000000" + t;
1893                        break;
1894                    case 7 :
1895                        sx = "800000000" + t;
1896                        break;
1897                    case 8 :
1898                        sx = "80000000" + t;
1899                        break;
1900                    case 9 :
1901                        sx = "8000000" + t;
1902                        break;
1903                    case 10 :
1904                        sx = "800000" + t;
1905                        break;
1906                    case 11 :
1907                        sx = "80000" + t;
1908                        break;
1909                    case 12 :
1910                        sx = "8000" + t;
1911                        break;
1912                    case 13 :
1913                        sx = "800" + t;
1914                        break;
1915                    case 14 :
1916                        sx = "80" + t;
1917                        break;
1918                    case 15 :
1919                        sx = "8" + t;
1920                        break;
1921                    case 16 :
1922                        switch (t.charAt(0)) {
1923                            case '1' :
1924                                sx = "9" + t.substring(1, 16);
1925                                break;
1926                            case '2' :
1927                                sx = "a" + t.substring(1, 16);
1928                                break;
1929                            case '3' :
1930                                sx = "b" + t.substring(1, 16);
1931                                break;
1932                            case '4' :
1933                                sx = "c" + t.substring(1, 16);
1934                                break;
1935                            case '5' :
1936                                sx = "d" + t.substring(1, 16);
1937                                break;
1938                            case '6' :
1939                                sx = "e" + t.substring(1, 16);
1940                                break;
1941                            case '7' :
1942                                sx = "f" + t.substring(1, 16);
1943                                break;
1944                        }
1945                        break;
1946                }
1947            } else {
1948                sx = Long.toString(x, 16);
1949            }
1950            return printXFormat(sx);
1951        }
1952
1953        private String JavaDoc printXFormat(int x) {
1954            String JavaDoc sx = null;
1955            if (x == Integer.MIN_VALUE) {
1956                sx = "80000000";
1957            } else if (x < 0) {
1958                String JavaDoc t = Integer.toString((~(-x - 1)) ^ Integer.MIN_VALUE, 16);
1959                switch (t.length()) {
1960                    case 1 :
1961                        sx = "8000000" + t;
1962                        break;
1963                    case 2 :
1964                        sx = "800000" + t;
1965                        break;
1966                    case 3 :
1967                        sx = "80000" + t;
1968                        break;
1969                    case 4 :
1970                        sx = "8000" + t;
1971                        break;
1972                    case 5 :
1973                        sx = "800" + t;
1974                        break;
1975                    case 6 :
1976                        sx = "80" + t;
1977                        break;
1978                    case 7 :
1979                        sx = "8" + t;
1980                        break;
1981                    case 8 :
1982                        switch (t.charAt(0)) {
1983                            case '1' :
1984                                sx = "9" + t.substring(1, 8);
1985                                break;
1986                            case '2' :
1987                                sx = "a" + t.substring(1, 8);
1988                                break;
1989                            case '3' :
1990                                sx = "b" + t.substring(1, 8);
1991                                break;
1992                            case '4' :
1993                                sx = "c" + t.substring(1, 8);
1994                                break;
1995                            case '5' :
1996                                sx = "d" + t.substring(1, 8);
1997                                break;
1998                            case '6' :
1999                                sx = "e" + t.substring(1, 8);
2000                                break;
2001                            case '7' :
2002                                sx = "f" + t.substring(1, 8);
2003                                break;
2004                        }
2005                        break;
2006                }
2007            } else {
2008                sx = Integer.toString(x, 16);
2009            }
2010            return printXFormat(sx);
2011        }
2012
2013        private String JavaDoc printXFormat(String JavaDoc sx) {
2014            return printAltFormat(sx,"0x",'X');
2015        }
2016
2017        private String JavaDoc printAltFormat(String JavaDoc sx, String JavaDoc alt, char bigChar) {
2018            int nLeadingZeros = 0;
2019            int nBlanks = 0;
2020            boolean neg = sx.charAt(0) == '-';
2021            if (sx.equals("0") && precisionSet && precision == 0) {
2022                sx = "";
2023            }
2024            if (!neg) {
2025                if (precisionSet && sx.length() < precision) {
2026                    nLeadingZeros = precision - sx.length();
2027                }
2028            } else {
2029                if (precisionSet && sx.length() - 1 < precision) {
2030                    nLeadingZeros = precision - sx.length() + 1;
2031                }
2032            }
2033            if (nLeadingZeros < 0) {
2034                nLeadingZeros = 0;
2035            }
2036            if (fieldWidthSet) {
2037                nBlanks = fieldWidth - nLeadingZeros - sx.length();
2038                if (alternateForm) {
2039                    nBlanks = nBlanks - alt.length();
2040                }
2041            }
2042            if (nBlanks < 0) {
2043                nBlanks = 0;
2044            }
2045            int n = 0;
2046            if (alternateForm) {
2047                n += 2;
2048            }
2049            if (leadingSign) {
2050                n++;
2051            } else if (leadingSpace) {
2052                n++;
2053            }
2054            n += nLeadingZeros;
2055            n += sx.length();
2056            n += nBlanks;
2057            if(neg) {
2058                n--;
2059            }
2060            char[] ca = new char[n];
2061            int i = 0;
2062            if (leftJustify) {
2063                if (alternateForm) {
2064                    for(int k=0;k<alt.length();k++) {
2065                        ca[i++] = alt.charAt(k);
2066                    }
2067                }
2068                if (neg) {
2069                    ca[i++] = '-';
2070                } else if (leadingSign) {
2071                    ca[i++] = '+';
2072                } else if (leadingSpace) {
2073                    ca[i++] = ' ';
2074                }
2075                int jFirst = neg ? 1 : 0;
2076                for (int j = 0; j < nLeadingZeros; j++, i++) {
2077                    ca[i] = '0';
2078                }
2079                char[] csx = sx.toCharArray();
2080                for (int j = jFirst; j < csx.length; j++, i++) {
2081                    ca[i] = csx[j];
2082                }
2083                for (int j = 0; j < nBlanks; j++, i++) {
2084                    ca[i] = ' ';
2085                }
2086            } else {
2087                if (!leadingZeros) {
2088                    for (int j = 0; j < nBlanks; j++, i++) {
2089                        ca[i] = ' ';
2090                    }
2091                }
2092                if (alternateForm) {
2093                    for(int k=0;k<alt.length();k++) {
2094                        ca[i++] = alt.charAt(k);
2095                    }
2096                }
2097                if (neg) {
2098                    ca[i++] = '-';
2099                } else if (leadingSign) {
2100                    ca[i++] = '+';
2101                } else if (leadingSpace) {
2102                    ca[i++] = ' ';
2103                }
2104                if (leadingZeros) {
2105                    for (int j = 0; j < nBlanks; j++, i++) {
2106                        ca[i] = '0';
2107                    }
2108                }
2109                for (int j = 0; j < nLeadingZeros; j++, i++) {
2110                    ca[i] = '0';
2111                }
2112                char[] csx = sx.toCharArray();
2113                int jFirst = neg ? 1 : 0;
2114                for (int j = jFirst; j < csx.length; j++, i++) {
2115                    ca[i] = csx[j];
2116                }
2117            }
2118            String JavaDoc caReturn = new String JavaDoc(ca);
2119            if (conversionCharacter == bigChar) {
2120                caReturn = caReturn.toUpperCase();
2121            }
2122            return caReturn;
2123        }
2124
2125        private String JavaDoc printOFormat(short x) {
2126            String JavaDoc sx = null;
2127            if (x == Short.MIN_VALUE) {
2128                sx = "100000";
2129            } else if (x < 0) {
2130                String JavaDoc t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE, 8);
2131                switch (t.length()) {
2132                    case 1 :
2133                        sx = "10000" + t;
2134                        break;
2135                    case 2 :
2136                        sx = "1000" + t;
2137                        break;
2138                    case 3 :
2139                        sx = "100" + t;
2140                        break;
2141                    case 4 :
2142                        sx = "10" + t;
2143                        break;
2144                    case 5 :
2145                        sx = "1" + t;
2146                        break;
2147                }
2148            } else {
2149                sx = Integer.toString(x, 8);
2150            }
2151            return printOFormat(sx);
2152        }
2153
2154        private String JavaDoc printOFormat(BigInteger JavaDoc x) {
2155            return printOFormat(x.toString(8));
2156        }
2157
2158        private String JavaDoc printOFormat(long x) {
2159            String JavaDoc sx = null;
2160            if (x == Long.MIN_VALUE) {
2161                sx = "1000000000000000000000";
2162            } else if (x < 0) {
2163                String JavaDoc t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE, 8);
2164                switch (t.length()) {
2165                    case 1 :
2166                        sx = "100000000000000000000" + t;
2167                        break;
2168                    case 2 :
2169                        sx = "10000000000000000000" + t;
2170                        break;
2171                    case 3 :
2172                        sx = "1000000000000000000" + t;
2173                        break;
2174                    case 4 :
2175                        sx = "100000000000000000" + t;
2176                        break;
2177                    case 5 :
2178                        sx = "10000000000000000" + t;
2179                        break;
2180                    case 6 :
2181                        sx = "1000000000000000" + t;
2182                        break;
2183                    case 7 :
2184                        sx = "100000000000000" + t;
2185                        break;
2186                    case 8 :
2187                        sx = "10000000000000" + t;
2188                        break;
2189                    case 9 :
2190                        sx = "1000000000000" + t;
2191                        break;
2192                    case 10 :
2193                        sx = "100000000000" + t;
2194                        break;
2195                    case 11 :
2196                        sx = "10000000000" + t;
2197                        break;
2198                    case 12 :
2199                        sx = "1000000000" + t;
2200                        break;
2201                    case 13 :
2202                        sx = "100000000" + t;
2203                        break;
2204                    case 14 :
2205                        sx = "10000000" + t;
2206                        break;
2207                    case 15 :
2208                        sx = "1000000" + t;
2209                        break;
2210                    case 16 :
2211                        sx = "100000" + t;
2212                        break;
2213                    case 17 :
2214                        sx = "10000" + t;
2215                        break;
2216                    case 18 :
2217                        sx = "1000" + t;
2218                        break;
2219                    case 19 :
2220                        sx = "100" + t;
2221                        break;
2222                    case 20 :
2223                        sx = "10" + t;
2224                        break;
2225                    case 21 :
2226                        sx = "1" + t;
2227                        break;
2228                }
2229            } else {
2230                sx = Long.toString(x, 8);
2231            }
2232            return printOFormat(sx);
2233        }
2234
2235        private String JavaDoc printOFormat(int x) {
2236            String JavaDoc sx = null;
2237            if (x == Integer.MIN_VALUE) {
2238                sx = "20000000000";
2239            } else if (x < 0) {
2240                String JavaDoc t = Integer.toString((~(-x - 1)) ^ Integer.MIN_VALUE, 8);
2241                switch (t.length()) {
2242                    case 1 :
2243                        sx = "2000000000" + t;
2244                        break;
2245                    case 2 :
2246                        sx = "200000000" + t;
2247                        break;
2248                    case 3 :
2249                        sx = "20000000" + t;
2250                        break;
2251                    case 4 :
2252                        sx = "2000000" + t;
2253                        break;
2254                    case 5 :
2255                        sx = "200000" + t;
2256                        break;
2257                    case 6 :
2258                        sx = "20000" + t;
2259                        break;
2260                    case 7 :
2261                        sx = "2000" + t;
2262                        break;
2263                    case 8 :
2264                        sx = "200" + t;
2265                        break;
2266                    case 9 :
2267                        sx = "20" + t;
2268                        break;
2269                    case 10 :
2270                        sx = "2" + t;
2271                        break;
2272                    case 11 :
2273                        sx = "3" + t.substring(1);
2274                        break;
2275                }
2276            } else {
2277                sx = Integer.toString(x, 8);
2278            }
2279            return printOFormat(sx);
2280        }
2281
2282        private String JavaDoc printOFormat(String JavaDoc sx) {
2283            int nLeadingZeros = 0;
2284            int nBlanks = 0;
2285            if (sx.equals("0") && precisionSet && precision == 0) {
2286                sx = "";
2287            }
2288            if (precisionSet) {
2289                nLeadingZeros = precision - sx.length();
2290            }
2291            if (alternateForm) {
2292                nLeadingZeros++;
2293            }
2294            if (nLeadingZeros < 0) {
2295                nLeadingZeros = 0;
2296            }
2297            if (fieldWidthSet) {
2298                nBlanks = fieldWidth - nLeadingZeros - sx.length();
2299            }
2300            if (nBlanks < 0) {
2301                nBlanks = 0;
2302            }
2303            int n = nLeadingZeros + sx.length() + nBlanks;
2304            char[] ca = new char[n];
2305            int i;
2306            if (leftJustify) {
2307                for (i = 0; i < nLeadingZeros; i++) {
2308                    ca[i] = '0';
2309                }
2310                char[] csx = sx.toCharArray();
2311                for (int j = 0; j < csx.length; j++, i++) {
2312                    ca[i] = csx[j];
2313                }
2314                for (int j = 0; j < nBlanks; j++, i++) {
2315                    ca[i] = ' ';
2316                }
2317            } else {
2318                if (leadingZeros) {
2319                    for (i = 0; i < nBlanks; i++) {
2320                        ca[i] = '0';
2321                    }
2322                } else {
2323                    for (i = 0; i < nBlanks; i++) {
2324                        ca[i] = ' ';
2325                    }
2326                }
2327                for (int j = 0; j < nLeadingZeros; j++, i++) {
2328                    ca[i] = '0';
2329                }
2330                char[] csx = sx.toCharArray();
2331                for (int j = 0; j < csx.length; j++, i++) {
2332                    ca[i] = csx[j];
2333                }
2334            }
2335            return new String JavaDoc(ca);
2336        }
2337
2338        private String JavaDoc printCFormat(char x) {
2339            int nPrint = 1;
2340            int width = fieldWidth;
2341            if (!fieldWidthSet) {
2342                width = nPrint;
2343            }
2344            char[] ca = new char[width];
2345            int i = 0;
2346            if (leftJustify) {
2347                ca[0] = x;
2348                for (i = 1; i <= width - nPrint; i++) {
2349                    ca[i] = ' ';
2350                }
2351            } else {
2352                for (i = 0; i < width - nPrint; i++) {
2353                    ca[i] = ' ';
2354                }
2355                ca[i] = x;
2356            }
2357            return new String JavaDoc(ca);
2358        }
2359
2360        private String JavaDoc printSFormat(String JavaDoc x) {
2361            int nPrint = x.length();
2362            int width = fieldWidth;
2363            if (precisionSet && nPrint > precision) {
2364                nPrint = precision;
2365            }
2366            if (!fieldWidthSet) {
2367                width = nPrint;
2368            }
2369            int n = 0;
2370            if (width > nPrint) {
2371                n += width - nPrint;
2372            }
2373            if (nPrint >= x.length()) {
2374                n += x.length();
2375            } else {
2376                n += nPrint;
2377            }
2378            char[] ca = new char[n];
2379            int i = 0;
2380            if (leftJustify) {
2381                if (nPrint >= x.length()) {
2382                    char[] csx = x.toCharArray();
2383                    for (i = 0; i < x.length(); i++) {
2384                        ca[i] = csx[i];
2385                    }
2386                } else {
2387                    char[] csx = x.substring(0, nPrint).toCharArray();
2388                    for (i = 0; i < nPrint; i++) {
2389                        ca[i] = csx[i];
2390                    }
2391                }
2392                for (int j = 0; j < width - nPrint; j++, i++) {
2393                    ca[i] = ' ';
2394                }
2395            } else {
2396                for (i = 0; i < width - nPrint; i++) {
2397                    ca[i] = ' ';
2398                }
2399                if (nPrint >= x.length()) {
2400                    char[] csx = x.toCharArray();
2401                    for (int j = 0; j < x.length(); i++, j++) {
2402                        ca[i] = csx[j];
2403                    }
2404                } else {
2405                    char[] csx = x.substring(0, nPrint).toCharArray();
2406                    for (int j = 0; j < nPrint; i++, j++) {
2407                        ca[i] = csx[j];
2408                    }
2409                }
2410            }
2411            return new String JavaDoc(ca);
2412        }
2413
2414        private boolean setConversionCharacter() {
2415            /* idfgGoxXeEcsb */
2416            boolean ret = false;
2417            conversionCharacter = '\0';
2418            if (pos < fmt.length()) {
2419                char c = fmt.charAt(pos);
2420                if ("idfgGoxXeEcsbp%".indexOf(c) != -1) {
2421                    conversionCharacter = c;
2422                    pos++;
2423                    ret = true;
2424                }
2425            }
2426            return ret;
2427        }
2428
2429        private void setOptionalHL() {
2430            optionalh = false;
2431            optionall = false;
2432            optionalL = false;
2433            if (pos < fmt.length()) {
2434                char c = fmt.charAt(pos);
2435                if (c == 'h') {
2436                    optionalh = true;
2437                    pos++;
2438                } else if (c == 'l') {
2439                    optionall = true;
2440                    pos++;
2441                } else if (c == 'L') {
2442                    optionalL = true;
2443                    pos++;
2444                }
2445            }
2446        }
2447
2448        private void setPrecision() {
2449            int firstPos = pos;
2450            precisionSet = false;
2451            if (pos < fmt.length() && fmt.charAt(pos) == '.') {
2452                pos++;
2453                if (pos < fmt.length() && fmt.charAt(pos) == '*') {
2454                    pos++;
2455                    if (!setPrecisionArgPosition()) {
2456                        variablePrecision = true;
2457                        precisionSet = true;
2458                    }
2459                    return;
2460                }
2461                while (pos < fmt.length()) {
2462                    char c = fmt.charAt(pos);
2463                    if (Character.isDigit(c)) {
2464                        pos++;
2465                    } else {
2466                        break;
2467                    }
2468                }
2469                if (pos > firstPos + 1) {
2470                    String JavaDoc sz = fmt.substring(firstPos + 1, pos);
2471                    precision = Integer.parseInt(sz);
2472                    precisionSet = true;
2473                }
2474            }
2475        }
2476
2477        private void setFieldWidth() {
2478            int firstPos = pos;
2479            fieldWidth = 0;
2480            fieldWidthSet = false;
2481            if ((pos < fmt.length()) && fmt.charAt(pos) == '*') {
2482                pos++;
2483                if (!setFieldWidthArgPosition()) {
2484                    variableFieldWidth = true;
2485                    fieldWidthSet = true;
2486                }
2487            } else {
2488                while (pos < fmt.length()) {
2489                    char c = fmt.charAt(pos);
2490                    if (Character.isDigit(c)) {
2491                        pos++;
2492                    } else {
2493                        break;
2494                    }
2495                }
2496                if (firstPos < pos && firstPos < fmt.length()) {
2497                    String JavaDoc sz = fmt.substring(firstPos, pos);
2498                    fieldWidth = Integer.parseInt(sz);
2499                    fieldWidthSet = true;
2500                }
2501            }
2502        }
2503
2504        private void setArgPosition() {
2505            int xPos;
2506            for (xPos = pos; xPos < fmt.length(); xPos++) {
2507                if (!Character.isDigit(fmt.charAt(xPos))) {
2508                    break;
2509                }
2510            }
2511            if (xPos > pos && xPos < fmt.length()) {
2512                if (fmt.charAt(xPos) == '$') {
2513                    positionalSpecification = true;
2514                    argumentPosition = Integer.parseInt(fmt.substring(pos, xPos));
2515                    pos = xPos + 1;
2516                }
2517            }
2518        }
2519
2520        private boolean setFieldWidthArgPosition() {
2521            boolean ret = false;
2522            int xPos;
2523            for (xPos = pos; xPos < fmt.length(); xPos++) {
2524                if (!Character.isDigit(fmt.charAt(xPos))) {
2525                    break;
2526                }
2527            }
2528            if (xPos > pos && xPos < fmt.length()) {
2529                if (fmt.charAt(xPos) == '$') {
2530                    positionalFieldWidth = true;
2531                    argumentPositionForFieldWidth = Integer.parseInt(fmt.substring(pos, xPos));
2532                    pos = xPos + 1;
2533                    ret = true;
2534                }
2535            }
2536            return ret;
2537        }
2538
2539        private boolean setPrecisionArgPosition() {
2540            boolean ret = false;
2541            int xPos;
2542            for (xPos = pos; xPos < fmt.length(); xPos++) {
2543                if (!Character.isDigit(fmt.charAt(xPos))) {
2544                    break;
2545                }
2546            }
2547            if (xPos > pos && xPos < fmt.length()) {
2548                if (fmt.charAt(xPos) == '$') {
2549                    positionalPrecision = true;
2550                    argumentPositionForPrecision = Integer.parseInt(fmt.substring(pos, xPos));
2551                    pos = xPos + 1;
2552                    ret = true;
2553                }
2554            }
2555            return ret;
2556        }
2557
2558        boolean isPositionalSpecification() {
2559            return positionalSpecification;
2560        }
2561
2562        int getArgumentPosition() {
2563            return argumentPosition;
2564        }
2565
2566        boolean isPositionalFieldWidth() {
2567            return positionalFieldWidth;
2568        }
2569
2570        int getArgumentPositionForFieldWidth() {
2571            return argumentPositionForFieldWidth;
2572        }
2573
2574        boolean isPositionalPrecision() {
2575            return positionalPrecision;
2576        }
2577
2578        int getArgumentPositionForPrecision() {
2579            return argumentPositionForPrecision;
2580        }
2581
2582        private void setFlagCharacters() {
2583            /* '-+ #0 */
2584            thousands = false;
2585            leftJustify = false;
2586            leadingSign = false;
2587            leadingSpace = false;
2588            alternateForm = false;
2589            leadingZeros = false;
2590            for (; pos < fmt.length(); pos++) {
2591                char c = fmt.charAt(pos);
2592                if (c == '\'') {
2593                    thousands = true;
2594                } else if (c == '-') {
2595                    leftJustify = true;
2596                    leadingZeros = false;
2597                } else if (c == '+') {
2598                    leadingSign = true;
2599                    leadingSpace = false;
2600                } else if (c == ' ') {
2601                    if (!leadingSign) {
2602                        leadingSpace = true;
2603                    }
2604                } else if (c == '#') {
2605                    alternateForm = true;
2606                } else if (c == '0') {
2607                    if (!leftJustify) {
2608                        leadingZeros = true;
2609                    }
2610                } else {
2611                    break;
2612                }
2613            }
2614        }
2615
2616        private boolean thousands = false;
2617
2618        private boolean leftJustify = false;
2619
2620        private boolean leadingSign = false;
2621
2622        private boolean leadingSpace = false;
2623
2624        private boolean alternateForm = false;
2625
2626        private boolean leadingZeros = false;
2627
2628        private boolean variableFieldWidth = false;
2629
2630        private int fieldWidth = 0;
2631
2632        private boolean fieldWidthSet = false;
2633
2634        private int precision = 0;
2635
2636        private static final int defaultDigits = 6;
2637
2638        private boolean variablePrecision = false;
2639
2640        private boolean precisionSet = false;
2641        private boolean positionalSpecification = false;
2642        private int argumentPosition = 0;
2643        private boolean positionalFieldWidth = false;
2644        private int argumentPositionForFieldWidth = 0;
2645        private boolean positionalPrecision = false;
2646        private int argumentPositionForPrecision = 0;
2647
2648        private boolean optionalh = false;
2649
2650        private boolean optionall = false;
2651
2652        private boolean optionalL = false;
2653
2654        private char conversionCharacter = '\0';
2655
2656        private int pos = 0;
2657
2658        private String JavaDoc fmt;
2659    }
2660
2661    private Vector JavaDoc vFmt = new Vector JavaDoc();
2662
2663    private int cPos = 0;
2664
2665    private DecimalFormatSymbols JavaDoc dfs = null;
2666}
2667
Popular Tags