KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javolution > text > TypeFormat


1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2006 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javolution.text;
10
11 import j2me.lang.CharSequence;
12 import javolution.text.TextFormat.Cursor;
13
14 import java.io.IOException JavaDoc;
15
16 /**
17  * <p> This class provides utility methods to parse <code>CharSequence</code>
18  * into primitive types and to format primitive types into any
19  * <code>Appendable</code>.</p>
20  *
21  * <p> Methods from this class <b>do not create temporary objects</b> and
22  * are typically faster than standard library methods (see
23  * <a HREF="http://javolution.org/doc/benchmark.html">benchmark</a>).</p>
24  *
25  * <p> The number of digits when formatting floating point numbers can be
26  * specified. The default setting for <code>double</code> is 17 digits
27  * or even 16 digits when the conversion is lossless back and forth
28  * (mimic the standard library formatting). For example:[code]
29  * TypeFormat.format(0.2, a) = "0.2" // 17 or 16 digits (as long as lossless conversion), remove trailing zeros.
30  * TypeFormat.format(0.2, 17, false, false, a) = "0.20000000000000001" // Closest 17 digits number.
31  * TypeFormat.format(0.2, 19, false, false, a) = "0.2000000000000000111" // Closest 19 digits.
32  * TypeFormat.format(0.2, 4, false, false, a) = "0.2" // Fixed-point notation, remove trailing zeros.
33  * TypeFormat.format(0.2, 4, false, true, a) = "0.2000" // Fixed-point notation, fixed number of digits.
34  * TypeFormat.format(0.2, 4, true, false, a) = "2.0E-1" // Scientific notation, remove trailing zeros.
35  * TypeFormat.format(0.2, 4, true, true, a) = "2.000E-1" // Scientific notation, fixed number of digits.
36  * [/code]</p>
37  *
38  * <p> For non-primitive objects, formatting is typically performed using
39  * specialized {@link TextFormat} instances.</p>
40  *
41  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
42  * @version 4.1, November 30, 2006
43  */

44 public final class TypeFormat {
45
46     /**
47      * Default constructor (forbids derivation).
48      */

49     private TypeFormat() {
50     }
51
52     /**
53      * Parses the specified character sequence as a <code>boolean</code>.
54      *
55      * @param csq the character sequence to parse.
56      * @return the corresponding boolean value.
57      * @throws IllegalArgumentException if the specified character sequence
58      * is different from "true" or "false" ignoring cases.
59      */

60     public static boolean parseBoolean(CharSequence JavaDoc csq) {
61         if ((csq.length() == 4)
62                 && (csq.charAt(0) == 't' || csq.charAt(0) == 'T')
63                 && (csq.charAt(1) == 'r' || csq.charAt(1) == 'R')
64                 && (csq.charAt(2) == 'u' || csq.charAt(2) == 'U')
65                 && (csq.charAt(3) == 'e' || csq.charAt(3) == 'E')) {
66             return true;
67         } else if ((csq.length() == 5)
68                 && (csq.charAt(0) == 'f' || csq.charAt(0) == 'F')
69                 && (csq.charAt(1) == 'a' || csq.charAt(1) == 'A')
70                 && (csq.charAt(2) == 'l' || csq.charAt(2) == 'L')
71                 && (csq.charAt(3) == 's' || csq.charAt(3) == 'S')
72                 && (csq.charAt(4) == 'e' || csq.charAt(4) == 'E')) {
73             return false;
74         }
75         throw new IllegalArgumentException JavaDoc("Cannot parse " + csq
76                 + " as boolean");
77     }
78
79     /**
80      * Equivalent to {@link #parseBoolean(CharSequence)}
81      * (for J2ME compatibility).
82      */

83     public static boolean parseBoolean(String JavaDoc csq) {
84         if ((csq.length() == 4)
85                 && (csq.charAt(0) == 't' || csq.charAt(0) == 'T')
86                 && (csq.charAt(1) == 'r' || csq.charAt(1) == 'R')
87                 && (csq.charAt(2) == 'u' || csq.charAt(2) == 'U')
88                 && (csq.charAt(3) == 'e' || csq.charAt(3) == 'E')) {
89             return true;
90         } else if ((csq.length() == 5)
91                 && (csq.charAt(0) == 'f' || csq.charAt(0) == 'F')
92                 && (csq.charAt(1) == 'a' || csq.charAt(1) == 'A')
93                 && (csq.charAt(2) == 'l' || csq.charAt(2) == 'L')
94                 && (csq.charAt(3) == 's' || csq.charAt(3) == 'S')
95                 && (csq.charAt(4) == 'e' || csq.charAt(4) == 'E')) {
96             return false;
97         }
98         throw new IllegalArgumentException JavaDoc("Cannot parse " + csq
99                 + " as boolean");
100     }
101
102     /**
103      * Parses the specified character sequence from the specified position
104      * as a <code>boolean</code>.
105      *
106      * @param csq the character sequence to parse.
107      * @param cursor the current cursor position (being maintained).
108      * @return the next boolean value.
109      * @throws IllegalArgumentException if the character sequence from the
110      * specified position is different from "true" or "false" ignoring
111      * cases.
112      */

113     public static boolean parseBoolean(CharSequence JavaDoc csq, Cursor cursor) {
114         final int i = cursor.getIndex();
115         if ((cursor.getEndIndex() > i + 4)
116                 && (csq.charAt(i) == 't' || csq.charAt(i) == 'T')
117                 && (csq.charAt(i + 1) == 'r' || csq.charAt(i + 1) == 'R')
118                 && (csq.charAt(i + 2) == 'u' || csq.charAt(i + 2) == 'U')
119                 && (csq.charAt(i + 3) == 'e' || csq.charAt(i + 3) == 'E')) {
120             cursor.increment(4);
121             return true;
122         }
123         if ((cursor.getEndIndex() > i + 5)
124                 && (csq.charAt(i) == 'f' || csq.charAt(i) == 'F')
125                 && (csq.charAt(i + 1) == 'a' || csq.charAt(i + 1) == 'A')
126                 && (csq.charAt(i + 2) == 'l' || csq.charAt(i + 2) == 'L')
127                 && (csq.charAt(i + 3) == 's' || csq.charAt(i + 3) == 'S')
128                 && (csq.charAt(i + 4) == 'e' || csq.charAt(i + 4) == 'E')) {
129             cursor.increment(5);
130             return false;
131         }
132         throw new IllegalArgumentException JavaDoc("Cannot parse boolean at "
133                 + cursor.getIndex());
134     }
135
136     /**
137      * Parses the specified character sequence as a signed decimal
138      * <code>byte</code>.
139      *
140      * @param csq the character sequence to parse.
141      * @return <code>parseByte(csq, 10)</code>
142      * @throws NumberFormatException if the specified character sequence
143      * does not contain a parsable <code>byte</code>.
144      * @see #parseByte(CharSequence, int)
145      */

146     public static byte parseByte(CharSequence JavaDoc csq) {
147         return parseByte(csq, 10);
148     }
149
150     /**
151      * Parses the specified character sequence as a signed <code>byte</code>
152      * in the specified radix.
153      *
154      * @param csq the character sequence to parse.
155      * @param radix the radix to be used while parsing.
156      * @return the corresponding <code>byte</code>.
157      * @throws NumberFormatException if the specified character sequence
158      * does not contain a parsable <code>byte</code>.
159      */

160     public static byte parseByte(CharSequence JavaDoc csq, int radix) {
161         int i = parseInt(csq, radix);
162         if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE))
163             throw new NumberFormatException JavaDoc("Overflow");
164         return (byte) i;
165     }
166
167     /**
168      * Parses the specified character sequence from the specified position
169      * as a signed <code>byte</code> in the specified radix.
170      *
171      * @param csq the character sequence to parse.
172      * @param radix the radix to be used while parsing.
173      * @param cursor the current cursor position (being maintained).
174      * @return the corresponding <code>byte</code>.
175      * @throws NumberFormatException if the specified character sequence
176      * does not contain a parsable <code>byte</code>.
177      */

178     public static byte parseByte(CharSequence JavaDoc csq, int radix, Cursor cursor) {
179         int i = parseInt(csq, radix, cursor);
180         if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE))
181             throw new NumberFormatException JavaDoc("Overflow");
182         return (byte) i;
183     }
184
185     /**
186      * Parses the specified character sequence as a signed decimal
187      * <code>short</code>.
188      *
189      * @param csq the character sequence to parse.
190      * @return <code>parseShort(csq, 10)</code>
191      * @throws NumberFormatException if the specified character sequence
192      * does not contain a parsable <code>short</code>.
193      * @see #parseShort(CharSequence, int)
194      */

195     public static short parseShort(CharSequence JavaDoc csq) {
196         return parseShort(csq, 10);
197     }
198
199     /**
200      * Parses the specified character sequence as a signed <code>short</code>
201      * in the specified radix.
202      *
203      * @param csq the character sequence to parse.
204      * @param radix the radix to be used while parsing.
205      * @return the corresponding <code>short</code>.
206      * @throws NumberFormatException if the specified character sequence
207      * does not contain a parsable <code>short</code>.
208      */

209     public static short parseShort(CharSequence JavaDoc csq, int radix) {
210         int i = parseInt(csq, radix);
211         if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE))
212             throw new NumberFormatException JavaDoc("Overflow");
213         return (short) i;
214     }
215
216     /**
217      * Parses the specified character sequence from the specified position
218      * as a signed <code>short</code> in the specified radix.
219      *
220      * @param csq the character sequence to parse.
221      * @param radix the radix to be used while parsing.
222      * @param cursor the current cursor position (being maintained).
223      * @return the corresponding <code>short</code>.
224      * @throws NumberFormatException if the specified character sequence
225      * does not contain a parsable <code>short</code>.
226      */

227     public static short parseShort(CharSequence JavaDoc csq, int radix, Cursor cursor) {
228         int i = parseInt(csq, radix, cursor);
229         if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE))
230             throw new NumberFormatException JavaDoc("Overflow");
231         return (short) i;
232     }
233
234     /**
235      * Parses the specified character sequence as a signed <code>int</code>.
236      *
237      * @param csq the character sequence to parse.
238      * @return <code>parseInt(csq, 10)</code>
239      * @throws NumberFormatException if the specified character sequence
240      * does not contain a parsable <code>int</code>.
241      * @see #parseInt(CharSequence, int)
242      */

243     public static int parseInt(CharSequence JavaDoc csq) {
244         return parseInt(csq, 10);
245     }
246
247     /**
248      * Equivalent to {@link #parseInt(CharSequence)} (for J2ME compatibility).
249      */

250     public static int parseInt(String JavaDoc str) {
251         return parseIntString(str, 10, null);
252     }
253
254     /**
255      * Parses the specified character sequence as a signed <code>int</code>
256      * in the specified radix.
257      *
258      * @param csq the character sequence to parse.
259      * @param radix the radix to be used while parsing.
260      * @return the corresponding <code>int</code>.
261      * @throws NumberFormatException if the specified character sequence
262      * does not contain a parsable <code>int</code>.
263      */

264     public static int parseInt(CharSequence JavaDoc csq, int radix) {
265         return parseInt(csq, radix, null);
266     }
267
268     /**
269      * Equivalent to {@link #parseInt(CharSequence, int)}
270      * (for J2ME compatibility).
271      */

272     public static int parseInt(String JavaDoc str, int radix) {
273         return parseIntString(str, radix, null);
274     }
275
276     /**
277      * Parses the specified character sequence from the specified position
278      * as a signed <code>int</code> in the specified radix.
279      *
280      * @param csq the character sequence to parse.
281      * @param radix the radix to be used while parsing.
282      * @param cursor the current cursor position (being maintained) or
283      * <code>null</code> if the whole character sequence is parsed.
284      * @return the corresponding <code>int</code>.
285      * @throws NumberFormatException if the specified character sequence
286      * does not contain a parsable <code>int</code>.
287      */

288     public static int parseInt(CharSequence JavaDoc csq, int radix, Cursor cursor) {
289         // Avoids dynamic cost of CharSequence.charAt
290
if (csq instanceof CharArray)
291             return parseIntCharArray((CharArray) csq, radix, cursor);
292         if (csq instanceof TextBuilder)
293             return parseIntTextBuilder((TextBuilder) csq, radix, cursor);
294         if (csq instanceof Text)
295             return parseIntText((Text) csq, radix, cursor);
296         if (((Object JavaDoc) csq) instanceof String JavaDoc)
297             return parseIntString((String JavaDoc) ((Object JavaDoc) csq), radix, cursor);
298         return parseIntCharSequence(csq, radix, cursor);
299     }
300
301     private static int parseIntCharArray(CharArray csq, int radix, Cursor cursor) {
302         // Parsing block identical for all CharSequences.
303
final int start = (cursor != null) ? cursor.getIndex() : 0;
304         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
305         boolean isNegative = false;
306         int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
307
int i = start;
308         for (; i < end; i++) {
309             char c = csq.charAt(i);
310             int digit = (c <= '9') ? c - '0'
311                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
312                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
313             if ((digit >= 0) && (digit < radix)) {
314                 int newResult = result * radix - digit;
315                 if (newResult > result)
316                     throw new NumberFormatException JavaDoc("Overflow");
317                 result = newResult;
318             } else if ((c == '-') && (i == start)) {
319                 isNegative = true;
320             } else if ((c == '+') && (i == start)) {
321                 // Ok.
322
} else {
323                 if (cursor == null)
324                     throw new NumberFormatException JavaDoc("Incomplete parsing");
325                 break; // Done.
326
}
327         }
328         // Requires one valid digit character and checks for opposite overflow.
329
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
330             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
331         if ((result == Integer.MIN_VALUE) && !isNegative)
332             throw new NumberFormatException JavaDoc("Overflow");
333         if (cursor != null)
334             cursor.setIndex(i);
335         return isNegative ? result : -result;
336     }
337
338     private static int parseIntTextBuilder(TextBuilder csq, int radix,
339             Cursor cursor) {
340         // Parsing block identical for all CharSequences.
341
final int start = (cursor != null) ? cursor.getIndex() : 0;
342         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
343         boolean isNegative = false;
344         int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
345
int i = start;
346         for (; i < end; i++) {
347             char c = csq.charAt(i);
348             int digit = (c <= '9') ? c - '0'
349                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
350                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
351             if ((digit >= 0) && (digit < radix)) {
352                 int newResult = result * radix - digit;
353                 if (newResult > result)
354                     throw new NumberFormatException JavaDoc("Overflow");
355                 result = newResult;
356             } else if ((c == '-') && (i == start)) {
357                 isNegative = true;
358             } else if ((c == '+') && (i == start)) {
359                 // Ok.
360
} else {
361                 if (cursor == null)
362                     throw new NumberFormatException JavaDoc("Incomplete parsing");
363                 break; // Done.
364
}
365         }
366         // Requires one valid digit character and checks for opposite overflow.
367
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
368             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
369         if ((result == Integer.MIN_VALUE) && !isNegative)
370             throw new NumberFormatException JavaDoc("Overflow");
371         if (cursor != null)
372             cursor.setIndex(i);
373         return isNegative ? result : -result;
374     }
375
376     private static int parseIntText(Text csq, int radix, Cursor cursor) {
377         // Parsing block identical for all CharSequences.
378
final int start = (cursor != null) ? cursor.getIndex() : 0;
379         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
380         boolean isNegative = false;
381         int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
382
int i = start;
383         for (; i < end; i++) {
384             char c = csq.charAt(i);
385             int digit = (c <= '9') ? c - '0'
386                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
387                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
388             if ((digit >= 0) && (digit < radix)) {
389                 int newResult = result * radix - digit;
390                 if (newResult > result)
391                     throw new NumberFormatException JavaDoc("Overflow");
392                 result = newResult;
393             } else if ((c == '-') && (i == start)) {
394                 isNegative = true;
395             } else if ((c == '+') && (i == start)) {
396                 // Ok.
397
} else {
398                 if (cursor == null)
399                     throw new NumberFormatException JavaDoc("Incomplete parsing");
400                 break; // Done.
401
}
402         }
403         // Requires one valid digit character and checks for opposite overflow.
404
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
405             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
406         if ((result == Integer.MIN_VALUE) && !isNegative)
407             throw new NumberFormatException JavaDoc("Overflow");
408         if (cursor != null)
409             cursor.setIndex(i);
410         return isNegative ? result : -result;
411     }
412
413     private static int parseIntString(String JavaDoc csq, int radix, Cursor cursor) {
414         // Parsing block identical for all CharSequences.
415
final int start = (cursor != null) ? cursor.getIndex() : 0;
416         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
417         boolean isNegative = false;
418         int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
419
int i = start;
420         for (; i < end; i++) {
421             char c = csq.charAt(i);
422             int digit = (c <= '9') ? c - '0'
423                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
424                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
425             if ((digit >= 0) && (digit < radix)) {
426                 int newResult = result * radix - digit;
427                 if (newResult > result)
428                     throw new NumberFormatException JavaDoc("Overflow");
429                 result = newResult;
430             } else if ((c == '-') && (i == start)) {
431                 isNegative = true;
432             } else if ((c == '+') && (i == start)) {
433                 // Ok.
434
} else {
435                 if (cursor == null)
436                     throw new NumberFormatException JavaDoc("Incomplete parsing");
437                 break; // Done.
438
}
439         }
440         // Requires one valid digit character and checks for opposite overflow.
441
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
442             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
443         if ((result == Integer.MIN_VALUE) && !isNegative)
444             throw new NumberFormatException JavaDoc("Overflow");
445         if (cursor != null)
446             cursor.setIndex(i);
447         return isNegative ? result : -result;
448     }
449
450     private static int parseIntCharSequence(CharSequence JavaDoc csq, int radix,
451             Cursor cursor) {
452         // Parsing block identical for all CharSequences.
453
final int start = (cursor != null) ? cursor.getIndex() : 0;
454         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
455         boolean isNegative = false;
456         int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
457
int i = start;
458         for (; i < end; i++) {
459             char c = csq.charAt(i);
460             int digit = (c <= '9') ? c - '0'
461                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
462                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
463             if ((digit >= 0) && (digit < radix)) {
464                 int newResult = result * radix - digit;
465                 if (newResult > result)
466                     throw new NumberFormatException JavaDoc("Overflow");
467                 result = newResult;
468             } else if ((c == '-') && (i == start)) {
469                 isNegative = true;
470             } else if ((c == '+') && (i == start)) {
471                 // Ok.
472
} else {
473                 if (cursor == null)
474                     throw new NumberFormatException JavaDoc("Incomplete parsing");
475                 break; // Done.
476
}
477         }
478         // Requires one valid digit character and checks for opposite overflow.
479
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
480             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
481         if ((result == Integer.MIN_VALUE) && !isNegative)
482             throw new NumberFormatException JavaDoc("Overflow");
483         if (cursor != null)
484             cursor.setIndex(i);
485         return isNegative ? result : -result;
486     }
487
488     /**
489      * Parses the specified character sequence as a decimal <code>long</code>.
490      *
491      * @param csq the character sequence to parse.
492      * @return <code>parseLong(csq, 10)</code>
493      * @throws NumberFormatException if the specified character sequence
494      * does not contain a parsable <code>long</code>.
495      * @see #parseLong(CharSequence, int)
496      */

497     public static long parseLong(CharSequence JavaDoc csq) {
498         return parseLong(csq, 10);
499     }
500
501     /**
502      * Equivalent to {@link #parseLong(CharSequence)}
503      * (for J2ME compatibility).
504      */

505     public static long parseLong(String JavaDoc str) {
506         return parseLongString(str, 10, null);
507     }
508
509     /**
510      * Parses the specified character sequence as a signed <code>long</code>
511      * in the specified radix.
512      *
513      * @param csq the character sequence to parse.
514      * @param radix the radix to be used while parsing.
515      * @return the corresponding <code>long</code>.
516      * @throws NumberFormatException if the specified character sequence
517      * does not contain a parsable <code>long</code>.
518      */

519     public static long parseLong(CharSequence JavaDoc csq, int radix) {
520         return parseLong(csq, radix, null);
521     }
522
523     /**
524      * Equivalent to {@link #parseLong(CharSequence, int)}
525      * (for J2ME compatibility).
526      */

527     public static long parseLong(String JavaDoc str, int radix) {
528         return parseLongString(str, radix, null);
529     }
530
531     /**
532      * Parses the specified character sequence from the specified position
533      * as a signed <code>long</code> in the specified radix.
534      *
535      * @param csq the character sequence to parse.
536      * @param radix the radix to be used while parsing.
537      * @param cursor the current cursor position (being maintained) or
538      * <code>null</code> if the whole character sequence is parsed.
539      * @return the corresponding <code>long</code>.
540      * @throws NumberFormatException if the specified character sequence
541      * does not contain a parsable <code>long</code>.
542      */

543     public static long parseLong(CharSequence JavaDoc csq, int radix, Cursor cursor) {
544         // Avoids dynamic cost of CharSequence.charAt
545
if (csq instanceof CharArray)
546             return parseLongCharArray((CharArray) csq, radix, cursor);
547         if (csq instanceof TextBuilder)
548             return parseLongTextBuilder((TextBuilder) csq, radix, cursor);
549         if (csq instanceof Text)
550             return parseLongText((Text) csq, radix, cursor);
551         if (((Object JavaDoc) csq) instanceof String JavaDoc)
552             return parseLongString((String JavaDoc) ((Object JavaDoc) csq), radix, cursor);
553         return parseLongCharSequence(csq, radix, cursor);
554     }
555
556     private static long parseLongCharArray(CharArray csq, int radix,
557             Cursor cursor) {
558         // Parsing block identical for all CharSequences.
559
final int start = (cursor != null) ? cursor.getIndex() : 0;
560         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
561         boolean isNegative = false;
562         long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
563
int i = start;
564         for (; i < end; i++) {
565             char c = csq.charAt(i);
566             int digit = (c <= '9') ? c - '0'
567                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
568                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
569             if ((digit >= 0) && (digit < radix)) {
570                 long newResult = result * radix - digit;
571                 if (newResult > result)
572                     throw new NumberFormatException JavaDoc("Overflow");
573                 result = newResult;
574             } else if ((c == '-') && (i == start)) {
575                 isNegative = true;
576             } else if ((c == '+') && (i == start)) {
577                 // Ok.
578
} else {
579                 if (cursor == null)
580                     throw new NumberFormatException JavaDoc("Incomplete parsing");
581                 break; // Done.
582
}
583         }
584         // Requires one valid digit character and checks for opposite overflow.
585
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
586             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
587         if ((result == Long.MIN_VALUE) && !isNegative)
588             throw new NumberFormatException JavaDoc("Overflow");
589         if (cursor != null)
590             cursor.setIndex(i);
591         return isNegative ? result : -result;
592     }
593
594     private static long parseLongTextBuilder(TextBuilder csq, int radix,
595             Cursor cursor) {
596         // Parsing block identical for all CharSequences.
597
final int start = (cursor != null) ? cursor.getIndex() : 0;
598         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
599         boolean isNegative = false;
600         long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
601
int i = start;
602         for (; i < end; i++) {
603             char c = csq.charAt(i);
604             int digit = (c <= '9') ? c - '0'
605                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
606                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
607             if ((digit >= 0) && (digit < radix)) {
608                 long newResult = result * radix - digit;
609                 if (newResult > result)
610                     throw new NumberFormatException JavaDoc("Overflow");
611                 result = newResult;
612             } else if ((c == '-') && (i == start)) {
613                 isNegative = true;
614             } else if ((c == '+') && (i == start)) {
615                 // Ok.
616
} else {
617                 if (cursor == null)
618                     throw new NumberFormatException JavaDoc("Incomplete parsing");
619                 break; // Done.
620
}
621         }
622         // Requires one valid digit character and checks for opposite overflow.
623
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
624             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
625         if ((result == Long.MIN_VALUE) && !isNegative)
626             throw new NumberFormatException JavaDoc("Overflow");
627         if (cursor != null)
628             cursor.setIndex(i);
629         return isNegative ? result : -result;
630     }
631
632     private static long parseLongText(Text csq, int radix, Cursor cursor) {
633         // Parsing block identical for all CharSequences.
634
final int start = (cursor != null) ? cursor.getIndex() : 0;
635         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
636         boolean isNegative = false;
637         long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
638
int i = start;
639         for (; i < end; i++) {
640             char c = csq.charAt(i);
641             int digit = (c <= '9') ? c - '0'
642                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
643                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
644             if ((digit >= 0) && (digit < radix)) {
645                 long newResult = result * radix - digit;
646                 if (newResult > result)
647                     throw new NumberFormatException JavaDoc("Overflow");
648                 result = newResult;
649             } else if ((c == '-') && (i == start)) {
650                 isNegative = true;
651             } else if ((c == '+') && (i == start)) {
652                 // Ok.
653
} else {
654                 if (cursor == null)
655                     throw new NumberFormatException JavaDoc("Incomplete parsing");
656                 break; // Done.
657
}
658         }
659         // Requires one valid digit character and checks for opposite overflow.
660
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
661             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
662         if ((result == Long.MIN_VALUE) && !isNegative)
663             throw new NumberFormatException JavaDoc("Overflow");
664         if (cursor != null)
665             cursor.setIndex(i);
666         return isNegative ? result : -result;
667     }
668
669     private static long parseLongString(String JavaDoc csq, int radix, Cursor cursor) {
670         // Parsing block identical for all CharSequences.
671
final int start = (cursor != null) ? cursor.getIndex() : 0;
672         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
673         boolean isNegative = false;
674         long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
675
int i = start;
676         for (; i < end; i++) {
677             char c = csq.charAt(i);
678             int digit = (c <= '9') ? c - '0'
679                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
680                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
681             if ((digit >= 0) && (digit < radix)) {
682                 long newResult = result * radix - digit;
683                 if (newResult > result)
684                     throw new NumberFormatException JavaDoc("Overflow");
685                 result = newResult;
686             } else if ((c == '-') && (i == start)) {
687                 isNegative = true;
688             } else if ((c == '+') && (i == start)) {
689                 // Ok.
690
} else {
691                 if (cursor == null)
692                     throw new NumberFormatException JavaDoc("Incomplete parsing");
693                 break; // Done.
694
}
695         }
696         // Requires one valid digit character and checks for opposite overflow.
697
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
698             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
699         if ((result == Long.MIN_VALUE) && !isNegative)
700             throw new NumberFormatException JavaDoc("Overflow");
701         if (cursor != null)
702             cursor.setIndex(i);
703         return isNegative ? result : -result;
704     }
705
706     private static long parseLongCharSequence(CharSequence JavaDoc csq, int radix,
707             Cursor cursor) {
708         // Parsing block identical for all CharSequences.
709
final int start = (cursor != null) ? cursor.getIndex() : 0;
710         final int end = (cursor != null) ? cursor.getEndIndex() : csq.length();
711         boolean isNegative = false;
712         long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
713
int i = start;
714         for (; i < end; i++) {
715             char c = csq.charAt(i);
716             int digit = (c <= '9') ? c - '0'
717                     : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
718                             : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
719             if ((digit >= 0) && (digit < radix)) {
720                 long newResult = result * radix - digit;
721                 if (newResult > result)
722                     throw new NumberFormatException JavaDoc("Overflow");
723                 result = newResult;
724             } else if ((c == '-') && (i == start)) {
725                 isNegative = true;
726             } else if ((c == '+') && (i == start)) {
727                 // Ok.
728
} else {
729                 if (cursor == null)
730                     throw new NumberFormatException JavaDoc("Incomplete parsing");
731                 break; // Done.
732
}
733         }
734         // Requires one valid digit character and checks for opposite overflow.
735
if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
736             throw new NumberFormatException JavaDoc("Cannot parse " + csq + " as int");
737         if ((result == Long.MIN_VALUE) && !isNegative)
738             throw new NumberFormatException JavaDoc("Overflow");
739         if (cursor != null)
740             cursor.setIndex(i);
741         return isNegative ? result : -result;
742     }
743
744     /**
745      * Parses the specified character sequence as a <code>float</code>.
746      *
747      * @param csq the character sequence to parse.
748      * @return the float number represented by the specified character sequence.
749      *@JVM-1.1+@
750      public static float parseFloat(CharSequence csq) {
751      return (float) parseDouble(csq);
752      }
753      /**/

754
755     /**
756      * Equivalent to {@link #parseFloat(CharSequence)}
757      * (for J2ME compatibility).
758      *@JVM-1.1+@
759      public static float parseFloat(String str) {
760      return (float) parseDoubleString(str, null);
761      }
762      /**/

763
764     /**
765      * Parses the specified character sequence from the specified position
766      * as a <code>float</code>.
767      *
768      * @param csq the character sequence to parse.
769      * @param cursor the current cursor position (being maintained).
770      * @return the float number represented by the specified character sequence.
771      *@JVM-1.1+@
772      public static float parseFloat(CharSequence csq, Cursor cursor) {
773      return (float) parseDouble(csq, cursor);
774      }
775      /**/

776
777     /**
778      * Parses the specified character sequence as a <code>double</code>.
779      * The format must be of the form:<code>
780      * &lt;decimal&gt;{'.'&lt;fraction&gt;}{'E|e'&lt;exponent&gt;}</code>.
781      *
782      * @param csq the character sequence to parse.
783      * @return the double number represented by this character sequence.
784      * @throws NumberFormatException if the character sequence does not contain
785      * a parsable <code>double</code>.
786      *@JVM-1.1+@
787      public static double parseDouble(CharSequence csq)
788      throws NumberFormatException {
789      return parseDouble(csq, null);
790      }
791      /**/

792
793     /**
794      * Equivalent to {@link #parseDouble(CharSequence)}
795      * (for J2ME compatibility).
796      *@JVM-1.1+@
797      public static double parseDouble(String str) {
798      return parseDoubleString(str, null);
799      }
800      /**/

801
802     /**
803      * Parses the specified character sequence from the specified position
804      * as a <code>double</code>.
805      *
806      * @param csq the character sequence to parse.
807      * @param cursor the current cursor position (being maintained).
808      * @return the double number represented by this character sequence.
809      * @throws NumberFormatException if the character sequence does not contain
810      * a parsable <code>double</code>.
811      *@JVM-1.1+@
812      public static double parseDouble(CharSequence csq, Cursor cursor)
813      throws NumberFormatException {
814      // Avoids dynamic cost of CharSequence.charAt
815      if (csq instanceof CharArray)
816      return parseDoubleCharArray((CharArray) csq, cursor);
817      if (csq instanceof TextBuilder)
818      return parseDoubleTextBuilder((TextBuilder) csq, cursor);
819      if (csq instanceof Text)
820      return parseDoubleText((Text) csq, cursor);
821      if (((Object) csq) instanceof String)
822      return parseDoubleString((String) ((Object) csq), cursor);
823      return parseDoubleCharSequence(csq, cursor);
824      }
825      
826      private static double parseDoubleCharArray(CharArray csq, Cursor cursor)
827      throws NumberFormatException {
828      // Parsing block identical for all CharSequences.
829      final int start = (cursor != null) ? cursor.getIndex() : 0;
830      final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
831      int i = start;
832      char c = csq.charAt(i);
833      
834      // Checks for NaN.
835      if ((c == 'N') && match("NaN", csq, i, length)) {
836      if (cursor != null) cursor.setIndex(i + 3);
837      return Double.NaN;
838      }
839      
840      // Reads sign.
841      boolean isNegative = (c == '-');
842      if ((isNegative || (c == '+')) && (++i < length)) {
843      c = csq.charAt(i);
844      }
845      
846      // Checks for Infinity.
847      if ((c == 'I') && match("Infinity", csq, i, length)) {
848      if (cursor != null) cursor.setIndex(i + 8);
849      return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
850      }
851      
852      // Reads decimal and fraction (both merged to a long).
853      long decimal = 0;
854      int decimalPoint = -1;
855      while (true) {
856      int digit = c - '0';
857      if ((digit >= 0) && (digit < 10)) {
858      long tmp = decimal * 10 + digit;
859      if (tmp < decimal)
860      throw new NumberFormatException("Too many digits - Overflow");
861      decimal = tmp;
862      } else if (c == '.') {
863      decimalPoint = i;
864      } else {
865      break; // Done.
866      }
867      if (++i >= length)
868      break;
869      c = csq.charAt(i);
870      }
871      if (isNegative) {
872      decimal = - decimal;
873      }
874      int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
875      
876      // Reads exponent.
877      int exp = 0;
878      if ((i < length) && ((c == 'E') || (c == 'e'))) {
879      c = csq.charAt(++i);
880      boolean isNegativeExp = (c == '-');
881      if ((isNegativeExp || (c == '+')) && (++i < length)) {
882      c = csq.charAt(i);
883      }
884      while (true) {
885      int digit = c - '0';
886      if ((digit >= 0) && (digit < 10)) {
887      int tmp = exp * 10 + digit;
888      if (tmp < exp)
889      throw new NumberFormatException("Exponent Overflow");
890      exp = tmp;
891      } else {
892      break; // Done.
893      }
894      if (++i >= length)
895      break;
896      c = csq.charAt(i);
897      }
898      if (isNegativeExp) {
899      exp = -exp;
900      }
901      }
902      if (cursor != null)
903      cursor.setIndex(i);
904      return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
905      }
906      
907      private static double parseDoubleTextBuilder(TextBuilder csq, Cursor cursor)
908      throws NumberFormatException {
909      // Parsing block identical for all CharSequences.
910      final int start = (cursor != null) ? cursor.getIndex() : 0;
911      final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
912      int i = start;
913      char c = csq.charAt(i);
914      
915      // Checks for NaN.
916      if ((c == 'N') && match("NaN", csq, i, length)) {
917      if (cursor != null) cursor.setIndex(i + 3);
918      return Double.NaN;
919      }
920      
921      // Reads sign.
922      boolean isNegative = (c == '-');
923      if ((isNegative || (c == '+')) && (++i < length)) {
924      c = csq.charAt(i);
925      }
926      
927      // Checks for Infinity.
928      if ((c == 'I') && match("Infinity", csq, i, length)) {
929      if (cursor != null) cursor.setIndex(i + 8);
930      return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
931      }
932      
933      // Reads decimal and fraction (both merged to a long).
934      long decimal = 0;
935      int decimalPoint = -1;
936      while (true) {
937      int digit = c - '0';
938      if ((digit >= 0) && (digit < 10)) {
939      long tmp = decimal * 10 + digit;
940      if (tmp < decimal)
941      throw new NumberFormatException("Too many digits - Overflow");
942      decimal = tmp;
943      } else if (c == '.') {
944      decimalPoint = i;
945      } else {
946      break; // Done.
947      }
948      if (++i >= length)
949      break;
950      c = csq.charAt(i);
951      }
952      if (isNegative) {
953      decimal = - decimal;
954      }
955      int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
956      
957      // Reads exponent.
958      int exp = 0;
959      if ((i < length) && ((c == 'E') || (c == 'e'))) {
960      c = csq.charAt(++i);
961      boolean isNegativeExp = (c == '-');
962      if ((isNegativeExp || (c == '+')) && (++i < length)) {
963      c = csq.charAt(i);
964      }
965      while (true) {
966      int digit = c - '0';
967      if ((digit >= 0) && (digit < 10)) {
968      int tmp = exp * 10 + digit;
969      if (tmp < exp)
970      throw new NumberFormatException("Exponent Overflow");
971      exp = tmp;
972      } else {
973      break; // Done.
974      }
975      if (++i >= length)
976      break;
977      c = csq.charAt(i);
978      }
979      if (isNegativeExp) {
980      exp = -exp;
981      }
982      }
983      if (cursor != null)
984      cursor.setIndex(i);
985      return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
986      }
987
988      private static double parseDoubleText(Text csq, Cursor cursor)
989      throws NumberFormatException {
990      // Parsing block identical for all CharSequences.
991      final int start = (cursor != null) ? cursor.getIndex() : 0;
992      final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
993      int i = start;
994      char c = csq.charAt(i);
995      
996      // Checks for NaN.
997      if ((c == 'N') && match("NaN", csq, i, length)) {
998      if (cursor != null) cursor.setIndex(i + 3);
999      return Double.NaN;
1000     }
1001     
1002     // Reads sign.
1003     boolean isNegative = (c == '-');
1004     if ((isNegative || (c == '+')) && (++i < length)) {
1005     c = csq.charAt(i);
1006     }
1007     
1008     // Checks for Infinity.
1009     if ((c == 'I') && match("Infinity", csq, i, length)) {
1010     if (cursor != null) cursor.setIndex(i + 8);
1011     return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
1012     }
1013     
1014     // Reads decimal and fraction (both merged to a long).
1015     long decimal = 0;
1016     int decimalPoint = -1;
1017     while (true) {
1018     int digit = c - '0';
1019     if ((digit >= 0) && (digit < 10)) {
1020     long tmp = decimal * 10 + digit;
1021     if (tmp < decimal)
1022     throw new NumberFormatException("Too many digits - Overflow");
1023     decimal = tmp;
1024     } else if (c == '.') {
1025     decimalPoint = i;
1026     } else {
1027     break; // Done.
1028     }
1029     if (++i >= length)
1030     break;
1031     c = csq.charAt(i);
1032     }
1033     if (isNegative) {
1034     decimal = - decimal;
1035     }
1036     int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1037     
1038     // Reads exponent.
1039     int exp = 0;
1040     if ((i < length) && ((c == 'E') || (c == 'e'))) {
1041     c = csq.charAt(++i);
1042     boolean isNegativeExp = (c == '-');
1043     if ((isNegativeExp || (c == '+')) && (++i < length)) {
1044     c = csq.charAt(i);
1045     }
1046     while (true) {
1047     int digit = c - '0';
1048     if ((digit >= 0) && (digit < 10)) {
1049     int tmp = exp * 10 + digit;
1050     if (tmp < exp)
1051     throw new NumberFormatException("Exponent Overflow");
1052     exp = tmp;
1053     } else {
1054     break; // Done.
1055     }
1056     if (++i >= length)
1057     break;
1058     c = csq.charAt(i);
1059     }
1060     if (isNegativeExp) {
1061     exp = -exp;
1062     }
1063     }
1064     if (cursor != null)
1065     cursor.setIndex(i);
1066     return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1067     }
1068     
1069     private static double parseDoubleString(String csq, Cursor cursor)
1070     throws NumberFormatException {
1071     // Parsing block identical for all CharSequences.
1072     final int start = (cursor != null) ? cursor.getIndex() : 0;
1073     final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
1074     int i = start;
1075     char c = csq.charAt(i);
1076     
1077     // Checks for NaN.
1078     if ((c == 'N') && match("NaN", csq, i, length)) {
1079     if (cursor != null) cursor.setIndex(i + 3);
1080     return Double.NaN;
1081     }
1082     
1083     // Reads sign.
1084     boolean isNegative = (c == '-');
1085     if ((isNegative || (c == '+')) && (++i < length)) {
1086     c = csq.charAt(i);
1087     }
1088     
1089     // Checks for Infinity.
1090     if ((c == 'I') && match("Infinity", csq, i, length)) {
1091     if (cursor != null) cursor.setIndex(i + 8);
1092     return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
1093     }
1094     
1095     // Reads decimal and fraction (both merged to a long).
1096     long decimal = 0;
1097     int decimalPoint = -1;
1098     while (true) {
1099     int digit = c - '0';
1100     if ((digit >= 0) && (digit < 10)) {
1101     long tmp = decimal * 10 + digit;
1102     if (tmp < decimal)
1103     throw new NumberFormatException("Too many digits - Overflow");
1104     decimal = tmp;
1105     } else if (c == '.') {
1106     decimalPoint = i;
1107     } else {
1108     break; // Done.
1109     }
1110     if (++i >= length)
1111     break;
1112     c = csq.charAt(i);
1113     }
1114     if (isNegative) {
1115     decimal = - decimal;
1116     }
1117     int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1118     
1119     // Reads exponent.
1120     int exp = 0;
1121     if ((i < length) && ((c == 'E') || (c == 'e'))) {
1122     c = csq.charAt(++i);
1123     boolean isNegativeExp = (c == '-');
1124     if ((isNegativeExp || (c == '+')) && (++i < length)) {
1125     c = csq.charAt(i);
1126     }
1127     while (true) {
1128     int digit = c - '0';
1129     if ((digit >= 0) && (digit < 10)) {
1130     int tmp = exp * 10 + digit;
1131     if (tmp < exp)
1132     throw new NumberFormatException("Exponent Overflow");
1133     exp = tmp;
1134     } else {
1135     break; // Done.
1136     }
1137     if (++i >= length)
1138     break;
1139     c = csq.charAt(i);
1140     }
1141     if (isNegativeExp) {
1142     exp = -exp;
1143     }
1144     }
1145     if (cursor != null)
1146     cursor.setIndex(i);
1147     return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1148     }
1149     
1150     private static double parseDoubleCharSequence(CharSequence csq, Cursor cursor)
1151     throws NumberFormatException {
1152     // Parsing block identical for all CharSequences.
1153     final int start = (cursor != null) ? cursor.getIndex() : 0;
1154     final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
1155     int i = start;
1156     char c = csq.charAt(i);
1157     
1158     // Checks for NaN.
1159     if ((c == 'N') && match("NaN", csq, i, length)) {
1160     if (cursor != null) cursor.setIndex(i + 3);
1161     return Double.NaN;
1162     }
1163     
1164     // Reads sign.
1165     boolean isNegative = (c == '-');
1166     if ((isNegative || (c == '+')) && (++i < length)) {
1167     c = csq.charAt(i);
1168     }
1169     
1170     // Checks for Infinity.
1171     if ((c == 'I') && match("Infinity", csq, i, length)) {
1172     if (cursor != null) cursor.setIndex(i + 8);
1173     return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
1174     }
1175     
1176     // Reads decimal and fraction (both merged to a long).
1177     long decimal = 0;
1178     int decimalPoint = -1;
1179     while (true) {
1180     int digit = c - '0';
1181     if ((digit >= 0) && (digit < 10)) {
1182     long tmp = decimal * 10 + digit;
1183     if (tmp < decimal)
1184     throw new NumberFormatException("Too many digits - Overflow");
1185     decimal = tmp;
1186     } else if (c == '.') {
1187     decimalPoint = i;
1188     } else {
1189     break; // Done.
1190     }
1191     if (++i >= length)
1192     break;
1193     c = csq.charAt(i);
1194     }
1195     if (isNegative) {
1196     decimal = - decimal;
1197     }
1198     int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1199     
1200     // Reads exponent.
1201     int exp = 0;
1202     if ((i < length) && ((c == 'E') || (c == 'e'))) {
1203     c = csq.charAt(++i);
1204     boolean isNegativeExp = (c == '-');
1205     if ((isNegativeExp || (c == '+')) && (++i < length)) {
1206     c = csq.charAt(i);
1207     }
1208     while (true) {
1209     int digit = c - '0';
1210     if ((digit >= 0) && (digit < 10)) {
1211     int tmp = exp * 10 + digit;
1212     if (tmp < exp)
1213     throw new NumberFormatException("Exponent Overflow");
1214     exp = tmp;
1215     } else {
1216     break; // Done.
1217     }
1218     if (++i >= length)
1219     break;
1220     c = csq.charAt(i);
1221     }
1222     if (isNegativeExp) {
1223     exp = -exp;
1224     }
1225     }
1226     if (cursor != null)
1227     cursor.setIndex(i);
1228     return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1229     }
1230     
1231     static boolean match(String str, CharSequence csq, int start, int length) {
1232     for (int i = 0; i < str.length(); i++) {
1233     if ((start + i >= length)
1234     || csq.charAt(start + i) != str.charAt(i))
1235     return false;
1236     }
1237     return true;
1238     }
1239     static boolean match(String str, String csq, int start, int length) {
1240     for (int i = 0; i < str.length(); i++) {
1241     if ((start + i >= length)
1242     || csq.charAt(start + i) != str.charAt(i))
1243     return false;
1244     }
1245     return true;
1246     }
1247     /**/

1248
1249    /**
1250     * Formats the specified <code>boolean</code> and appends the resulting
1251     * text to the <code>Appendable</code> argument.
1252     *
1253     * @param b a <code>boolean</code>.
1254     * @param a the <code>Appendable</code> to append.
1255     * @return the specified <code>StringBuffer</code> object.
1256     * @throws IOException if an I/O exception occurs.
1257     * @see #parseBoolean
1258     */

1259    public static Appendable JavaDoc format(boolean b, Appendable JavaDoc a) throws IOException JavaDoc {
1260        return b ? a.append('t').append('r').append('u').append('e') : a
1261                .append('f').append('a').append('l').append('s').append('e');
1262    }
1263
1264    /**
1265     * Formats the specified <code>int</code> and appends the resulting
1266     * text (decimal representation) to the <code>Appendable</code> argument.
1267     *
1268     * <p> Note: This method is preferred to <code>Appendable.append(int)
1269     * </code> as it does not create temporary <code>String</code>
1270     * objects (several times faster for small numbers).</p>
1271     *
1272     * @param i the <code>int</code> number.
1273     * @param a the <code>Appendable</code> to append.
1274     * @return the specified <code>Appendable</code> object.
1275     * @throws IOException if an I/O exception occurs.
1276     * @see #parseInt
1277     */

1278    public static Appendable JavaDoc format(int i, Appendable JavaDoc a) throws IOException JavaDoc {
1279        if (a instanceof TextBuilder)
1280            return ((TextBuilder) a).append(i);
1281        TextBuilder tmp = TextBuilder.newInstance();
1282        tmp.append(i);
1283        appendTo(a, tmp);
1284        TextBuilder.recycle(tmp);
1285        return a;
1286    }
1287
1288    /**
1289     * Formats the specified <code>int</code> in the specified radix and appends
1290     * the resulting text to the <code>Appendable</code> argument.
1291     *
1292     * @param i the <code>int</code> number.
1293     * @param radix the radix.
1294     * @param a the <code>Appendable</code> to append.
1295     * @return the specified <code>Appendable</code> object.
1296     * @throws IllegalArgumentException if radix is not in [2 .. 36] range.
1297     * @throws IOException if an I/O exception occurs.
1298     * @see #parseInt(CharSequence, int)
1299     */

1300    public static Appendable JavaDoc format(int i, int radix, Appendable JavaDoc a)
1301            throws IOException JavaDoc {
1302        if (a instanceof TextBuilder)
1303            return ((TextBuilder) a).append(i, radix);
1304        TextBuilder tmp = TextBuilder.newInstance();
1305        tmp.append(i, radix);
1306        appendTo(a, tmp);
1307        TextBuilder.recycle(tmp);
1308        return a;
1309    }
1310
1311    /**
1312     * Formats the specified <code>long</code> and appends the resulting
1313     * text (decimal representation) to the <code>Appendable</code> argument.
1314     *
1315     * <p> Note: This method is preferred to <code>Appendable.append(long)
1316     * </code> as it does not create temporary <code>String</code>
1317     * objects (several times faster for small numbers).</p>
1318     *
1319     * @param l the <code>long</code> number.
1320     * @param a the <code>Appendable</code> to append.
1321     * @return the specified <code>Appendable</code> object.
1322     * @throws IOException if an I/O exception occurs.
1323     * @see #parseLong
1324     */

1325    public static Appendable JavaDoc format(long l, Appendable JavaDoc a) throws IOException JavaDoc {
1326        if (a instanceof TextBuilder)
1327            return ((TextBuilder) a).append(l);
1328        TextBuilder tmp = TextBuilder.newInstance();
1329        tmp.append(l);
1330        appendTo(a, tmp);
1331        TextBuilder.recycle(tmp);
1332        return a;
1333    }
1334
1335    /**
1336     * Formats the specified <code>long</code> in the specified radix and
1337     * appends the resulting text to the <code>Appendable</code> argument.
1338     *
1339     * @param l the <code>long</code> number.
1340     * @param radix the radix.
1341     * @param a the <code>Appendable</code> to append.
1342     * @return the specified <code>Appendable</code> object.
1343     * @throws IllegalArgumentException if radix is not in [2 .. 36] range.
1344     * @throws IOException if an I/O exception occurs.
1345     * @see #parseLong(CharSequence, int)
1346     */

1347    public static Appendable JavaDoc format(long l, int radix, Appendable JavaDoc a)
1348            throws IOException JavaDoc {
1349        if (a instanceof TextBuilder)
1350            return ((TextBuilder) a).append(l);
1351        TextBuilder tmp = TextBuilder.newInstance();
1352        tmp.append(l, radix);
1353        appendTo(a, tmp);
1354        TextBuilder.recycle(tmp);
1355        return a;
1356    }
1357
1358    /**
1359     * Formats the specified <code>float</code> value.
1360     *
1361     * @param f the <code>float</code> value.
1362     * @param a the <code>Appendable</code> to append.
1363     * @return the specified <code>Appendable</code> object.
1364     * @throws IOException if an I/O exception occurs.
1365     * @see TextBuilder#append(float)
1366     *@JVM-1.1+@
1367     public static Appendable format(float f, Appendable a)
1368     throws IOException {
1369     if (a instanceof TextBuilder)
1370     return ((TextBuilder) a).append(f);
1371     TextBuilder tmp = TextBuilder.newInstance();
1372     tmp.append(f);
1373     appendTo(a, tmp);
1374     TextBuilder.recycle(tmp);
1375     return a;
1376     }
1377     /**/

1378
1379    /**
1380     * Formats the specified <code>double</code> value (16 or 17 digits output).
1381     *
1382     * @param d the <code>double</code> value.
1383     * @param a the <code>Appendable</code> to append.
1384     * @return the specified <code>Appendable</code> object.
1385     * @throws IOException if an I/O exception occurs.
1386     * @see TextBuilder#append(double)
1387     *@JVM-1.1+@
1388     public static Appendable format(double d, Appendable a)
1389     throws IOException {
1390     if (a instanceof TextBuilder)
1391     return ((TextBuilder) a).append(d);
1392     TextBuilder tmp = TextBuilder.newInstance();
1393     tmp.append(d);
1394     appendTo(a, tmp);
1395     TextBuilder.recycle(tmp);
1396     return a;
1397     }
1398     /**/

1399
1400    /**
1401     * Formats the specified <code>double</code> value according to the
1402     * specified formatting arguments.
1403     *
1404     * @param d the <code>double</code> value.
1405     * @param digits the number of significative digits (excludes exponent) or
1406     * <code>-1</code> to mimic the standard library (16 or 17 digits).
1407     * @param scientific <code>true</code> to forces the use of the scientific
1408     * notation (e.g. <code>1.23E3</code>); <code>false</code>
1409     * otherwise.
1410     * @param showZero <code>true</code> if trailing fractional zeros are
1411     * represented; <code>false</code> otherwise.
1412     * @param a the <code>Appendable</code> to append.
1413     * @return the specified <code>Appendable</code> object.
1414     * @throws IllegalArgumentException if <code>(digits &gt; 19)</code>)
1415     * @throws IOException if an I/O exception occurs.
1416     * @see TextBuilder#append(double, int, boolean, boolean)
1417     *@JVM-1.1+@
1418     public static Appendable format(double d, int digits,
1419     boolean scientific, boolean showZero, Appendable a) throws IOException {
1420     if (a instanceof TextBuilder)
1421     return ((TextBuilder) a).append(d, digits, scientific, showZero);
1422     TextBuilder tmp = TextBuilder.newInstance();
1423     tmp.append(d, digits, scientific, showZero);
1424     appendTo(a, tmp);
1425     TextBuilder.recycle(tmp);
1426     return a;
1427     }
1428     /**/

1429
1430    /**
1431     * Appends to the specified appendable the text builder argument
1432     * (for text builder less than 32 characters).
1433     *
1434     * @param a the appendable.
1435     * @param txt the text to be append.
1436     * @throws IOException if an I/O exception occurs.
1437     */

1438    private static void appendTo(Object JavaDoc to, TextBuilder txt) throws IOException JavaDoc {
1439        if (to instanceof StringBuffer JavaDoc) {
1440            txt.appendTo((StringBuffer JavaDoc) to);
1441        /* @JVM-1.5+@
1442        } else if (to instanceof StringBuilder) {
1443            txt.appendTo((StringBuilder) to);
1444        /**/

1445        } else {
1446            ((Appendable JavaDoc) to).append(txt);
1447        }
1448    }
1449
1450}
Popular Tags