KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > util > Sprintf


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Sam
27  */

28
29 package com.caucho.util;
30
31 public class Sprintf {
32   private static final L10N L = new L10N(Sprintf.class);
33
34   /** copied then modified from com.caucho.es.Printf */
35
36   private final static int ALT = 0x01;
37   private final static int ZERO_FILL = 0x02;
38   private final static int POS_PLUS = 0x04;
39   private final static int POS_SPACE = 0x08;
40   private final static int LALIGN = 0x10;
41   private final static int BIG = 0x20;
42   private final static int NO_TRAIL_ZERO = 0x40;
43   private final static int JAVAESCAPE = 0x80;
44   private final static int CSVESCAPE = 0x100;
45   private final static int XMLESCAPE = 0x200;
46
47   private static char []digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
48                                   'a', 'b', 'c', 'd', 'e', 'f'};
49   private static char []bigDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
50                                      'A', 'B', 'C', 'D', 'E', 'F'};
51
52   /**
53    * An implementation of the classic sprintf.<p>
54    *
55    * `sprintf' accepts a series of arguments, applies to each a format
56    * specifier from `format', and returns the formatted data as a string.
57    * `format' is a string containing two types of objects: ordinary
58    * characters (other than `%'), which are copied unchanged to the output, and
59    * conversion specifications, each of which is introduced by `%'. (To include
60    * `%' in the output, use `%%' in the format string). <p>
61    *
62    * A conversion specification has the following form:
63    *
64    * <pre>%[FLAGS][WIDTH][.PREC][TYPE]</pre>
65    *
66    * TYPE is required, the rest are optional.
67    *
68    * The following TYPE's are supported:
69    *
70    * <table>
71    * <tr><td>%%<td>a percent sign
72    * <tr><td>%c<td>a character with the given number
73    * <tr><td>%s<td>a string, a null string becomes "#null"
74    * <tr><td>%z<td>a string, a null string becomes the empty string ""
75    * <tr><td>%d<td>a signed integer, in decimal
76    * <tr><td>%o<td>an integer, in octal
77    * <tr><td>%u<td>an integer, in decimal
78    * <tr><td>%x<td>an integer, in hexadecimal
79    * <tr><td>%X<td>an integer, in hexadecimal using upper-case letters
80    * <tr><td>%e<td>a floating-point number, in scientific notation
81    * <tr><td>%E<td>a floating-point number, like %e with an upper-case "E"
82    * <tr><td>%f<td>a floating-point number, in fixed decimal notation
83    * <tr><td>%g<td>a floating-point number, in %e or %f notation
84    * <tr><td>%G<td>a floating-point number, like %g with an upper-case "E"
85    * <tr><td>%p<td>a pointer (outputs a value like the default of toString())
86    * </table>
87    *
88    * Intepret the word `integer' to mean the java type long.
89    * Since java does not support unsigned integers, all integers are treated
90    * the same.<p>
91    *
92    * The following optional FLAGS are supported:
93    * <table>
94    * <tr><td>0<td>If the TYPE character is an integer leading zeroes are used
95    * to pad the field width instead of spaces (following any
96    * indication of sign or base).
97    *
98    * <tr><td>+<td>Include a `+' with positive numbers.
99    *
100    * <tr><td>(a space)<td>use a space placeholder for the `+' that would result
101    * from a positive number
102    * <tr><td>-<td>The result of is left justified, and the right is padded with
103    * blanks until the result is `WIDTH' in length. If you do not
104    * use this flag, the result is right justified, and padded on
105    * the left.
106    * <tr><td>#<td>an alternate display is used, for `x' and `X' a
107    * non-zero result will have an "0x" prefix; for floating
108    * point numbers the result will always contain a decimal point.
109    *
110    * <tr><td>j<td>escape a string suitable for a Java string, or a CSV file.
111    * The following escapes are applied: " becomes \",
112    * newline becomes \n, return becomes \r, \ becomes \\.
113    *
114    * <tr><td>v<td>escape a string suitable for CSV files, the same as `j'
115    * with an additional <code>"</code> placed at the beginning
116    * and ending of the string
117    *
118    * <tr><td>m<td>escape a string suitable for a XML file. The following
119    * escapes are applied: &lt; becomes &amp;lt;,
120    * &gt; becomes &amp;gt; &amp; becomes &amp;amp;
121    * ' becomes &amp;#039, " becomes &amp;034;
122    * </table>
123    *
124    * The optional WIDTH argument specifies a minium width for the field.
125    * Spaces are used unless the `0' FLAG was used to indicate 0 padding.<p>
126    *
127    * The optional PREC argument is introduced with a `.', and gives the
128    * maximum number of characters to print; or the minimum
129    * number of digits to print for integer and hex values; or the maximum
130    * number of significant digits for `g' and `G'; or the number of digits
131    * to print after the decimal point for floating points.<p>
132    */

133
134   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc[] args)
135   {
136     String JavaDoc ret;
137     CharBuffer cb = CharBuffer.allocate();
138     try {
139       sprintf(cb,format,args);
140     }
141     finally {
142       ret = cb.close();
143     }
144     return ret;
145   }
146
147   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4, Object JavaDoc arg5, Object JavaDoc arg6, Object JavaDoc arg7, Object JavaDoc arg8, Object JavaDoc arg9)
148   {
149     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 } );
150   }
151
152   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4, Object JavaDoc arg5, Object JavaDoc arg6, Object JavaDoc arg7, Object JavaDoc arg8)
153   {
154     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 } );
155   }
156
157   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4, Object JavaDoc arg5, Object JavaDoc arg6, Object JavaDoc arg7)
158   {
159     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 } );
160   }
161
162   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4, Object JavaDoc arg5, Object JavaDoc arg6)
163   {
164     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3, arg4, arg5, arg6 } );
165   }
166
167   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4, Object JavaDoc arg5)
168   {
169     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3, arg4, arg5 } );
170   }
171
172   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3, Object JavaDoc arg4)
173   {
174     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3, arg4 } );
175   }
176
177   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2, Object JavaDoc arg3)
178   {
179     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2, arg3 } );
180   }
181
182   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1, Object JavaDoc arg2)
183   {
184     return sprintf(format, new Object JavaDoc[] { arg0, arg1, arg2 } );
185   }
186
187   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0, Object JavaDoc arg1)
188   {
189     return sprintf(format, new Object JavaDoc[] { arg0, arg1 } );
190   }
191
192   public static String JavaDoc sprintf(String JavaDoc format, Object JavaDoc arg0)
193   {
194     return sprintf(format, new Object JavaDoc[] { arg0 } );
195   }
196
197   public static CharBuffer sprintf(CharBuffer result,
198                                    String JavaDoc format,
199                                    Object JavaDoc ... args)
200   {
201     int length = args.length;
202     int arg = 0;
203     int len = format.length();
204
205     for (int i = 0; i < len; i++) {
206       int ch;
207       int start = i;
208
209       if ((ch = format.charAt(i)) != '%') {
210         result.append((char) ch);
211         continue;
212       }
213
214       int flags = 0;
215     loop:
216       while (++i < len) {
217         switch ((ch = format.charAt(i))) {
218         case '0': flags |= ZERO_FILL; break;
219         case '+': flags |= POS_PLUS; break;
220         case ' ': flags |= POS_SPACE; break;
221         case '#': flags |= ALT; break;
222         case '-': flags |= LALIGN; break;
223         case 'j': flags |= JAVAESCAPE; break;
224         case 'v': flags |= JAVAESCAPE; flags |= CSVESCAPE; break;
225         case 'm': flags |= XMLESCAPE; break;
226
227         default: break loop;
228         }
229       }
230
231       int width = 0;
232       for (; i < len && (ch = format.charAt(i)) >= '0' && ch <= '9'; i++) {
233         width = 10 * width + ch - '0';
234       }
235
236       if (i >= len) {
237         fixBits(result, format, start, i);
238         break;
239       }
240
241       int prec = 0;
242       if (ch == '.') {
243         while (++i < len && (ch = format.charAt(i)) >= '0' && ch <= '9') {
244           prec = 10 * prec + ch - '0';
245         }
246       } else
247         prec = -1;
248
249       if (i >= len) {
250         fixBits(result, format, start, i);
251         break;
252       }
253
254       switch (ch) {
255       case '%':
256         result.append((char) '%');
257         break;
258
259       case 'd':
260       case 'D':
261       case 'i':
262       case 'u':
263       case 'U':
264         if (arg >= length)
265           missing(arg);
266         formatInteger(result, toLong(args[arg++]), width, prec, flags, 10);
267         break;
268
269       case 'o':
270       case 'O':
271         if (arg >= length)
272           missing(arg);
273         formatInteger(result, toLong(args[arg++]), width, prec, flags, 8);
274         break;
275
276       case 'X':
277         flags |= BIG;
278       case 'x':
279         if (arg >= length)
280           missing(arg);
281         formatInteger(result, toLong(args[arg++]), width, prec, flags, 16);
282         break;
283
284       case 'E':
285       case 'G':
286         flags |= BIG;
287       case 'f':
288       case 'e':
289       case 'g':
290         if (arg >= length)
291           missing(arg);
292         formatDouble(result, toDouble(args[arg++]), width, prec, flags, ch);
293         break;
294
295       case 'c':
296         if (arg >= length)
297           missing(arg);
298         formatChar(result, toLong(args[arg++]), width, flags);
299         break;
300
301       case 's':
302         if (arg >= length)
303           missing(arg);
304         formatString(result, toString(args[arg++],"#null"), prec, width, flags);
305         break;
306
307       case 'z':
308         if (arg >= length)
309           missing(arg);
310         formatString(result, toString(args[arg++],""), prec, width, flags);
311         break;
312
313       case 'p':
314         if (arg >= length)
315           missing(arg);
316
317         // like the default for toString()
318
Object JavaDoc o = args[arg++];
319         result.append(o.getClass().getName());
320         result.append('@');
321         result.append(Integer.toHexString(o.hashCode()));
322
323       default:
324         fixBits(result, format, start, i + 1);
325         break;
326       }
327     }
328
329     return result;
330   }
331
332   private static void missing(int arg)
333   {
334     throw new IllegalArgumentException JavaDoc(L.l("missing sprintf argument {0}",arg));
335   }
336
337   public static void formatDouble(CharBuffer cb, double value,
338                                   int prec, int flags, int type)
339   {
340     String JavaDoc raw = Double.toString(value);
341     int expt = 0;
342     int i = 0;
343     CharBuffer digits = new CharBuffer();
344     int ch = raw.charAt(i);
345     boolean seenDigit = false;
346
347     // XXX: locale screws us?
348
for (; i < raw.length(); i++) {
349       if ((ch = raw.charAt(i)) == '.' || ch == 'e' || ch == 'E')
350         break;
351       else if (! seenDigit && ch == '0') {
352       }
353       else {
354         seenDigit = true;
355         digits.append((char) ch);
356         expt++;
357       }
358     }
359
360     if (ch == '.')
361       i++;
362
363     for (; i < raw.length(); i++) {
364       ch = raw.charAt(i);
365
366       if (! seenDigit && ch == '0') {
367         expt--;
368       } else if (ch >= '0' && ch <= '9') {
369         digits.append((char) ch);
370         seenDigit = true;
371       }
372       else {
373         int sign = 1;
374         i++;
375         if ((ch = raw.charAt(i)) == '+') {
376           i++;
377         }
378         else if (ch == '-') {
379           i++;
380           sign = -1;
381         }
382
383         int e = 0;
384         for (; i < raw.length() && (ch = raw.charAt(i)) >= '0' && ch <= '9';
385              i++) {
386           e = 10 * e + ch - '0';
387         }
388
389         expt += sign * e;
390         break;
391       }
392     }
393
394     if (! seenDigit)
395       expt = 1;
396
397     while (digits.length() > 0 && digits.charAt(digits.length() - 1) == '0')
398       digits.setLength(digits.length() - 1);
399
400     if (type == 'f') {
401       if (roundDigits(digits, expt + prec)) {
402         expt++;
403       }
404
405       formatFixed(cb, digits, expt, prec, flags);
406     }
407     else if (type == 'e' || type == 'E') {
408       if (roundDigits(digits, prec + 1))
409         expt++;
410
411       formatExpt(cb, digits, expt, prec, flags);
412     }
413     else {
414       if (roundDigits(digits, prec))
415         expt++;
416
417       if (expt < -3 || expt > prec)
418         formatExpt(cb, digits, expt, prec - 1, flags|NO_TRAIL_ZERO);
419       else
420         formatFixed(cb, digits, expt, prec - expt, flags|NO_TRAIL_ZERO);
421     }
422   }
423
424   public static void formatDouble(CharBuffer cb, double value,
425                                   int width, int prec, int flags,
426                                   int type)
427   {
428     if (prec < 0)
429       prec = 6;
430
431     int offset = cb.length();
432
433     if ((flags & ZERO_FILL) != 0 &&
434         (value < 0 || (flags & (POS_PLUS|POS_SPACE)) != 0)) {
435         offset++;
436         width--;
437     }
438
439     if (value < 0) {
440       cb.append((char) '-');
441       value = -value;
442     } else if ((flags & POS_PLUS) != 0) {
443       cb.append((char) '+');
444     } else if ((flags & POS_SPACE) != 0) {
445       cb.append((char) ' ');
446     }
447
448     formatDouble(cb, value, prec, flags, type);
449
450     width -= cb.length() - offset;
451
452     for (int i = 0; i < width; i++) {
453       if ((flags & LALIGN) != 0)
454         cb.append(' ');
455       else
456         cb.insert(offset, (flags & ZERO_FILL) == 0 ? ' ' : '0');
457     }
458   }
459
460   private static boolean roundDigits(CharBuffer digits, int len)
461   {
462     if (len < 0 || digits.length() <= len)
463       return false;
464
465     int value = digits.charAt(len);
466     if (value < '5')
467       return false;
468
469     for (int i = len - 1; i >= 0; i--) {
470       int ch = digits.charAt(i);
471
472       if (ch != '9') {
473         digits.setCharAt(i, (char) (ch + 1));
474         return false;
475       }
476       digits.setCharAt(i, '0');
477     }
478
479     digits.insert(0, '1');
480
481     return true;
482   }
483
484   private static void formatFixed(CharBuffer cb, CharBuffer digits,
485                                   int expt, int prec, int flags)
486   {
487     int i = 0;
488     int origExpt = expt;
489
490     for (; expt > 0; expt--) {
491       if (i < digits.length())
492         cb.append((char) digits.charAt(i++));
493       else
494         cb.append('0');
495     }
496
497     if (origExpt <= 0) // || digits.length() == 0)
498
cb.append('0');
499
500     if (prec > 0 || (flags & ALT) != 0)
501       cb.append('.');
502
503     for (; expt < 0 && prec > 0; expt++) {
504       cb.append('0');
505       prec--;
506     }
507
508     for (; prec > 0 && i < digits.length(); i++) {
509       cb.append(digits.charAt(i));
510       prec--;
511     }
512
513     for (; prec > 0 && (flags & (NO_TRAIL_ZERO|ALT)) != NO_TRAIL_ZERO; prec--)
514       cb.append('0');
515   }
516
517   private static void formatExpt(CharBuffer cb, CharBuffer digits,
518                                  int expt, int prec, int flags)
519   {
520     if (digits.length() == 0)
521       cb.append('0');
522     else
523       cb.append((char) digits.charAt(0));
524
525     if (prec > 0 || (flags & ALT) != 0)
526       cb.append('.');
527
528     for (int i = 1; i < digits.length(); i++) {
529       if (prec > 0)
530         cb.append((char) digits.charAt(i));
531       prec--;
532     }
533
534     for (; prec > 0 && (flags & (NO_TRAIL_ZERO|ALT)) != NO_TRAIL_ZERO; prec--)
535       cb.append('0');
536
537     if ((flags & BIG) != 0)
538       cb.append('E');
539     else
540       cb.append('e');
541
542     formatInteger(cb, expt - 1, 0, 2, POS_PLUS, 10);
543   }
544
545   public static void formatInteger(CharBuffer cb, long dvalue,
546                                    int width, int prec, int flags, int radix)
547   {
548     boolean isBig = (flags & BIG) != 0;
549     int begin = cb.length();
550
551     long value;
552     if (dvalue > 0)
553       value = (long) (dvalue + 0.5);
554     else
555       value = (long) (dvalue - 0.5);
556
557     if (value < 0 && radix == 10) {
558       cb.append((char) '-');
559       value = -value;
560     } else if (value >= 0 && radix == 10 && (flags & POS_PLUS) != 0)
561       cb.append((char) '+');
562     else if (value >= 0 && radix == 10 && (flags & POS_SPACE) != 0)
563       cb.append((char) ' ');
564     else if (value < 0)
565       value &= 0xffffffffL;
566     else if (radix == 8 && (flags & ALT) != 0 && value != 0)
567       cb.append('0');
568     else if (radix == 16 && (flags & ALT) != 0)
569       cb.append((flags & BIG) == 0 ? "0x" : "0X");
570
571     if ((flags & ZERO_FILL) != 0) {
572       width -= cb.length() - begin;
573       begin = cb.length();
574     }
575
576     int offset = cb.length();
577     int len = 0;
578     while (value != 0) {
579       len++;
580       cb.insert(offset, (isBig ? bigDigits : digits)[(int) (value % radix)]);
581       value /= radix;
582     }
583
584     for (int i = 0; i < prec - len; i++)
585       cb.insert(offset, '0');
586     if (len == 0 && prec == 0)
587       cb.insert(offset, '0');
588
589     width -= cb.length() - begin;
590     for (; width > 0; width--) {
591       if ((flags & LALIGN) != 0)
592         cb.append(' ');
593       else if ((flags & ZERO_FILL) != 0 && prec < 0)
594         cb.insert(begin, '0');
595       else
596         cb.insert(begin, ' ');
597     }
598
599     if (cb.length() == begin)
600       cb.append('0');
601   }
602
603   public static void formatInteger(CharBuffer cb, double dvalue,
604                                    int width, int prec, int flags, int radix)
605   {
606     long value;
607     if (dvalue > 0)
608       value = (long) (dvalue + 0.5);
609     else
610       value = (long) (dvalue - 0.5);
611
612     formatInteger(cb,value,width,prec,flags,radix);
613   }
614
615   public static void formatChar(CharBuffer cb, long ch, int width, int flags)
616   {
617     int offset = cb.length();
618
619     cb.append((char) ch);
620
621     if ((flags & LALIGN) == 0) {
622       for (int i = 0; i < width - 1; i++)
623         cb.insert(offset, (char) ' ');
624     } else {
625       for (int i = 0; i < width - 1; i++)
626         cb.append((char) ' ');
627     }
628   }
629
630   public static void formatString(CharBuffer cb, String JavaDoc string,
631                                   int prec, int width, int flags)
632   {
633     int offset = cb.length();
634
635     if (prec < 0)
636       prec = Integer.MAX_VALUE;
637
638     if ((flags & CSVESCAPE) != 0) { cb.append('\"'); offset+=1; width -= 1; }
639
640     for (int i = 0; i < string.length() && i < prec; i++) {
641       width--;
642       char ch = string.charAt(i);
643       if ((flags & JAVAESCAPE) != 0) {
644         switch (ch) {
645           case '\\':
646             cb.append("\\\\"); offset+=1; width-=1; continue;
647           case '\n':
648             cb.append("\\n"); offset+=1; width-=1; continue;
649           case '\r':
650             cb.append("\\r"); offset+=1; width-=1; continue;
651           case '\"':
652             cb.append("\\\""); offset+=1; width-=1; continue;
653         }
654       }
655       if ((flags & XMLESCAPE) != 0) {
656         switch (ch) {
657           case '<':
658             cb.append("&lt;"); offset+=3; width-=3; continue;
659           case '>':
660             cb.append("&gt;"); offset+=3; width-=3; continue;
661           case '&':
662             cb.append("&amp;"); offset+=4; width-=4; continue;
663           case '\'':
664             cb.append("&#039;"); offset+=5; width-=5; continue;
665           case '"':
666             cb.append("&#034;"); offset+=5; width-=5; continue;
667         }
668       }
669       cb.append(ch);
670     }
671
672     if ((flags & CSVESCAPE) != 0) { cb.append('\"'); offset+=1; width -= 1; }
673
674     if ((flags & LALIGN) == 0) {
675       for (int i = 0; i < width; i++)
676         cb.insert(offset, (char) ' ');
677     } else {
678       for (int i = 0; i < width; i++)
679         cb.append((char) ' ');
680     }
681   }
682
683   private static void fixBits(CharBuffer cb, String JavaDoc format, int s, int i)
684   {
685     for (; s < i; s++)
686       cb.append((char) format.charAt(s));
687   }
688
689   /**
690    * Converts some unknown value to a double.
691    *
692    * @param value the value to be converted.
693    *
694    * @return the double-converted value.
695    */

696   public static double toDouble(Object JavaDoc value)
697   {
698     /** copied from com.caucho.el.Expr */
699
700     if (value == null)
701       return 0;
702     else if (value instanceof Number JavaDoc) {
703       double dValue = ((Number JavaDoc) value).doubleValue();
704
705       if (Double.isNaN(dValue))
706         return 0;
707       else
708         return dValue;
709     }
710     else if (value.equals(""))
711       return 0;
712     else if (value instanceof String JavaDoc) {
713       double dValue = Double.parseDouble((String JavaDoc) value);
714
715       if (Double.isNaN(dValue))
716         return 0;
717       else
718         return dValue;
719     }
720     else {
721       throw new IllegalArgumentException JavaDoc(L.l("can't convert {0} to double.",
722                                              value.getClass().getName()));
723     }
724   }
725
726   /**
727    * Converts some unknown value to a long.
728    *
729    * @param value the value to be converted.
730    *
731    * @return the long-converted value.
732    */

733   public static long toLong(Object JavaDoc value)
734   {
735     /** copied from com.caucho.el.Expr */
736
737     if (value == null)
738       return 0;
739     else if (value instanceof Number JavaDoc)
740       return ((Number JavaDoc) value).longValue();
741     else if (value.equals(""))
742       return 0;
743     else if (value instanceof String JavaDoc) {
744       int sign = 1;
745       String JavaDoc string = (String JavaDoc) value;
746       int length = string.length();
747       long intValue = 0;
748
749       int i = 0;
750       for (; i < length && Character.isWhitespace(string.charAt(i)); i++) {
751       }
752
753       if (length <= i)
754         return 0;
755
756       int ch = string.charAt(i);
757       if (ch == '-') {
758         sign = -1;
759         i++;
760       }
761       else if (ch == '+')
762         i++;
763
764       for (; i < length; i++) {
765         ch = string.charAt(i);
766
767         if (ch >= '0' && ch <= '9') {
768           intValue = 10 * intValue + ch - '0';
769         }
770         else if (ch == '.') {
771           // truncate the decimal
772
i = length;
773           break;
774         } else
775           break;
776       }
777
778       for (; i < length && Character.isWhitespace(string.charAt(i)); i++) {
779       }
780
781       if (i < length)
782         throw new IllegalArgumentException JavaDoc(L.l("can't convert '{0}' to long.", string));
783
784       return sign * intValue;
785
786     }
787     else {
788       throw new IllegalArgumentException JavaDoc(L.l("can't convert {0} to long.",
789                                              value.getClass().getName()));
790     }
791   }
792
793   /**
794    * Converts some unknown value to a String.
795    *
796    * @param value the value to be converted.
797    * @param nullValue the value to return if value == null
798    *
799    * @return the String converted value
800    */

801   public static String JavaDoc toString(Object JavaDoc value, String JavaDoc nullValue)
802   {
803     return (value == null) ? nullValue : value.toString();
804   }
805
806 }
807
Popular Tags