Source Code Cross Referenced for TypeFormat.java in  » Science » javolution-5.2 » javolution » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » javolution 5.2 » javolution.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
0003:         * Copyright (C) 2006 - Javolution (http://javolution.org/)
0004:         * All rights reserved.
0005:         * 
0006:         * Permission to use, copy, modify, and distribute this software is
0007:         * freely granted, provided that this notice is preserved.
0008:         */
0009:        package javolution.text;
0010:
0011:        import j2me.lang.CharSequence;
0012:        import javolution.text.TextFormat.Cursor;
0013:
0014:        import java.io.IOException;
0015:
0016:        /**
0017:         * <p> This class provides utility methods to parse <code>CharSequence</code>
0018:         *     into primitive types and to format primitive types into any 
0019:         *     <code>Appendable</code>.</p>
0020:         *
0021:         * <p> Methods from this class <b>do not create temporary objects</b> and
0022:         *     are typically faster than standard library methods (see 
0023:         *     <a href="http://javolution.org/doc/benchmark.html">benchmark</a>).</p>
0024:         *     
0025:         * <p> The number of digits when formatting floating point numbers can be 
0026:         *     specified. The default setting for <code>double</code> is 17 digits 
0027:         *     or even 16 digits when the conversion is lossless back and forth
0028:         *     (mimic the standard library formatting). For example:[code]
0029:         *         TypeFormat.format(0.2, a) = "0.2" // 17 or 16 digits (as long as lossless conversion), remove trailing zeros.
0030:         *         TypeFormat.format(0.2, 17, false, false, a) = "0.20000000000000001" // Closest 17 digits number.
0031:         *         TypeFormat.format(0.2, 19, false, false, a) = "0.2000000000000000111" // Closest 19 digits.
0032:         *         TypeFormat.format(0.2, 4, false, false, a) = "0.2" // Fixed-point notation, remove trailing zeros.
0033:         *         TypeFormat.format(0.2, 4, false, true, a) = "0.2000" // Fixed-point notation, fixed number of digits.
0034:         *         TypeFormat.format(0.2, 4, true, false, a) = "2.0E-1" // Scientific notation, remove trailing zeros.  
0035:         *         TypeFormat.format(0.2, 4, true, true, a) = "2.000E-1" // Scientific notation, fixed number of digits.
0036:         *         [/code]</p>        
0037:         *
0038:         * <p> For non-primitive objects, formatting is typically performed using 
0039:         *     specialized {@link TextFormat} instances.</p>
0040:         * 
0041:         * @author  <a href="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
0042:         * @version 4.1, November 30, 2006
0043:         */
0044:        public final class TypeFormat {
0045:
0046:            /**
0047:             * Default constructor (forbids derivation).
0048:             */
0049:            private TypeFormat() {
0050:            }
0051:
0052:            /**
0053:             * Parses the specified character sequence as a <code>boolean</code>.
0054:             *
0055:             * @param  csq the character sequence to parse.
0056:             * @return the corresponding boolean value.
0057:             * @throws IllegalArgumentException if the specified character sequence 
0058:             *         is different from "true" or "false" ignoring cases.
0059:             */
0060:            public static boolean parseBoolean(CharSequence csq) {
0061:                if ((csq.length() == 4)
0062:                        && (csq.charAt(0) == 't' || csq.charAt(0) == 'T')
0063:                        && (csq.charAt(1) == 'r' || csq.charAt(1) == 'R')
0064:                        && (csq.charAt(2) == 'u' || csq.charAt(2) == 'U')
0065:                        && (csq.charAt(3) == 'e' || csq.charAt(3) == 'E')) {
0066:                    return true;
0067:                } else if ((csq.length() == 5)
0068:                        && (csq.charAt(0) == 'f' || csq.charAt(0) == 'F')
0069:                        && (csq.charAt(1) == 'a' || csq.charAt(1) == 'A')
0070:                        && (csq.charAt(2) == 'l' || csq.charAt(2) == 'L')
0071:                        && (csq.charAt(3) == 's' || csq.charAt(3) == 'S')
0072:                        && (csq.charAt(4) == 'e' || csq.charAt(4) == 'E')) {
0073:                    return false;
0074:                }
0075:                throw new IllegalArgumentException("Cannot parse " + csq
0076:                        + " as boolean");
0077:            }
0078:
0079:            /**
0080:             * Equivalent to {@link #parseBoolean(CharSequence)} 
0081:             * (for J2ME compatibility).
0082:             */
0083:            public static boolean parseBoolean(String csq) {
0084:                if ((csq.length() == 4)
0085:                        && (csq.charAt(0) == 't' || csq.charAt(0) == 'T')
0086:                        && (csq.charAt(1) == 'r' || csq.charAt(1) == 'R')
0087:                        && (csq.charAt(2) == 'u' || csq.charAt(2) == 'U')
0088:                        && (csq.charAt(3) == 'e' || csq.charAt(3) == 'E')) {
0089:                    return true;
0090:                } else if ((csq.length() == 5)
0091:                        && (csq.charAt(0) == 'f' || csq.charAt(0) == 'F')
0092:                        && (csq.charAt(1) == 'a' || csq.charAt(1) == 'A')
0093:                        && (csq.charAt(2) == 'l' || csq.charAt(2) == 'L')
0094:                        && (csq.charAt(3) == 's' || csq.charAt(3) == 'S')
0095:                        && (csq.charAt(4) == 'e' || csq.charAt(4) == 'E')) {
0096:                    return false;
0097:                }
0098:                throw new IllegalArgumentException("Cannot parse " + csq
0099:                        + " as boolean");
0100:            }
0101:
0102:            /**
0103:             * Parses the specified character sequence from the specified position 
0104:             * as a <code>boolean</code>.
0105:             *
0106:             * @param csq the character sequence to parse.
0107:             * @param cursor the current cursor position (being maintained).
0108:             * @return the next boolean value.
0109:             * @throws IllegalArgumentException if the character sequence from the 
0110:             *         specified position is different from "true" or "false" ignoring
0111:             *         cases.
0112:             */
0113:            public static boolean parseBoolean(CharSequence csq, Cursor cursor) {
0114:                final int i = cursor.getIndex();
0115:                if ((cursor.getEndIndex() >= i + 4)
0116:                        && (csq.charAt(i) == 't' || csq.charAt(i) == 'T')
0117:                        && (csq.charAt(i + 1) == 'r' || csq.charAt(i + 1) == 'R')
0118:                        && (csq.charAt(i + 2) == 'u' || csq.charAt(i + 2) == 'U')
0119:                        && (csq.charAt(i + 3) == 'e' || csq.charAt(i + 3) == 'E')) {
0120:                    cursor.increment(4);
0121:                    return true;
0122:                }
0123:                if ((cursor.getEndIndex() >= i + 5)
0124:                        && (csq.charAt(i) == 'f' || csq.charAt(i) == 'F')
0125:                        && (csq.charAt(i + 1) == 'a' || csq.charAt(i + 1) == 'A')
0126:                        && (csq.charAt(i + 2) == 'l' || csq.charAt(i + 2) == 'L')
0127:                        && (csq.charAt(i + 3) == 's' || csq.charAt(i + 3) == 'S')
0128:                        && (csq.charAt(i + 4) == 'e' || csq.charAt(i + 4) == 'E')) {
0129:                    cursor.increment(5);
0130:                    return false;
0131:                }
0132:                throw new IllegalArgumentException("Cannot parse boolean "
0133:                        + csq.subSequence(cursor.getIndex(), cursor
0134:                                .getEndIndex()));
0135:            }
0136:
0137:            /**
0138:             * Parses the specified character sequence as a signed decimal 
0139:             * <code>byte</code>.
0140:             *
0141:             * @param  csq the character sequence to parse.
0142:             * @return <code>parseByte(csq, 10)</code>
0143:             * @throws NumberFormatException if the specified character sequence
0144:             *         does not contain a parsable <code>byte</code>.
0145:             * @see    #parseByte(CharSequence, int)
0146:             */
0147:            public static byte parseByte(CharSequence csq) {
0148:                return parseByte(csq, 10);
0149:            }
0150:
0151:            /**
0152:             * Parses the specified character sequence as a signed <code>byte</code> 
0153:             * in the specified radix.
0154:             *
0155:             * @param  csq the character sequence to parse.
0156:             * @param  radix the radix to be used while parsing.
0157:             * @return the corresponding <code>byte</code>.
0158:             * @throws NumberFormatException if the specified character sequence
0159:             *         does not contain a parsable <code>byte</code>.
0160:             */
0161:            public static byte parseByte(CharSequence csq, int radix) {
0162:                int i = parseInt(csq, radix);
0163:                if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE))
0164:                    throw new NumberFormatException("Overflow");
0165:                return (byte) i;
0166:            }
0167:
0168:            /**
0169:             * Parses the specified character sequence from the specified position 
0170:             * as a signed <code>byte</code> in the specified radix.
0171:             *
0172:             * @param  csq the character sequence to parse.
0173:             * @param  radix the radix to be used while parsing.
0174:             * @param cursor the current cursor position (being maintained).
0175:             * @return the corresponding <code>byte</code>.
0176:             * @throws NumberFormatException if the specified character sequence
0177:             *         does not contain a parsable <code>byte</code>.
0178:             */
0179:            public static byte parseByte(CharSequence csq, int radix,
0180:                    Cursor cursor) {
0181:                int i = parseInt(csq, radix, cursor);
0182:                if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE))
0183:                    throw new NumberFormatException("Overflow");
0184:                return (byte) i;
0185:            }
0186:
0187:            /**
0188:             * Parses the specified character sequence as a signed decimal 
0189:             * <code>short</code>.
0190:             *
0191:             * @param  csq the character sequence to parse.
0192:             * @return <code>parseShort(csq, 10)</code>
0193:             * @throws NumberFormatException if the specified character sequence
0194:             *         does not contain a parsable <code>short</code>.
0195:             * @see    #parseShort(CharSequence, int)
0196:             */
0197:            public static short parseShort(CharSequence csq) {
0198:                return parseShort(csq, 10);
0199:            }
0200:
0201:            /**
0202:             * Parses the specified character sequence as a signed <code>short</code> 
0203:             * in the specified radix.
0204:             *
0205:             * @param  csq the character sequence to parse.
0206:             * @param  radix the radix to be used while parsing.
0207:             * @return the corresponding <code>short</code>.
0208:             * @throws NumberFormatException if the specified character sequence
0209:             *         does not contain a parsable <code>short</code>.
0210:             */
0211:            public static short parseShort(CharSequence csq, int radix) {
0212:                int i = parseInt(csq, radix);
0213:                if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE))
0214:                    throw new NumberFormatException("Overflow");
0215:                return (short) i;
0216:            }
0217:
0218:            /**
0219:             * Parses the specified character sequence from the specified position 
0220:             * as a signed <code>short</code> in the specified radix.
0221:             *
0222:             * @param  csq the character sequence to parse.
0223:             * @param  radix the radix to be used while parsing.
0224:             * @param cursor the current cursor position (being maintained).
0225:             * @return the corresponding <code>short</code>.
0226:             * @throws NumberFormatException if the specified character sequence
0227:             *         does not contain a parsable <code>short</code>.
0228:             */
0229:            public static short parseShort(CharSequence csq, int radix,
0230:                    Cursor cursor) {
0231:                int i = parseInt(csq, radix, cursor);
0232:                if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE))
0233:                    throw new NumberFormatException("Overflow");
0234:                return (short) i;
0235:            }
0236:
0237:            /**
0238:             * Parses the specified character sequence as a signed <code>int</code>.
0239:             *
0240:             * @param  csq the character sequence to parse.
0241:             * @return <code>parseInt(csq, 10)</code>
0242:             * @throws NumberFormatException if the specified character sequence
0243:             *         does not contain a parsable <code>int</code>.
0244:             * @see    #parseInt(CharSequence, int)
0245:             */
0246:            public static int parseInt(CharSequence csq) {
0247:                return parseInt(csq, 10);
0248:            }
0249:
0250:            /**
0251:             * Equivalent to {@link #parseInt(CharSequence)} (for J2ME compatibility).
0252:             */
0253:            public static int parseInt(String str) {
0254:                return parseIntString(str, 10, null);
0255:            }
0256:
0257:            /**
0258:             * Parses the specified character sequence as a signed <code>int</code> 
0259:             * in the specified radix.
0260:             *
0261:             * @param  csq the character sequence to parse.
0262:             * @param  radix the radix to be used while parsing.
0263:             * @return the corresponding <code>int</code>.
0264:             * @throws NumberFormatException if the specified character sequence
0265:             *         does not contain a parsable <code>int</code>.
0266:             */
0267:            public static int parseInt(CharSequence csq, int radix) {
0268:                return parseInt(csq, radix, null);
0269:            }
0270:
0271:            /**
0272:             * Equivalent to {@link #parseInt(CharSequence, int)} 
0273:             * (for J2ME compatibility).
0274:             */
0275:            public static int parseInt(String str, int radix) {
0276:                return parseIntString(str, radix, null);
0277:            }
0278:
0279:            /**
0280:             * Parses the specified character sequence from the specified position
0281:             * as a signed <code>int</code> in the specified radix.
0282:             *
0283:             * @param  csq the character sequence to parse.
0284:             * @param  radix the radix to be used while parsing.
0285:             * @param  cursor the current cursor position (being maintained) or
0286:             *         <code>null</code> if the whole character sequence is parsed.
0287:             * @return the corresponding <code>int</code>.
0288:             * @throws NumberFormatException if the specified character sequence
0289:             *         does not contain a parsable <code>int</code>.
0290:             */
0291:            public static int parseInt(CharSequence csq, int radix,
0292:                    Cursor cursor) {
0293:                // Avoids dynamic cost of CharSequence.charAt
0294:                if (csq instanceof  CharArray)
0295:                    return parseIntCharArray((CharArray) csq, radix, cursor);
0296:                if (csq instanceof  TextBuilder)
0297:                    return parseIntTextBuilder((TextBuilder) csq, radix, cursor);
0298:                if (csq instanceof  Text)
0299:                    return parseIntText((Text) csq, radix, cursor);
0300:                if (((Object) csq) instanceof  String)
0301:                    return parseIntString((String) ((Object) csq), radix,
0302:                            cursor);
0303:                return parseIntCharSequence(csq, radix, cursor);
0304:            }
0305:
0306:            private static int parseIntCharArray(CharArray csq, int radix,
0307:                    Cursor cursor) {
0308:                // Parsing block identical for all CharSequences.
0309:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0310:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0311:                        .length();
0312:                boolean isNegative = false;
0313:                int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0314:                int i = start;
0315:                for (; i < end; i++) {
0316:                    char c = csq.charAt(i);
0317:                    int digit = (c <= '9') ? c - '0'
0318:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0319:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0320:                                            : -1;
0321:                    if ((digit >= 0) && (digit < radix)) {
0322:                        int newResult = result * radix - digit;
0323:                        if (newResult > result)
0324:                            throw new NumberFormatException("Overflow");
0325:                        result = newResult;
0326:                    } else if ((c == '-') && (i == start)) {
0327:                        isNegative = true;
0328:                    } else if ((c == '+') && (i == start)) {
0329:                        // Ok.
0330:                    } else {
0331:                        if (cursor == null)
0332:                            throw new NumberFormatException(
0333:                                    "Incomplete parsing");
0334:                        break; // Done.
0335:                    }
0336:                }
0337:                // Requires one valid digit character and checks for opposite overflow.
0338:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0339:                    throw new NumberFormatException("Cannot parse " + csq
0340:                            + " as int");
0341:                if ((result == Integer.MIN_VALUE) && !isNegative)
0342:                    throw new NumberFormatException("Overflow");
0343:                if (cursor != null)
0344:                    cursor.setIndex(i);
0345:                return isNegative ? result : -result;
0346:            }
0347:
0348:            private static int parseIntTextBuilder(TextBuilder csq, int radix,
0349:                    Cursor cursor) {
0350:                // Parsing block identical for all CharSequences.
0351:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0352:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0353:                        .length();
0354:                boolean isNegative = false;
0355:                int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0356:                int i = start;
0357:                for (; i < end; i++) {
0358:                    char c = csq.charAt(i);
0359:                    int digit = (c <= '9') ? c - '0'
0360:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0361:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0362:                                            : -1;
0363:                    if ((digit >= 0) && (digit < radix)) {
0364:                        int newResult = result * radix - digit;
0365:                        if (newResult > result)
0366:                            throw new NumberFormatException("Overflow");
0367:                        result = newResult;
0368:                    } else if ((c == '-') && (i == start)) {
0369:                        isNegative = true;
0370:                    } else if ((c == '+') && (i == start)) {
0371:                        // Ok.
0372:                    } else {
0373:                        if (cursor == null)
0374:                            throw new NumberFormatException(
0375:                                    "Incomplete parsing");
0376:                        break; // Done.
0377:                    }
0378:                }
0379:                // Requires one valid digit character and checks for opposite overflow.
0380:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0381:                    throw new NumberFormatException("Cannot parse " + csq
0382:                            + " as int");
0383:                if ((result == Integer.MIN_VALUE) && !isNegative)
0384:                    throw new NumberFormatException("Overflow");
0385:                if (cursor != null)
0386:                    cursor.setIndex(i);
0387:                return isNegative ? result : -result;
0388:            }
0389:
0390:            private static int parseIntText(Text csq, int radix, Cursor cursor) {
0391:                // Parsing block identical for all CharSequences.
0392:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0393:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0394:                        .length();
0395:                boolean isNegative = false;
0396:                int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0397:                int i = start;
0398:                for (; i < end; i++) {
0399:                    char c = csq.charAt(i);
0400:                    int digit = (c <= '9') ? c - '0'
0401:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0402:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0403:                                            : -1;
0404:                    if ((digit >= 0) && (digit < radix)) {
0405:                        int newResult = result * radix - digit;
0406:                        if (newResult > result)
0407:                            throw new NumberFormatException("Overflow");
0408:                        result = newResult;
0409:                    } else if ((c == '-') && (i == start)) {
0410:                        isNegative = true;
0411:                    } else if ((c == '+') && (i == start)) {
0412:                        // Ok.
0413:                    } else {
0414:                        if (cursor == null)
0415:                            throw new NumberFormatException(
0416:                                    "Incomplete parsing");
0417:                        break; // Done.
0418:                    }
0419:                }
0420:                // Requires one valid digit character and checks for opposite overflow.
0421:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0422:                    throw new NumberFormatException("Cannot parse " + csq
0423:                            + " as int");
0424:                if ((result == Integer.MIN_VALUE) && !isNegative)
0425:                    throw new NumberFormatException("Overflow");
0426:                if (cursor != null)
0427:                    cursor.setIndex(i);
0428:                return isNegative ? result : -result;
0429:            }
0430:
0431:            private static int parseIntString(String csq, int radix,
0432:                    Cursor cursor) {
0433:                // Parsing block identical for all CharSequences.
0434:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0435:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0436:                        .length();
0437:                boolean isNegative = false;
0438:                int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0439:                int i = start;
0440:                for (; i < end; i++) {
0441:                    char c = csq.charAt(i);
0442:                    int digit = (c <= '9') ? c - '0'
0443:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0444:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0445:                                            : -1;
0446:                    if ((digit >= 0) && (digit < radix)) {
0447:                        int newResult = result * radix - digit;
0448:                        if (newResult > result)
0449:                            throw new NumberFormatException("Overflow");
0450:                        result = newResult;
0451:                    } else if ((c == '-') && (i == start)) {
0452:                        isNegative = true;
0453:                    } else if ((c == '+') && (i == start)) {
0454:                        // Ok.
0455:                    } else {
0456:                        if (cursor == null)
0457:                            throw new NumberFormatException(
0458:                                    "Incomplete parsing");
0459:                        break; // Done.
0460:                    }
0461:                }
0462:                // Requires one valid digit character and checks for opposite overflow.
0463:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0464:                    throw new NumberFormatException("Cannot parse " + csq
0465:                            + " as int");
0466:                if ((result == Integer.MIN_VALUE) && !isNegative)
0467:                    throw new NumberFormatException("Overflow");
0468:                if (cursor != null)
0469:                    cursor.setIndex(i);
0470:                return isNegative ? result : -result;
0471:            }
0472:
0473:            private static int parseIntCharSequence(CharSequence csq,
0474:                    int radix, Cursor cursor) {
0475:                // Parsing block identical for all CharSequences.
0476:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0477:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0478:                        .length();
0479:                boolean isNegative = false;
0480:                int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0481:                int i = start;
0482:                for (; i < end; i++) {
0483:                    char c = csq.charAt(i);
0484:                    int digit = (c <= '9') ? c - '0'
0485:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0486:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0487:                                            : -1;
0488:                    if ((digit >= 0) && (digit < radix)) {
0489:                        int newResult = result * radix - digit;
0490:                        if (newResult > result)
0491:                            throw new NumberFormatException("Overflow");
0492:                        result = newResult;
0493:                    } else if ((c == '-') && (i == start)) {
0494:                        isNegative = true;
0495:                    } else if ((c == '+') && (i == start)) {
0496:                        // Ok.
0497:                    } else {
0498:                        if (cursor == null)
0499:                            throw new NumberFormatException(
0500:                                    "Incomplete parsing");
0501:                        break; // Done.
0502:                    }
0503:                }
0504:                // Requires one valid digit character and checks for opposite overflow.
0505:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0506:                    throw new NumberFormatException("Cannot parse " + csq
0507:                            + " as int");
0508:                if ((result == Integer.MIN_VALUE) && !isNegative)
0509:                    throw new NumberFormatException("Overflow");
0510:                if (cursor != null)
0511:                    cursor.setIndex(i);
0512:                return isNegative ? result : -result;
0513:            }
0514:
0515:            /**
0516:             * Parses the specified character sequence as a decimal <code>long</code>.
0517:             *
0518:             * @param  csq the character sequence to parse.
0519:             * @return <code>parseLong(csq, 10)</code>
0520:             * @throws NumberFormatException if the specified character sequence
0521:             *         does not contain a parsable <code>long</code>.
0522:             * @see    #parseLong(CharSequence, int)
0523:             */
0524:            public static long parseLong(CharSequence csq) {
0525:                return parseLong(csq, 10);
0526:            }
0527:
0528:            /**
0529:             * Equivalent to {@link #parseLong(CharSequence)} 
0530:             * (for J2ME compatibility).
0531:             */
0532:            public static long parseLong(String str) {
0533:                return parseLongString(str, 10, null);
0534:            }
0535:
0536:            /**
0537:             * Parses the specified character sequence as a signed <code>long</code>
0538:             * in the specified radix.
0539:             *
0540:             * @param  csq the character sequence to parse.
0541:             * @param  radix the radix to be used while parsing.
0542:             * @return the corresponding <code>long</code>.
0543:             * @throws NumberFormatException if the specified character sequence
0544:             *         does not contain a parsable <code>long</code>.
0545:             */
0546:            public static long parseLong(CharSequence csq, int radix) {
0547:                return parseLong(csq, radix, null);
0548:            }
0549:
0550:            /**
0551:             * Equivalent to {@link #parseLong(CharSequence, int)} 
0552:             * (for J2ME compatibility).
0553:             */
0554:            public static long parseLong(String str, int radix) {
0555:                return parseLongString(str, radix, null);
0556:            }
0557:
0558:            /**
0559:             * Parses the specified character sequence from the specified position 
0560:             * as a signed <code>long</code> in the specified radix.
0561:             *
0562:             * @param  csq the character sequence to parse.
0563:             * @param  radix the radix to be used while parsing.
0564:             * @param  cursor the current cursor position (being maintained) or
0565:             *         <code>null</code> if the whole character sequence is parsed.
0566:             * @return the corresponding <code>long</code>.
0567:             * @throws NumberFormatException if the specified character sequence
0568:             *         does not contain a parsable <code>long</code>.
0569:             */
0570:            public static long parseLong(CharSequence csq, int radix,
0571:                    Cursor cursor) {
0572:                // Avoids dynamic cost of CharSequence.charAt
0573:                if (csq instanceof  CharArray)
0574:                    return parseLongCharArray((CharArray) csq, radix, cursor);
0575:                if (csq instanceof  TextBuilder)
0576:                    return parseLongTextBuilder((TextBuilder) csq, radix,
0577:                            cursor);
0578:                if (csq instanceof  Text)
0579:                    return parseLongText((Text) csq, radix, cursor);
0580:                if (((Object) csq) instanceof  String)
0581:                    return parseLongString((String) ((Object) csq), radix,
0582:                            cursor);
0583:                return parseLongCharSequence(csq, radix, cursor);
0584:            }
0585:
0586:            private static long parseLongCharArray(CharArray csq, int radix,
0587:                    Cursor cursor) {
0588:                // Parsing block identical for all CharSequences.
0589:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0590:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0591:                        .length();
0592:                boolean isNegative = false;
0593:                long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0594:                int i = start;
0595:                for (; i < end; i++) {
0596:                    char c = csq.charAt(i);
0597:                    int digit = (c <= '9') ? c - '0'
0598:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0599:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0600:                                            : -1;
0601:                    if ((digit >= 0) && (digit < radix)) {
0602:                        long newResult = result * radix - digit;
0603:                        if (newResult > result)
0604:                            throw new NumberFormatException("Overflow");
0605:                        result = newResult;
0606:                    } else if ((c == '-') && (i == start)) {
0607:                        isNegative = true;
0608:                    } else if ((c == '+') && (i == start)) {
0609:                        // Ok.
0610:                    } else {
0611:                        if (cursor == null)
0612:                            throw new NumberFormatException(
0613:                                    "Incomplete parsing");
0614:                        break; // Done.
0615:                    }
0616:                }
0617:                // Requires one valid digit character and checks for opposite overflow.
0618:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0619:                    throw new NumberFormatException("Cannot parse " + csq
0620:                            + " as int");
0621:                if ((result == Long.MIN_VALUE) && !isNegative)
0622:                    throw new NumberFormatException("Overflow");
0623:                if (cursor != null)
0624:                    cursor.setIndex(i);
0625:                return isNegative ? result : -result;
0626:            }
0627:
0628:            private static long parseLongTextBuilder(TextBuilder csq,
0629:                    int radix, Cursor cursor) {
0630:                // Parsing block identical for all CharSequences.
0631:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0632:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0633:                        .length();
0634:                boolean isNegative = false;
0635:                long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0636:                int i = start;
0637:                for (; i < end; i++) {
0638:                    char c = csq.charAt(i);
0639:                    int digit = (c <= '9') ? c - '0'
0640:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0641:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0642:                                            : -1;
0643:                    if ((digit >= 0) && (digit < radix)) {
0644:                        long newResult = result * radix - digit;
0645:                        if (newResult > result)
0646:                            throw new NumberFormatException("Overflow");
0647:                        result = newResult;
0648:                    } else if ((c == '-') && (i == start)) {
0649:                        isNegative = true;
0650:                    } else if ((c == '+') && (i == start)) {
0651:                        // Ok.
0652:                    } else {
0653:                        if (cursor == null)
0654:                            throw new NumberFormatException(
0655:                                    "Incomplete parsing");
0656:                        break; // Done.
0657:                    }
0658:                }
0659:                // Requires one valid digit character and checks for opposite overflow.
0660:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0661:                    throw new NumberFormatException("Cannot parse " + csq
0662:                            + " as int");
0663:                if ((result == Long.MIN_VALUE) && !isNegative)
0664:                    throw new NumberFormatException("Overflow");
0665:                if (cursor != null)
0666:                    cursor.setIndex(i);
0667:                return isNegative ? result : -result;
0668:            }
0669:
0670:            private static long parseLongText(Text csq, int radix, Cursor cursor) {
0671:                // Parsing block identical for all CharSequences.
0672:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0673:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0674:                        .length();
0675:                boolean isNegative = false;
0676:                long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0677:                int i = start;
0678:                for (; i < end; i++) {
0679:                    char c = csq.charAt(i);
0680:                    int digit = (c <= '9') ? c - '0'
0681:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0682:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0683:                                            : -1;
0684:                    if ((digit >= 0) && (digit < radix)) {
0685:                        long newResult = result * radix - digit;
0686:                        if (newResult > result)
0687:                            throw new NumberFormatException("Overflow");
0688:                        result = newResult;
0689:                    } else if ((c == '-') && (i == start)) {
0690:                        isNegative = true;
0691:                    } else if ((c == '+') && (i == start)) {
0692:                        // Ok.
0693:                    } else {
0694:                        if (cursor == null)
0695:                            throw new NumberFormatException(
0696:                                    "Incomplete parsing");
0697:                        break; // Done.
0698:                    }
0699:                }
0700:                // Requires one valid digit character and checks for opposite overflow.
0701:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0702:                    throw new NumberFormatException("Cannot parse " + csq
0703:                            + " as int");
0704:                if ((result == Long.MIN_VALUE) && !isNegative)
0705:                    throw new NumberFormatException("Overflow");
0706:                if (cursor != null)
0707:                    cursor.setIndex(i);
0708:                return isNegative ? result : -result;
0709:            }
0710:
0711:            private static long parseLongString(String csq, int radix,
0712:                    Cursor cursor) {
0713:                // Parsing block identical for all CharSequences.
0714:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0715:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0716:                        .length();
0717:                boolean isNegative = false;
0718:                long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0719:                int i = start;
0720:                for (; i < end; i++) {
0721:                    char c = csq.charAt(i);
0722:                    int digit = (c <= '9') ? c - '0'
0723:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0724:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0725:                                            : -1;
0726:                    if ((digit >= 0) && (digit < radix)) {
0727:                        long newResult = result * radix - digit;
0728:                        if (newResult > result)
0729:                            throw new NumberFormatException("Overflow");
0730:                        result = newResult;
0731:                    } else if ((c == '-') && (i == start)) {
0732:                        isNegative = true;
0733:                    } else if ((c == '+') && (i == start)) {
0734:                        // Ok.
0735:                    } else {
0736:                        if (cursor == null)
0737:                            throw new NumberFormatException(
0738:                                    "Incomplete parsing");
0739:                        break; // Done.
0740:                    }
0741:                }
0742:                // Requires one valid digit character and checks for opposite overflow.
0743:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0744:                    throw new NumberFormatException("Cannot parse " + csq
0745:                            + " as int");
0746:                if ((result == Long.MIN_VALUE) && !isNegative)
0747:                    throw new NumberFormatException("Overflow");
0748:                if (cursor != null)
0749:                    cursor.setIndex(i);
0750:                return isNegative ? result : -result;
0751:            }
0752:
0753:            private static long parseLongCharSequence(CharSequence csq,
0754:                    int radix, Cursor cursor) {
0755:                // Parsing block identical for all CharSequences.
0756:                final int start = (cursor != null) ? cursor.getIndex() : 0;
0757:                final int end = (cursor != null) ? cursor.getEndIndex() : csq
0758:                        .length();
0759:                boolean isNegative = false;
0760:                long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
0761:                int i = start;
0762:                for (; i < end; i++) {
0763:                    char c = csq.charAt(i);
0764:                    int digit = (c <= '9') ? c - '0'
0765:                            : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
0766:                                    : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10
0767:                                            : -1;
0768:                    if ((digit >= 0) && (digit < radix)) {
0769:                        long newResult = result * radix - digit;
0770:                        if (newResult > result)
0771:                            throw new NumberFormatException("Overflow");
0772:                        result = newResult;
0773:                    } else if ((c == '-') && (i == start)) {
0774:                        isNegative = true;
0775:                    } else if ((c == '+') && (i == start)) {
0776:                        // Ok.
0777:                    } else {
0778:                        if (cursor == null)
0779:                            throw new NumberFormatException(
0780:                                    "Incomplete parsing");
0781:                        break; // Done.
0782:                    }
0783:                }
0784:                // Requires one valid digit character and checks for opposite overflow.
0785:                if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
0786:                    throw new NumberFormatException("Cannot parse " + csq
0787:                            + " as int");
0788:                if ((result == Long.MIN_VALUE) && !isNegative)
0789:                    throw new NumberFormatException("Overflow");
0790:                if (cursor != null)
0791:                    cursor.setIndex(i);
0792:                return isNegative ? result : -result;
0793:            }
0794:
0795:            /**
0796:             * Parses the specified character sequence as a <code>float</code>.
0797:             *
0798:             * @param  csq the character sequence to parse.
0799:             * @return the float number represented by the specified character sequence.
0800:             *@JVM-1.1+@
0801:             public static float parseFloat(CharSequence csq) {
0802:             return (float) parseDouble(csq);
0803:             }
0804:             /**/
0805:
0806:            /**
0807:             * Equivalent to {@link #parseFloat(CharSequence)} 
0808:             * (for J2ME compatibility).
0809:             *@JVM-1.1+@
0810:             public static float parseFloat(String str) {
0811:             return (float) parseDoubleString(str, null);
0812:             }
0813:             /**/
0814:
0815:            /**
0816:             * Parses the specified character sequence from the specified position 
0817:             * as a <code>float</code>.
0818:             *
0819:             * @param  csq the character sequence to parse.
0820:             * @param  cursor the current cursor position (being maintained).
0821:             * @return the float number represented by the specified character sequence.
0822:             *@JVM-1.1+@
0823:             public static float parseFloat(CharSequence csq, Cursor cursor) {
0824:             return (float) parseDouble(csq, cursor);
0825:             }
0826:             /**/
0827:
0828:            /**
0829:             * Parses the specified character sequence as a <code>double</code>.
0830:             * The format must be of the form:<code>
0831:             * &lt;decimal&gt;{'.'&lt;fraction&gt;}{'E|e'&lt;exponent&gt;}</code>.
0832:             *
0833:             * @param  csq the character sequence to parse.
0834:             * @return the double number represented by this character sequence.
0835:             * @throws NumberFormatException if the character sequence does not contain
0836:             *         a parsable <code>double</code>.
0837:             *@JVM-1.1+@
0838:             public static double parseDouble(CharSequence csq)
0839:             throws NumberFormatException {
0840:             return parseDouble(csq, null);
0841:             }
0842:             /**/
0843:
0844:            /**
0845:             * Equivalent to {@link #parseDouble(CharSequence)} 
0846:             * (for J2ME compatibility).
0847:             *@JVM-1.1+@
0848:             public static double parseDouble(String str) {
0849:             return parseDoubleString(str, null);
0850:             }
0851:             /**/
0852:
0853:            /**
0854:             * Parses the specified character sequence from the specified position 
0855:             * as a <code>double</code>.
0856:             *
0857:             * @param  csq the character sequence to parse.
0858:             * @param  cursor the current cursor position (being maintained).
0859:             * @return the double number represented by this character sequence.
0860:             * @throws NumberFormatException if the character sequence does not contain
0861:             *         a parsable <code>double</code>.
0862:             *@JVM-1.1+@
0863:             public static double parseDouble(CharSequence csq, Cursor cursor)
0864:             throws NumberFormatException {
0865:             // Avoids dynamic cost of CharSequence.charAt
0866:             if (csq instanceof CharArray)
0867:             return parseDoubleCharArray((CharArray) csq, cursor);
0868:             if (csq instanceof TextBuilder)
0869:             return parseDoubleTextBuilder((TextBuilder) csq, cursor);
0870:             if (csq instanceof Text)
0871:             return parseDoubleText((Text) csq, cursor);
0872:             if (((Object) csq) instanceof String)
0873:             return parseDoubleString((String) ((Object) csq), cursor);
0874:             return parseDoubleCharSequence(csq,  cursor);
0875:             }
0876:             
0877:             private static double parseDoubleCharArray(CharArray csq, Cursor cursor)
0878:             throws NumberFormatException {
0879:             // Parsing block identical for all CharSequences.
0880:             final int start = (cursor != null) ? cursor.getIndex() : 0;
0881:             final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
0882:             int i = start;
0883:             char c = csq.charAt(i);
0884:             
0885:             // Checks for NaN.
0886:             if ((c == 'N') && match("NaN", csq, i, length)) {
0887:             if (cursor != null) cursor.setIndex(i + 3);
0888:             return Double.NaN;
0889:             }
0890:             
0891:             // Reads sign.
0892:             boolean isNegative = (c == '-');
0893:             if ((isNegative || (c == '+')) && (++i < length)) {
0894:             c = csq.charAt(i);
0895:             }
0896:             
0897:             // Checks for Infinity.
0898:             if ((c == 'I') && match("Infinity", csq, i, length)) {
0899:             if (cursor != null) cursor.setIndex(i + 8);
0900:             return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
0901:             }
0902:             
0903:             // Reads decimal and fraction (both merged to a long).
0904:             long decimal = 0;
0905:             int decimalPoint = -1;
0906:             while (true) {
0907:             int digit =  c - '0';
0908:             if ((digit >= 0) && (digit < 10)) {
0909:             long tmp = decimal * 10 + digit;
0910:             if (tmp < decimal)
0911:             throw new NumberFormatException("Too many digits - Overflow");
0912:             decimal = tmp;
0913:             } else if ((c == '.') && (decimalPoint < 0)) {
0914:             decimalPoint = i;
0915:             } else {
0916:             break; // Done.
0917:             }
0918:             if (++i >= length)
0919:             break;
0920:             c = csq.charAt(i);
0921:             }
0922:             if (isNegative) {
0923:             decimal = - decimal;
0924:             }
0925:             int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
0926:             
0927:             // Reads exponent.
0928:             int exp = 0;
0929:             if ((i < length) && ((c == 'E') || (c == 'e'))) {
0930:             c = csq.charAt(++i);
0931:             boolean isNegativeExp = (c == '-');
0932:             if ((isNegativeExp || (c == '+')) && (++i < length)) {
0933:             c = csq.charAt(i);
0934:             }
0935:             while (true) {
0936:             int digit =  c - '0';
0937:             if ((digit >= 0) && (digit < 10)) {
0938:             int tmp = exp * 10 + digit;
0939:             if (tmp < exp)
0940:             throw new NumberFormatException("Exponent Overflow");
0941:             exp = tmp;
0942:             } else {
0943:             break; // Done.
0944:             }
0945:             if (++i >= length)
0946:             break;
0947:             c = csq.charAt(i);
0948:             }
0949:             if (isNegativeExp) {
0950:             exp = -exp;
0951:             }
0952:             }
0953:             if (cursor != null)
0954:             cursor.setIndex(i);
0955:             else if (i < length)
0956:             throw new NumberFormatException("Incomplete parsing");    
0957:             return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
0958:             }
0959:             
0960:             private static double parseDoubleTextBuilder(TextBuilder csq, Cursor cursor)
0961:             throws NumberFormatException {
0962:             // Parsing block identical for all CharSequences.
0963:             final int start = (cursor != null) ? cursor.getIndex() : 0;
0964:             final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
0965:             int i = start;
0966:             char c = csq.charAt(i);
0967:             
0968:             // Checks for NaN.
0969:             if ((c == 'N') && match("NaN", csq, i, length)) {
0970:             if (cursor != null) cursor.setIndex(i + 3);
0971:             return Double.NaN;
0972:             }
0973:             
0974:             // Reads sign.
0975:             boolean isNegative = (c == '-');
0976:             if ((isNegative || (c == '+')) && (++i < length)) {
0977:             c = csq.charAt(i);
0978:             }
0979:             
0980:             // Checks for Infinity.
0981:             if ((c == 'I') && match("Infinity", csq, i, length)) {
0982:             if (cursor != null) cursor.setIndex(i + 8);
0983:             return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
0984:             }
0985:             
0986:             // Reads decimal and fraction (both merged to a long).
0987:             long decimal = 0;
0988:             int decimalPoint = -1;
0989:             while (true) {
0990:             int digit =  c - '0';
0991:             if ((digit >= 0) && (digit < 10)) {
0992:             long tmp = decimal * 10 + digit;
0993:             if (tmp < decimal)
0994:             throw new NumberFormatException("Too many digits - Overflow");
0995:             decimal = tmp;
0996:             } else if ((c == '.') && (decimalPoint < 0)) {
0997:             decimalPoint = i;
0998:             } else {
0999:             break; // Done.
1000:             }
1001:             if (++i >= length)
1002:             break;
1003:             c = csq.charAt(i);
1004:             }
1005:             if (isNegative) {
1006:             decimal = - decimal;
1007:             }
1008:             int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1009:             
1010:             // Reads exponent.
1011:             int exp = 0;
1012:             if ((i < length) && ((c == 'E') || (c == 'e'))) {
1013:             c = csq.charAt(++i);
1014:             boolean isNegativeExp = (c == '-');
1015:             if ((isNegativeExp || (c == '+')) && (++i < length)) {
1016:             c = csq.charAt(i);
1017:             }
1018:             while (true) {
1019:             int digit =  c - '0';
1020:             if ((digit >= 0) && (digit < 10)) {
1021:             int tmp = exp * 10 + digit;
1022:             if (tmp < exp)
1023:             throw new NumberFormatException("Exponent Overflow");
1024:             exp = tmp;
1025:             } else {
1026:             break; // Done.
1027:             }
1028:             if (++i >= length)
1029:             break;
1030:             c = csq.charAt(i);
1031:             }
1032:             if (isNegativeExp) {
1033:             exp = -exp;
1034:             }
1035:             }
1036:             if (cursor != null)
1037:             cursor.setIndex(i);
1038:             else if (i < length)
1039:             throw new NumberFormatException("Incomplete parsing");    
1040:             return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1041:             }
1042:
1043:             private static double parseDoubleText(Text csq, Cursor cursor)
1044:             throws NumberFormatException {
1045:             // Parsing block identical for all CharSequences.
1046:             final int start = (cursor != null) ? cursor.getIndex() : 0;
1047:             final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
1048:             int i = start;
1049:             char c = csq.charAt(i);
1050:             
1051:             // Checks for NaN.
1052:             if ((c == 'N') && match("NaN", csq, i, length)) {
1053:             if (cursor != null) cursor.setIndex(i + 3);
1054:             return Double.NaN;
1055:             }
1056:             
1057:             // Reads sign.
1058:             boolean isNegative = (c == '-');
1059:             if ((isNegative || (c == '+')) && (++i < length)) {
1060:             c = csq.charAt(i);
1061:             }
1062:             
1063:             // Checks for Infinity.
1064:             if ((c == 'I') && match("Infinity", csq, i, length)) {
1065:             if (cursor != null) cursor.setIndex(i + 8);
1066:             return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
1067:             }
1068:             
1069:             // Reads decimal and fraction (both merged to a long).
1070:             long decimal = 0;
1071:             int decimalPoint = -1;
1072:             while (true) {
1073:             int digit =  c - '0';
1074:             if ((digit >= 0) && (digit < 10)) {
1075:             long tmp = decimal * 10 + digit;
1076:             if (tmp < decimal)
1077:             throw new NumberFormatException("Too many digits - Overflow");
1078:             decimal = tmp;
1079:             } else if ((c == '.') && (decimalPoint < 0)) {
1080:             decimalPoint = i;
1081:             } else {
1082:             break; // Done.
1083:             }
1084:             if (++i >= length)
1085:             break;
1086:             c = csq.charAt(i);
1087:             }
1088:             if (isNegative) {
1089:             decimal = - decimal;
1090:             }
1091:             int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1092:             
1093:             // Reads exponent.
1094:             int exp = 0;
1095:             if ((i < length) && ((c == 'E') || (c == 'e'))) {
1096:             c = csq.charAt(++i);
1097:             boolean isNegativeExp = (c == '-');
1098:             if ((isNegativeExp || (c == '+')) && (++i < length)) {
1099:             c = csq.charAt(i);
1100:             }
1101:             while (true) {
1102:             int digit =  c - '0';
1103:             if ((digit >= 0) && (digit < 10)) {
1104:             int tmp = exp * 10 + digit;
1105:             if (tmp < exp)
1106:             throw new NumberFormatException("Exponent Overflow");
1107:             exp = tmp;
1108:             } else {
1109:             break; // Done.
1110:             }
1111:             if (++i >= length)
1112:             break;
1113:             c = csq.charAt(i);
1114:             }
1115:             if (isNegativeExp) {
1116:             exp = -exp;
1117:             }
1118:             }
1119:             if (cursor != null)
1120:             cursor.setIndex(i);
1121:             else if (i < length)
1122:             throw new NumberFormatException("Incomplete parsing");    
1123:             return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1124:             }
1125:             
1126:             private static double parseDoubleString(String csq, Cursor cursor)
1127:             throws NumberFormatException {
1128:             // Parsing block identical for all CharSequences.
1129:             final int start = (cursor != null) ? cursor.getIndex() : 0;
1130:             final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
1131:             int i = start;
1132:             char c = csq.charAt(i);
1133:             
1134:             // Checks for NaN.
1135:             if ((c == 'N') && match("NaN", csq, i, length)) {
1136:             if (cursor != null) cursor.setIndex(i + 3);
1137:             return Double.NaN;
1138:             }
1139:             
1140:             // Reads sign.
1141:             boolean isNegative = (c == '-');
1142:             if ((isNegative || (c == '+')) && (++i < length)) {
1143:             c = csq.charAt(i);
1144:             }
1145:             
1146:             // Checks for Infinity.
1147:             if ((c == 'I') && match("Infinity", csq, i, length)) {
1148:             if (cursor != null) cursor.setIndex(i + 8);
1149:             return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
1150:             }
1151:             
1152:             // Reads decimal and fraction (both merged to a long).
1153:             long decimal = 0;
1154:             int decimalPoint = -1;
1155:             while (true) {
1156:             int digit =  c - '0';
1157:             if ((digit >= 0) && (digit < 10)) {
1158:             long tmp = decimal * 10 + digit;
1159:             if (tmp < decimal)
1160:             throw new NumberFormatException("Too many digits - Overflow");
1161:             decimal = tmp;
1162:             } else if ((c == '.') && (decimalPoint < 0)) {
1163:             decimalPoint = i;
1164:             } else {
1165:             break; // Done.
1166:             }
1167:             if (++i >= length)
1168:             break;
1169:             c = csq.charAt(i);
1170:             }
1171:             if (isNegative) {
1172:             decimal = - decimal;
1173:             }
1174:             int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1175:             
1176:             // Reads exponent.
1177:             int exp = 0;
1178:             if ((i < length) && ((c == 'E') || (c == 'e'))) {
1179:             c = csq.charAt(++i);
1180:             boolean isNegativeExp = (c == '-');
1181:             if ((isNegativeExp || (c == '+')) && (++i < length)) {
1182:             c = csq.charAt(i);
1183:             }
1184:             while (true) {
1185:             int digit =  c - '0';
1186:             if ((digit >= 0) && (digit < 10)) {
1187:             int tmp = exp * 10 + digit;
1188:             if (tmp < exp)
1189:             throw new NumberFormatException("Exponent Overflow");
1190:             exp = tmp;
1191:             } else {
1192:             break; // Done.
1193:             }
1194:             if (++i >= length)
1195:             break;
1196:             c = csq.charAt(i);
1197:             }
1198:             if (isNegativeExp) {
1199:             exp = -exp;
1200:             }
1201:             }
1202:             if (cursor != null)
1203:             cursor.setIndex(i);
1204:             else if (i < length)
1205:             throw new NumberFormatException("Incomplete parsing");    
1206:             return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1207:             }
1208:             
1209:             private static double parseDoubleCharSequence(CharSequence csq, Cursor cursor)
1210:             throws NumberFormatException {
1211:             // Parsing block identical for all CharSequences.
1212:             final int start = (cursor != null) ? cursor.getIndex() : 0;
1213:             final int length = (cursor != null) ? cursor.getEndIndex() : csq.length();
1214:             int i = start;
1215:             char c = csq.charAt(i);
1216:             
1217:             // Checks for NaN.
1218:             if ((c == 'N') && match("NaN", csq, i, length)) {
1219:             if (cursor != null) cursor.setIndex(i + 3);
1220:             return Double.NaN;
1221:             }
1222:             
1223:             // Reads sign.
1224:             boolean isNegative = (c == '-');
1225:             if ((isNegative || (c == '+')) && (++i < length)) {
1226:             c = csq.charAt(i);
1227:             }
1228:             
1229:             // Checks for Infinity.
1230:             if ((c == 'I') && match("Infinity", csq, i, length)) {
1231:             if (cursor != null) cursor.setIndex(i + 8);
1232:             return isNegative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
1233:             }
1234:             
1235:             // Reads decimal and fraction (both merged to a long).
1236:             long decimal = 0;
1237:             int decimalPoint = -1;
1238:             while (true) {
1239:             int digit =  c - '0';
1240:             if ((digit >= 0) && (digit < 10)) {
1241:             long tmp = decimal * 10 + digit;
1242:             if (tmp < decimal)
1243:             throw new NumberFormatException("Too many digits - Overflow");
1244:             decimal = tmp;
1245:             } else if ((c == '.') && (decimalPoint < 0)) {
1246:             decimalPoint = i;
1247:             } else {
1248:             break; // Done.
1249:             }
1250:             if (++i >= length)
1251:             break;
1252:             c = csq.charAt(i);
1253:             }
1254:             if (isNegative) {
1255:             decimal = - decimal;
1256:             }
1257:             int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
1258:             
1259:             // Reads exponent.
1260:             int exp = 0;
1261:             if ((i < length) && ((c == 'E') || (c == 'e'))) {
1262:             c = csq.charAt(++i);
1263:             boolean isNegativeExp = (c == '-');
1264:             if ((isNegativeExp || (c == '+')) && (++i < length)) {
1265:             c = csq.charAt(i);
1266:             }
1267:             while (true) {
1268:             int digit =  c - '0';
1269:             if ((digit >= 0) && (digit < 10)) {
1270:             int tmp = exp * 10 + digit;
1271:             if (tmp < exp)
1272:             throw new NumberFormatException("Exponent Overflow");
1273:             exp = tmp;
1274:             } else {
1275:             break; // Done.
1276:             }
1277:             if (++i >= length)
1278:             break;
1279:             c = csq.charAt(i);
1280:             }
1281:             if (isNegativeExp) {
1282:             exp = -exp;
1283:             }
1284:             }
1285:             if (cursor != null)
1286:             cursor.setIndex(i);
1287:             else if (i < length)
1288:             throw new NumberFormatException("Incomplete parsing");    
1289:             return javolution.lang.MathLib.toDoublePow10(decimal, exp - fractionLength);
1290:             }
1291:             
1292:             static boolean match(String str, CharSequence csq, int start, int length) {
1293:             for (int i = 0; i < str.length(); i++) {
1294:             if ((start + i >= length)
1295:             || csq.charAt(start + i) != str.charAt(i))
1296:             return false;
1297:             }
1298:             return true;
1299:             }
1300:             static boolean match(String str, String csq, int start, int length) {
1301:             for (int i = 0; i < str.length(); i++) {
1302:             if ((start + i >= length)
1303:             || csq.charAt(start + i) != str.charAt(i))
1304:             return false;
1305:             }
1306:             return true;
1307:             }
1308:             /**/
1309:
1310:            /**
1311:             * Formats the specified <code>boolean</code> and appends the resulting
1312:             * text to the <code>Appendable</code> argument.
1313:             *
1314:             * @param  b a <code>boolean</code>.
1315:             * @param  a the <code>Appendable</code> to append.
1316:             * @return the specified <code>StringBuffer</code> object.
1317:             * @throws IOException if an I/O exception occurs.
1318:             * @see    #parseBoolean
1319:             */
1320:            public static Appendable format(boolean b, Appendable a)
1321:                    throws IOException {
1322:                return b ? a.append('t').append('r').append('u').append('e')
1323:                        : a.append('f').append('a').append('l').append('s')
1324:                                .append('e');
1325:            }
1326:
1327:            /**
1328:             * Formats the specified <code>int</code> and appends the resulting
1329:             * text (decimal representation) to the <code>Appendable</code> argument.
1330:             *
1331:             * <p> Note: This method is preferred to <code>Appendable.append(int)
1332:             *           </code> as it does not create temporary <code>String</code>
1333:             *           objects (several times faster for small numbers).</p>
1334:             *
1335:             * @param  i the <code>int</code> number.
1336:             * @param  a the <code>Appendable</code> to append.
1337:             * @return the specified <code>Appendable</code> object.
1338:             * @throws IOException if an I/O exception occurs.
1339:             * @see    #parseInt
1340:             */
1341:            public static Appendable format(int i, Appendable a)
1342:                    throws IOException {
1343:                if (a instanceof  TextBuilder)
1344:                    return ((TextBuilder) a).append(i);
1345:                TextBuilder tmp = TextBuilder.newInstance();
1346:                tmp.append(i);
1347:                appendTo(a, tmp);
1348:                TextBuilder.recycle(tmp);
1349:                return a;
1350:            }
1351:
1352:            /**
1353:             * Formats the specified <code>int</code> in the specified radix and appends
1354:             * the resulting text to the <code>Appendable</code> argument.
1355:             *
1356:             * @param  i the <code>int</code> number.
1357:             * @param  radix the radix.
1358:             * @param  a the <code>Appendable</code> to append.
1359:             * @return the specified <code>Appendable</code> object.
1360:             * @throws  IllegalArgumentException if radix is not in [2 .. 36] range.
1361:             * @throws IOException if an I/O exception occurs.
1362:             * @see    #parseInt(CharSequence, int)
1363:             */
1364:            public static Appendable format(int i, int radix, Appendable a)
1365:                    throws IOException {
1366:                if (a instanceof  TextBuilder)
1367:                    return ((TextBuilder) a).append(i, radix);
1368:                TextBuilder tmp = TextBuilder.newInstance();
1369:                tmp.append(i, radix);
1370:                appendTo(a, tmp);
1371:                TextBuilder.recycle(tmp);
1372:                return a;
1373:            }
1374:
1375:            /**
1376:             * Formats the specified <code>long</code> and appends the resulting
1377:             * text (decimal representation) to the <code>Appendable</code> argument.
1378:             *
1379:             * <p> Note: This method is preferred to <code>Appendable.append(long)
1380:             *           </code> as it does not create temporary <code>String</code>
1381:             *           objects (several times faster for small numbers).</p>
1382:             *
1383:             * @param  l the <code>long</code> number.
1384:             * @param  a the <code>Appendable</code> to append.
1385:             * @return the specified <code>Appendable</code> object.
1386:             * @throws IOException if an I/O exception occurs.
1387:             * @see    #parseLong
1388:             */
1389:            public static Appendable format(long l, Appendable a)
1390:                    throws IOException {
1391:                if (a instanceof  TextBuilder)
1392:                    return ((TextBuilder) a).append(l);
1393:                TextBuilder tmp = TextBuilder.newInstance();
1394:                tmp.append(l);
1395:                appendTo(a, tmp);
1396:                TextBuilder.recycle(tmp);
1397:                return a;
1398:            }
1399:
1400:            /**
1401:             * Formats the specified <code>long</code> in the specified radix and
1402:             * appends the resulting text to the <code>Appendable</code> argument.
1403:             *
1404:             * @param  l the <code>long</code> number.
1405:             * @param  radix the radix.
1406:             * @param  a the <code>Appendable</code> to append.
1407:             * @return the specified <code>Appendable</code> object.
1408:             * @throws  IllegalArgumentException if radix is not in [2 .. 36] range.
1409:             * @throws IOException if an I/O exception occurs.
1410:             * @see    #parseLong(CharSequence, int)
1411:             */
1412:            public static Appendable format(long l, int radix, Appendable a)
1413:                    throws IOException {
1414:                if (a instanceof  TextBuilder)
1415:                    return ((TextBuilder) a).append(l, radix);
1416:                TextBuilder tmp = TextBuilder.newInstance();
1417:                tmp.append(l, radix);
1418:                appendTo(a, tmp);
1419:                TextBuilder.recycle(tmp);
1420:                return a;
1421:            }
1422:
1423:            /**
1424:             * Formats the specified <code>float</code> value.
1425:             *
1426:             * @param  f the <code>float</code> value.
1427:             * @param  a the <code>Appendable</code> to append.
1428:             * @return the specified <code>Appendable</code> object.
1429:             * @throws IOException if an I/O exception occurs.
1430:             * @see    TextBuilder#append(float)
1431:             *@JVM-1.1+@
1432:             public static Appendable format(float f, Appendable a)
1433:             throws IOException {
1434:             if (a instanceof TextBuilder)
1435:             return ((TextBuilder) a).append(f);
1436:             TextBuilder tmp = TextBuilder.newInstance();
1437:             tmp.append(f);
1438:             appendTo(a, tmp);
1439:             TextBuilder.recycle(tmp);
1440:             return a;
1441:             }
1442:             /**/
1443:
1444:            /**
1445:             * Formats the specified <code>double</code> value (16 or 17 digits output).
1446:             *
1447:             * @param  d the <code>double</code> value.
1448:             * @param  a the <code>Appendable</code> to append.
1449:             * @return the specified <code>Appendable</code> object.
1450:             * @throws IOException if an I/O exception occurs.
1451:             * @see    TextBuilder#append(double)
1452:             *@JVM-1.1+@
1453:             public static Appendable format(double d, Appendable a)
1454:             throws IOException {
1455:             if (a instanceof TextBuilder)
1456:             return ((TextBuilder) a).append(d);
1457:             TextBuilder tmp = TextBuilder.newInstance();
1458:             tmp.append(d);
1459:             appendTo(a, tmp);
1460:             TextBuilder.recycle(tmp);
1461:             return a;
1462:             }
1463:             /**/
1464:
1465:            /**
1466:             * Formats the specified <code>double</code> value according to the 
1467:             * specified formatting arguments.
1468:             *
1469:             * @param  d the <code>double</code> value.
1470:             * @param  digits the number of significative digits (excludes exponent) or
1471:             *         <code>-1</code> to mimic the standard library (16 or 17 digits).
1472:             * @param  scientific <code>true</code> to forces the use of the scientific 
1473:             *         notation (e.g. <code>1.23E3</code>); <code>false</code> 
1474:             *         otherwise. 
1475:             * @param  showZero <code>true</code> if trailing fractional zeros are 
1476:             *         represented; <code>false</code> otherwise.
1477:             * @param  a the <code>Appendable</code> to append.
1478:             * @return the specified <code>Appendable</code> object.
1479:             * @throws IllegalArgumentException if <code>(digits &gt; 19)</code>)
1480:             * @throws IOException if an I/O exception occurs.
1481:             * @see    TextBuilder#append(double, int, boolean, boolean)
1482:             *@JVM-1.1+@
1483:             public static Appendable format(double d, int digits,
1484:             boolean scientific, boolean showZero, Appendable a) throws IOException {
1485:             if (a instanceof TextBuilder)
1486:             return ((TextBuilder) a).append(d, digits, scientific, showZero);
1487:             TextBuilder tmp = TextBuilder.newInstance();
1488:             tmp.append(d, digits, scientific, showZero);
1489:             appendTo(a, tmp);
1490:             TextBuilder.recycle(tmp);
1491:             return a;
1492:             }
1493:             /**/
1494:
1495:            /**
1496:             * Appends to the specified appendable the text builder argument
1497:             * (for text builder less than 32 characters).
1498:             *
1499:             * @param  a the appendable.
1500:             * @param  txt the text to be append.
1501:             * @throws IOException if an I/O exception occurs.
1502:             */
1503:            private static void appendTo(Object to, TextBuilder txt)
1504:                    throws IOException {
1505:                if (to instanceof  StringBuffer) {
1506:                    txt.appendTo((StringBuffer) to);
1507:                    /* @JVM-1.5+@            
1508:                    } else if (to instanceof StringBuilder) {
1509:                        txt.appendTo((StringBuilder) to);
1510:                    /**/
1511:                } else {
1512:                    ((Appendable) to).append(txt);
1513:                }
1514:            }
1515:
1516:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.