Source Code Cross Referenced for Scanner.java in  » 6.0-JDK-Core » Collections-Jar-Zip-Logging-regex » java » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » Collections Jar Zip Logging regex » java.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package java.util;
0027
0028        import java.util.regex.*;
0029        import java.io.*;
0030        import java.math.*;
0031        import java.nio.*;
0032        import java.nio.channels.*;
0033        import java.nio.charset.*;
0034        import java.text.*;
0035        import java.util.Locale;
0036        import sun.misc.LRUCache;
0037
0038        /**
0039         * A simple text scanner which can parse primitive types and strings using
0040         * regular expressions.
0041         *
0042         * <p>A <code>Scanner</code> breaks its input into tokens using a 
0043         * delimiter pattern, which by default matches whitespace. The resulting 
0044         * tokens may then be converted into values of different types using the 
0045         * various <tt>next</tt> methods.
0046         *
0047         * <p>For example, this code allows a user to read a number from 
0048         * <tt>System.in</tt>:
0049         * <blockquote><pre>
0050         *     Scanner sc = new Scanner(System.in);
0051         *     int i = sc.nextInt();
0052         * </pre></blockquote>
0053         *
0054         * <p>As another example, this code allows <code>long</code> types to be
0055         * assigned from entries in a file <code>myNumbers</code>:
0056         * <blockquote><pre>
0057         *      Scanner sc = new Scanner(new File("myNumbers"));
0058         *      while (sc.hasNextLong()) {
0059         *          long aLong = sc.nextLong();
0060         *      }</pre></blockquote>
0061         *
0062         * <p>The scanner can also use delimiters other than whitespace. This 
0063         * example reads several items in from a string:
0064         *<blockquote><pre>
0065         *     String input = "1 fish 2 fish red fish blue fish";
0066         *     Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
0067         *     System.out.println(s.nextInt());
0068         *     System.out.println(s.nextInt());
0069         *     System.out.println(s.next());
0070         *     System.out.println(s.next());
0071         *     s.close(); </pre></blockquote>
0072         * <p>
0073         * prints the following output:
0074         * <blockquote><pre>
0075         *     1
0076         *     2
0077         *     red
0078         *     blue </pre></blockquote>
0079         *
0080         * <p>The same output can be generated with this code, which uses a regular
0081         * expression to parse all four tokens at once:
0082         *<blockquote><pre>
0083         *     String input = "1 fish 2 fish red fish blue fish";
0084         *     Scanner s = new Scanner(input);
0085         *     s.findInLine("(\\d+) fish (\\d+) fish (\\w+) fish (\\w+)");
0086         *     MatchResult result = s.match();
0087         *     for (int i=1; i<=result.groupCount(); i++)
0088         *         System.out.println(result.group(i));
0089         *     s.close(); </pre></blockquote>
0090         *
0091         * <p>The <a name="default-delimiter">default whitespace delimiter</a> used 
0092         * by a scanner is as recognized by {@link java.lang.Character}.{@link
0093         * java.lang.Character#isWhitespace(char) isWhitespace}. The {@link #reset}
0094         * method will reset the value of the scanner's delimiter to the default
0095         * whitespace delimiter regardless of whether it was previously changed.
0096         * 
0097         * <p>A scanning operation may block waiting for input.
0098         *
0099         * <p>The {@link #next} and {@link #hasNext} methods and their 
0100         * primitive-type companion methods (such as {@link #nextInt} and 
0101         * {@link #hasNextInt}) first skip any input that matches the delimiter
0102         * pattern, and then attempt to return the next token. Both <tt>hasNext</tt>
0103         * and <tt>next</tt> methods may block waiting for further input.  Whether a
0104         * <tt>hasNext</tt> method blocks has no connection to whether or not its
0105         * associated <tt>next</tt> method will block.
0106         *
0107         * <p> The {@link #findInLine}, {@link #findWithinHorizon}, and {@link #skip}
0108         * methods operate independently of the delimiter pattern. These methods will 
0109         * attempt to match the specified pattern with no regard to delimiters in the 
0110         * input and thus can be used in special circumstances where delimiters are 
0111         * not relevant. These methods may block waiting for more input.
0112         *
0113         * <p>When a scanner throws an {@link InputMismatchException}, the scanner
0114         * will not pass the token that caused the exception, so that it may be
0115         * retrieved or skipped via some other method.
0116         *
0117         * <p>Depending upon the type of delimiting pattern, empty tokens may be
0118         * returned. For example, the pattern <tt>"\\s+"</tt> will return no empty 
0119         * tokens since it matches multiple instances of the delimiter. The delimiting 
0120         * pattern <tt>"\\s"</tt> could return empty tokens since it only passes one 
0121         * space at a time.
0122         *
0123         * <p> A scanner can read text from any object which implements the {@link
0124         * java.lang.Readable} interface.  If an invocation of the underlying
0125         * readable's {@link java.lang.Readable#read} method throws an {@link
0126         * java.io.IOException} then the scanner assumes that the end of the input
0127         * has been reached.  The most recent <tt>IOException</tt> thrown by the
0128         * underlying readable can be retrieved via the {@link #ioException} method.
0129         *
0130         * <p>When a <code>Scanner</code> is closed, it will close its input source
0131         * if the source implements the {@link java.io.Closeable} interface.
0132         *
0133         * <p>A <code>Scanner</code> is not safe for multithreaded use without
0134         * external synchronization.
0135         *
0136         * <p>Unless otherwise mentioned, passing a <code>null</code> parameter into
0137         * any method of a <code>Scanner</code> will cause a
0138         * <code>NullPointerException</code> to be thrown.
0139         *
0140         * <p>A scanner will default to interpreting numbers as decimal unless a
0141         * different radix has been set by using the {@link #useRadix} method. The
0142         * {@link #reset} method will reset the value of the scanner's radix to
0143         * <code>10</code> regardless of whether it was previously changed.
0144         *
0145         * <a name="localized-numbers">
0146         * <h4> Localized numbers </h4>
0147         *
0148         * <p> An instance of this class is capable of scanning numbers in the standard
0149         * formats as well as in the formats of the scanner's locale. A scanner's 
0150         * <a name="initial-locale">initial locale </a>is the value returned by the {@link
0151         * java.util.Locale#getDefault} method; it may be changed via the {@link
0152         * #useLocale} method. The {@link #reset} method will reset the value of the
0153         * scanner's locale to the initial locale regardless of whether it was
0154         * previously changed.
0155         *
0156         * <p>The localized formats are defined in terms of the following parameters, 
0157         * which for a particular locale are taken from that locale's {@link
0158         * java.text.DecimalFormat DecimalFormat} object, <tt>df</tt>, and its and
0159         * {@link java.text.DecimalFormatSymbols DecimalFormatSymbols} object,
0160         * <tt>dfs</tt>.
0161         *
0162         * <blockquote><table>
0163         * <tr><td valign="top"><i>LocalGroupSeparator&nbsp;&nbsp;</i></td>
0164         *     <td valign="top">The character used to separate thousands groups,
0165         *                      <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
0166         *                      java.text.DecimalFormatSymbols#getGroupingSeparator
0167         *                      getGroupingSeparator()}</td></tr>
0168         * <tr><td valign="top"><i>LocalDecimalSeparator&nbsp;&nbsp;</i></td>
0169         *     <td valign="top">The character used for the decimal point,
0170         *                      <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
0171         *                      java.text.DecimalFormatSymbols#getDecimalSeparator
0172         *                      getDecimalSeparator()}</td></tr>
0173         * <tr><td valign="top"><i>LocalPositivePrefix&nbsp;&nbsp;</i></td>
0174         *     <td valign="top">The string that appears before a positive number (may
0175         *                      be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
0176         *                      java.text.DecimalFormat#getPositivePrefix
0177         *                      getPositivePrefix()}</td></tr>
0178         * <tr><td valign="top"><i>LocalPositiveSuffix&nbsp;&nbsp;</i></td>
0179         *     <td valign="top">The string that appears after a positive number (may be
0180         *                      empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
0181         *                      java.text.DecimalFormat#getPositiveSuffix
0182         *                      getPositiveSuffix()}</td></tr>
0183         * <tr><td valign="top"><i>LocalNegativePrefix&nbsp;&nbsp;</i></td>
0184         *     <td valign="top">The string that appears before a negative number (may
0185         *                      be empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
0186         *                      java.text.DecimalFormat#getNegativePrefix
0187         *                      getNegativePrefix()}</td></tr>
0188         * <tr><td valign="top"><i>LocalNegativeSuffix&nbsp;&nbsp;</i></td>
0189         *     <td valign="top">The string that appears after a negative number (may be
0190         *                      empty), <i>i.e.,</i>&nbsp;<tt>df.</tt>{@link
0191         *                      java.text.DecimalFormat#getNegativeSuffix
0192         *                      getNegativeSuffix()}</td></tr>
0193         * <tr><td valign="top"><i>LocalNaN&nbsp;&nbsp;</i></td>
0194         *     <td valign="top">The string that represents not-a-number for
0195         *                      floating-point values,
0196         *                      <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
0197         *                      java.text.DecimalFormatSymbols#getNaN
0198         *                      getNaN()}</td></tr>
0199         * <tr><td valign="top"><i>LocalInfinity&nbsp;&nbsp;</i></td>
0200         *     <td valign="top">The string that represents infinity for floating-point
0201         *                      values, <i>i.e.,</i>&nbsp;<tt>dfs.</tt>{@link
0202         *                      java.text.DecimalFormatSymbols#getInfinity
0203         *                      getInfinity()}</td></tr>
0204         * </table></blockquote>
0205         * 
0206         * <a name="number-syntax">
0207         * <h4> Number syntax </h4>
0208         *
0209         * <p> The strings that can be parsed as numbers by an instance of this class
0210         * are specified in terms of the following regular-expression grammar, where
0211         * Rmax is the highest digit in the radix being used (for example, Rmax is 9
0212         * in base 10).
0213         *
0214         * <p>
0215         * <table cellspacing=0 cellpadding=0 align=center>
0216         * 
0217         *   <tr><td valign=top align=right><i>NonASCIIDigit</i>&nbsp;&nbsp;::</td>
0218         *       <td valign=top>= A non-ASCII character c for which
0219         *            {@link java.lang.Character#isDigit Character.isDigit}<tt>(c)</tt>
0220         *                        returns&nbsp;true</td></tr>
0221         * 
0222         *   <tr><td>&nbsp;</td></tr>
0223         * 
0224         *   <tr><td align=right><i>Non0Digit</i>&nbsp;&nbsp;::</td>
0225         *   <td><tt>= [1-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i></td></tr>
0226         * 
0227         *   <tr><td>&nbsp;</td></tr>
0228         * 
0229         *   <tr><td align=right><i>Digit</i>&nbsp;&nbsp;::</td>
0230         *   <td><tt>= [0-</tt><i>Rmax</i><tt>] | </tt><i>NonASCIIDigit</i></td></tr>
0231         * 
0232         *   <tr><td>&nbsp;</td></tr>
0233         * 
0234         *   <tr><td valign=top align=right><i>GroupedNumeral</i>&nbsp;&nbsp;::</td>
0235         *       <td valign=top>
0236         *         <table cellpadding=0 cellspacing=0>
0237         *           <tr><td><tt>= (&nbsp;</tt></td>
0238         *               <td><i>Non0Digit</i><tt>
0239         *                   </tt><i>Digit</i><tt>?
0240         *                   </tt><i>Digit</i><tt>?</tt></td></tr>
0241         *           <tr><td></td>
0242         *               <td><tt>(&nbsp;</tt><i>LocalGroupSeparator</i><tt>
0243         *                         </tt><i>Digit</i><tt>
0244         *                         </tt><i>Digit</i><tt>
0245         *                         </tt><i>Digit</i><tt> )+ )</tt></td></tr>
0246         *         </table></td></tr>
0247         * 
0248         *   <tr><td>&nbsp;</td></tr>
0249         * 
0250         *   <tr><td align=right><i>Numeral</i>&nbsp;&nbsp;::</td>
0251         *       <td><tt>= ( ( </tt><i>Digit</i><tt>+ )
0252         *               | </tt><i>GroupedNumeral</i><tt> )</tt></td></tr>
0253         * 
0254         *   <tr><td>&nbsp;</td></tr>
0255         *
0256         *   <tr><td valign=top align=right>
0257         *         <a name="Integer-regex"><i>Integer</i>&nbsp;&nbsp;::</td>
0258         *       <td valign=top><tt>= ( [-+]? ( </tt><i>Numeral</i><tt>
0259         *                               ) )</tt></td></tr>
0260         *   <tr><td></td>
0261         *       <td><tt>| </tt><i>LocalPositivePrefix</i><tt> </tt><i>Numeral</i><tt>
0262         *                      </tt><i>LocalPositiveSuffix</i></td></tr>
0263         *   <tr><td></td>
0264         *       <td><tt>| </tt><i>LocalNegativePrefix</i><tt> </tt><i>Numeral</i><tt>
0265         *                 </tt><i>LocalNegativeSuffix</i></td></tr>
0266         * 
0267         *   <tr><td>&nbsp;</td></tr>
0268         * 
0269         *   <tr><td align=right><i>DecimalNumeral</i>&nbsp;&nbsp;::</td>
0270         *       <td><tt>= </tt><i>Numeral</i></td></tr>
0271         *   <tr><td></td>
0272         *       <td><tt>| </tt><i>Numeral</i><tt>
0273         *                 </tt><i>LocalDecimalSeparator</i><tt>
0274         *                 </tt><i>Digit</i><tt>*</tt></td></tr>
0275         *   <tr><td></td>
0276         *       <td><tt>| </tt><i>LocalDecimalSeparator</i><tt>
0277         *                 </tt><i>Digit</i><tt>+</tt></td></tr>
0278         * 
0279         *   <tr><td>&nbsp;</td></tr>
0280         * 
0281         *   <tr><td align=right><i>Exponent</i>&nbsp;&nbsp;::</td>
0282         *       <td><tt>= ( [eE] [+-]? </tt><i>Digit</i><tt>+ )</tt></td></tr>
0283         * 
0284         *   <tr><td>&nbsp;</td></tr>
0285         * 
0286         *   <tr><td align=right>
0287         *         <a name="Decimal-regex"><i>Decimal</i>&nbsp;&nbsp;::</td>
0288         *       <td><tt>= ( [-+]? </tt><i>DecimalNumeral</i><tt>
0289         *                         </tt><i>Exponent</i><tt>? )</tt></td></tr>
0290         *   <tr><td></td>
0291         *       <td><tt>| </tt><i>LocalPositivePrefix</i><tt>
0292         *                 </tt><i>DecimalNumeral</i><tt>
0293         *                 </tt><i>LocalPositiveSuffix</i>
0294         *                 </tt><i>Exponent</i><tt>?</td></tr>
0295         *   <tr><td></td>
0296         *       <td><tt>| </tt><i>LocalNegativePrefix</i><tt>
0297         *                 </tt><i>DecimalNumeral</i><tt>
0298         *                 </tt><i>LocalNegativeSuffix</i>
0299         *                 </tt><i>Exponent</i><tt>?</td></tr>
0300         * 
0301         *   <tr><td>&nbsp;</td></tr>
0302         * 
0303         *   <tr><td align=right><i>HexFloat</i>&nbsp;&nbsp;::</td>
0304         *       <td><tt>= [-+]? 0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+
0305         *                 ([pP][-+]?[0-9]+)?</tt></td></tr>
0306         * 
0307         *   <tr><td>&nbsp;</td></tr>
0308         *
0309         *   <tr><td align=right><i>NonNumber</i>&nbsp;&nbsp;::</td>
0310         *       <td valign=top><tt>= NaN
0311         *                          | </tt><i>LocalNan</i><tt>
0312         *                          | Infinity
0313         *                          | </tt><i>LocalInfinity</i></td></tr>
0314         *
0315         *   <tr><td>&nbsp;</td></tr>
0316         *
0317         *   <tr><td align=right><i>SignedNonNumber</i>&nbsp;&nbsp;::</td>
0318         *       <td><tt>= ( [-+]? </tt><i>NonNumber</i><tt> )</tt></td></tr>
0319         *   <tr><td></td>
0320         *       <td><tt>| </tt><i>LocalPositivePrefix</i><tt>
0321         *                 </tt><i>NonNumber</i><tt>
0322         *                 </tt><i>LocalPositiveSuffix</i></td></tr>
0323         *   <tr><td></td>
0324         *       <td><tt>| </tt><i>LocalNegativePrefix</i><tt>
0325         *                 </tt><i>NonNumber</i><tt>
0326         *                 </tt><i>LocalNegativeSuffix</i></td></tr>
0327         * 
0328         *   <tr><td>&nbsp;</td></tr>
0329         * 
0330         *   <tr><td valign=top align=right>
0331         *         <a name="Float-regex"><i>Float</i>&nbsp;&nbsp;::</td>
0332         *       <td valign=top><tt>= </tt><i>Decimal</i><tt></td></tr>
0333         *       <tr><td></td>
0334         *           <td><tt>| </tt><i>HexFloat</i><tt></td></tr>
0335         *       <tr><td></td>
0336         *           <td><tt>| </tt><i>SignedNonNumber</i><tt></td></tr>
0337         * 
0338         * </table>
0339         * </center>
0340         *
0341         * <p> Whitespace is not significant in the above regular expressions.
0342         *
0343         * @version 1.34, 06/11/07 
0344         * @since   1.5
0345         */
0346        public final class Scanner implements  Iterator<String> {
0347
0348            // Internal buffer used to hold input
0349            private CharBuffer buf;
0350
0351            // Size of internal character buffer
0352            private static final int BUFFER_SIZE = 1024; // change to 1024;
0353
0354            // The index into the buffer currently held by the Scanner
0355            private int position;
0356
0357            // Internal matcher used for finding delimiters
0358            private Matcher matcher;
0359
0360            // Pattern used to delimit tokens
0361            private Pattern delimPattern;
0362
0363            // Pattern found in last hasNext operation
0364            private Pattern hasNextPattern;
0365
0366            // Position after last hasNext operation
0367            private int hasNextPosition;
0368
0369            // Result after last hasNext operation
0370            private String hasNextResult;
0371
0372            // The input source
0373            private Readable source;
0374
0375            // Boolean is true if source is done
0376            private boolean sourceClosed = false;
0377
0378            // Boolean indicating more input is required
0379            private boolean needInput = false;
0380
0381            // Boolean indicating if a delim has been skipped this operation
0382            private boolean skipped = false;
0383
0384            // A store of a position that the scanner may fall back to
0385            private int savedScannerPosition = -1;
0386
0387            // A cache of the last primitive type scanned
0388            private Object typeCache = null;
0389
0390            // Boolean indicating if a match result is available
0391            private boolean matchValid = false;
0392
0393            // Boolean indicating if this scanner has been closed
0394            private boolean closed = false;
0395
0396            // The current radix used by this scanner
0397            private int radix = 10;
0398
0399            // The default radix for this scanner
0400            private int defaultRadix = 10;
0401
0402            // The locale used by this scanner
0403            private Locale locale = null;
0404
0405            // A cache of the last few recently used Patterns
0406            private LRUCache<String, Pattern> patternCache = new LRUCache<String, Pattern>(
0407                    7) {
0408                protected Pattern create(String s) {
0409                    return Pattern.compile(s);
0410                }
0411
0412                protected boolean hasName(Pattern p, String s) {
0413                    return p.pattern().equals(s);
0414                }
0415            };
0416
0417            // A holder of the last IOException encountered
0418            private IOException lastException;
0419
0420            // A pattern for java whitespace
0421            private static Pattern WHITESPACE_PATTERN = Pattern
0422                    .compile("\\p{javaWhitespace}+");
0423
0424            // A pattern for any token
0425            private static Pattern FIND_ANY_PATTERN = Pattern.compile("(?s).*");
0426
0427            // A pattern for non-ASCII digits
0428            private static Pattern NON_ASCII_DIGIT = Pattern
0429                    .compile("[\\p{javaDigit}&&[^0-9]]");
0430
0431            // Fields and methods to support scanning primitive types
0432
0433            /**
0434             * Locale dependent values used to scan numbers
0435             */
0436            private String groupSeparator = "\\,";
0437            private String decimalSeparator = "\\.";
0438            private String nanString = "NaN";
0439            private String infinityString = "Infinity";
0440            private String positivePrefix = "";
0441            private String negativePrefix = "\\-";
0442            private String positiveSuffix = "";
0443            private String negativeSuffix = "";
0444
0445            /**
0446             * Fields and an accessor method to match booleans
0447             */
0448            private static volatile Pattern boolPattern;
0449            private static final String BOOLEAN_PATTERN = "true|false";
0450
0451            private static Pattern boolPattern() {
0452                Pattern bp = boolPattern;
0453                if (bp == null)
0454                    boolPattern = bp = Pattern.compile(BOOLEAN_PATTERN,
0455                            Pattern.CASE_INSENSITIVE);
0456                return bp;
0457            }
0458
0459            /**
0460             * Fields and methods to match bytes, shorts, ints, and longs
0461             */
0462            private Pattern integerPattern;
0463            private String digits = "0123456789abcdefghijklmnopqrstuvwxyz";
0464            private String non0Digit = "[\\p{javaDigit}&&[^0]]";
0465            private int SIMPLE_GROUP_INDEX = 5;
0466
0467            private String buildIntegerPatternString() {
0468                String radixDigits = digits.substring(0, radix);
0469                // \\p{javaDigit} is not guaranteed to be appropriate
0470                // here but what can we do? The final authority will be
0471                // whatever parse method is invoked, so ultimately the
0472                // Scanner will do the right thing
0473                String digit = "((?i)[" + radixDigits + "]|\\p{javaDigit})";
0474                String groupedNumeral = "(" + non0Digit + digit + "?" + digit
0475                        + "?(" + groupSeparator + digit + digit + digit + ")+)";
0476                // digit++ is the possessive form which is necessary for reducing
0477                // backtracking that would otherwise cause unacceptable performance
0478                String numeral = "((" + digit + "++)|" + groupedNumeral + ")";
0479                String javaStyleInteger = "([-+]?(" + numeral + "))";
0480                String negativeInteger = negativePrefix + numeral
0481                        + negativeSuffix;
0482                String positiveInteger = positivePrefix + numeral
0483                        + positiveSuffix;
0484                return "(" + javaStyleInteger + ")|(" + positiveInteger + ")|("
0485                        + negativeInteger + ")";
0486            }
0487
0488            private Pattern integerPattern() {
0489                if (integerPattern == null) {
0490                    integerPattern = patternCache
0491                            .forName(buildIntegerPatternString());
0492                }
0493                return integerPattern;
0494            }
0495
0496            /**
0497             * Fields and an accessor method to match line separators
0498             */
0499            private static volatile Pattern separatorPattern;
0500            private static volatile Pattern linePattern;
0501            private static final String LINE_SEPARATOR_PATTERN = "\r\n|[\n\r\u2028\u2029\u0085]";
0502            private static final String LINE_PATTERN = ".*("
0503                    + LINE_SEPARATOR_PATTERN + ")|.+$";
0504
0505            private static Pattern separatorPattern() {
0506                Pattern sp = separatorPattern;
0507                if (sp == null)
0508                    separatorPattern = sp = Pattern
0509                            .compile(LINE_SEPARATOR_PATTERN);
0510                return sp;
0511            }
0512
0513            private static Pattern linePattern() {
0514                Pattern lp = linePattern;
0515                if (lp == null)
0516                    linePattern = lp = Pattern.compile(LINE_PATTERN);
0517                return lp;
0518            }
0519
0520            /**
0521             * Fields and methods to match floats and doubles
0522             */
0523            private Pattern floatPattern;
0524            private Pattern decimalPattern;
0525
0526            private void buildFloatAndDecimalPattern() {
0527                // \\p{javaDigit} may not be perfect, see above
0528                String digit = "([0-9]|(\\p{javaDigit}))";
0529                String exponent = "([eE][+-]?" + digit + "+)?";
0530                String groupedNumeral = "(" + non0Digit + digit + "?" + digit
0531                        + "?(" + groupSeparator + digit + digit + digit + ")+)";
0532                // Once again digit++ is used for performance, as above
0533                String numeral = "((" + digit + "++)|" + groupedNumeral + ")";
0534                String decimalNumeral = "(" + numeral + "|" + numeral
0535                        + decimalSeparator + digit + "*+|" + decimalSeparator
0536                        + digit + "++)";
0537                String nonNumber = "(NaN|" + nanString + "|Infinity|"
0538                        + infinityString + ")";
0539                String positiveFloat = "(" + positivePrefix + decimalNumeral
0540                        + positiveSuffix + exponent + ")";
0541                String negativeFloat = "(" + negativePrefix + decimalNumeral
0542                        + negativeSuffix + exponent + ")";
0543                String decimal = "(([-+]?" + decimalNumeral + exponent + ")|"
0544                        + positiveFloat + "|" + negativeFloat + ")";
0545                String hexFloat = "[-+]?0[xX][0-9a-fA-F]*\\.[0-9a-fA-F]+([pP][-+]?[0-9]+)?";
0546                String positiveNonNumber = "(" + positivePrefix + nonNumber
0547                        + positiveSuffix + ")";
0548                String negativeNonNumber = "(" + negativePrefix + nonNumber
0549                        + negativeSuffix + ")";
0550                String signedNonNumber = "(([-+]?" + nonNumber + ")|"
0551                        + positiveNonNumber + "|" + negativeNonNumber + ")";
0552                floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|"
0553                        + signedNonNumber);
0554                decimalPattern = Pattern.compile(decimal);
0555            }
0556
0557            private Pattern floatPattern() {
0558                if (floatPattern == null) {
0559                    buildFloatAndDecimalPattern();
0560                }
0561                return floatPattern;
0562            }
0563
0564            private Pattern decimalPattern() {
0565                if (decimalPattern == null) {
0566                    buildFloatAndDecimalPattern();
0567                }
0568                return decimalPattern;
0569            }
0570
0571            // Constructors
0572
0573            /**
0574             * Constructs a <code>Scanner</code> that returns values scanned
0575             * from the specified source delimited by the specified pattern.
0576             *
0577             * @param  source A character source implementing the Readable interface
0578             * @param pattern A delimiting pattern
0579             * @return A scanner with the specified source and pattern
0580             */
0581            private Scanner(Readable source, Pattern pattern) {
0582                if (source == null)
0583                    throw new NullPointerException("source");
0584                if (pattern == null)
0585                    throw new NullPointerException("pattern");
0586                this .source = source;
0587                delimPattern = pattern;
0588                buf = CharBuffer.allocate(BUFFER_SIZE);
0589                buf.limit(0);
0590                matcher = delimPattern.matcher(buf);
0591                matcher.useTransparentBounds(true);
0592                matcher.useAnchoringBounds(false);
0593                useLocale(Locale.getDefault());
0594            }
0595
0596            /**
0597             * Constructs a new <code>Scanner</code> that produces values scanned
0598             * from the specified source.
0599             *
0600             * @param  source A character source implementing the {@link Readable}
0601             *         interface
0602             */
0603            public Scanner(Readable source) {
0604                this (source, WHITESPACE_PATTERN);
0605            }
0606
0607            /**
0608             * Constructs a new <code>Scanner</code> that produces values scanned
0609             * from the specified input stream. Bytes from the stream are converted 
0610             * into characters using the underlying platform's
0611             * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
0612             *
0613             * @param  source An input stream to be scanned
0614             */
0615            public Scanner(InputStream source) {
0616                this (new InputStreamReader(source), WHITESPACE_PATTERN);
0617            }
0618
0619            /**
0620             * Constructs a new <code>Scanner</code> that produces values scanned
0621             * from the specified input stream. Bytes from the stream are converted 
0622             * into characters using the specified charset.
0623             *
0624             * @param  source An input stream to be scanned
0625             * @param charsetName The encoding type used to convert bytes from the
0626             *        stream into characters to be scanned
0627             * @throws IllegalArgumentException if the specified character set
0628             *         does not exist
0629             */
0630            public Scanner(InputStream source, String charsetName) {
0631                this (makeReadable(source, charsetName), WHITESPACE_PATTERN);
0632            }
0633
0634            private static Readable makeReadable(InputStream source,
0635                    String charsetName) {
0636                if (source == null)
0637                    throw new NullPointerException("source");
0638                InputStreamReader isr = null;
0639                try {
0640                    isr = new InputStreamReader(source, charsetName);
0641                } catch (UnsupportedEncodingException uee) {
0642                    IllegalArgumentException iae = new IllegalArgumentException();
0643                    iae.initCause(uee);
0644                    throw iae;
0645                }
0646                return isr;
0647            }
0648
0649            /**
0650             * Constructs a new <code>Scanner</code> that produces values scanned
0651             * from the specified file. Bytes from the file are converted into 
0652             * characters using the underlying platform's
0653             * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
0654             *
0655             * @param  source A file to be scanned
0656             * @throws FileNotFoundException if source is not found
0657             */
0658            public Scanner(File source) throws FileNotFoundException {
0659                this ((ReadableByteChannel) (new FileInputStream(source)
0660                        .getChannel()));
0661            }
0662
0663            /**
0664             * Constructs a new <code>Scanner</code> that produces values scanned
0665             * from the specified file. Bytes from the file are converted into 
0666             * characters using the specified charset.
0667             *
0668             * @param  source A file to be scanned
0669             * @param charsetName The encoding type used to convert bytes from the file
0670             *        into characters to be scanned
0671             * @throws FileNotFoundException if source is not found
0672             * @throws IllegalArgumentException if the specified encoding is 
0673             *         not found
0674             */
0675            public Scanner(File source, String charsetName)
0676                    throws FileNotFoundException {
0677                this ((ReadableByteChannel) (new FileInputStream(source)
0678                        .getChannel()), charsetName);
0679            }
0680
0681            /**
0682             * Constructs a new <code>Scanner</code> that produces values scanned
0683             * from the specified string.
0684             *
0685             * @param  source A string to scan
0686             */
0687            public Scanner(String source) {
0688                this (new StringReader(source), WHITESPACE_PATTERN);
0689            }
0690
0691            /**
0692             * Constructs a new <code>Scanner</code> that produces values scanned
0693             * from the specified channel. Bytes from the source are converted into 
0694             * characters using the underlying platform's
0695             * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}.
0696             *
0697             * @param  source A channel to scan
0698             */
0699            public Scanner(ReadableByteChannel source) {
0700                this (makeReadable(source), WHITESPACE_PATTERN);
0701            }
0702
0703            private static Readable makeReadable(ReadableByteChannel source) {
0704                if (source == null)
0705                    throw new NullPointerException("source");
0706                String defaultCharsetName = java.nio.charset.Charset
0707                        .defaultCharset().name();
0708                return Channels.newReader(source, java.nio.charset.Charset
0709                        .defaultCharset().name());
0710            }
0711
0712            /**
0713             * Constructs a new <code>Scanner</code> that produces values scanned
0714             * from the specified channel. Bytes from the source are converted into 
0715             * characters using the specified charset.
0716             *
0717             * @param  source A channel to scan
0718             * @param charsetName The encoding type used to convert bytes from the
0719             *        channel into characters to be scanned
0720             * @throws IllegalArgumentException if the specified character set
0721             *         does not exist
0722             */
0723            public Scanner(ReadableByteChannel source, String charsetName) {
0724                this (makeReadable(source, charsetName), WHITESPACE_PATTERN);
0725            }
0726
0727            private static Readable makeReadable(ReadableByteChannel source,
0728                    String charsetName) {
0729                if (source == null)
0730                    throw new NullPointerException("source");
0731                if (!Charset.isSupported(charsetName))
0732                    throw new IllegalArgumentException(charsetName);
0733                return Channels.newReader(source, charsetName);
0734            }
0735
0736            // Private primitives used to support scanning
0737
0738            private void saveState() {
0739                savedScannerPosition = position;
0740            }
0741
0742            private void revertState() {
0743                this .position = savedScannerPosition;
0744                savedScannerPosition = -1;
0745                skipped = false;
0746            }
0747
0748            private boolean revertState(boolean b) {
0749                this .position = savedScannerPosition;
0750                savedScannerPosition = -1;
0751                skipped = false;
0752                return b;
0753            }
0754
0755            private void cacheResult() {
0756                hasNextResult = matcher.group();
0757                hasNextPosition = matcher.end();
0758                hasNextPattern = matcher.pattern();
0759            }
0760
0761            private void cacheResult(String result) {
0762                hasNextResult = result;
0763                hasNextPosition = matcher.end();
0764                hasNextPattern = matcher.pattern();
0765            }
0766
0767            // Clears both regular cache and type cache
0768            private void clearCaches() {
0769                hasNextPattern = null;
0770                typeCache = null;
0771            }
0772
0773            // Also clears both the regular cache and the type cache
0774            private String getCachedResult() {
0775                position = hasNextPosition;
0776                hasNextPattern = null;
0777                typeCache = null;
0778                return hasNextResult;
0779            }
0780
0781            // Also clears both the regular cache and the type cache
0782            private void useTypeCache() {
0783                if (closed)
0784                    throw new IllegalStateException("Scanner closed");
0785                position = hasNextPosition;
0786                hasNextPattern = null;
0787                typeCache = null;
0788            }
0789
0790            // Tries to read more input. May block.
0791            private void readInput() {
0792                if (buf.limit() == buf.capacity())
0793                    makeSpace();
0794
0795                // Prepare to receive data
0796                int p = buf.position();
0797                buf.position(buf.limit());
0798                buf.limit(buf.capacity());
0799
0800                int n = 0;
0801                try {
0802                    n = source.read(buf);
0803                } catch (IOException ioe) {
0804                    lastException = ioe;
0805                    n = -1;
0806                }
0807
0808                if (n == -1) {
0809                    sourceClosed = true;
0810                    needInput = false;
0811                }
0812
0813                if (n > 0)
0814                    needInput = false;
0815
0816                // Restore current position and limit for reading
0817                buf.limit(buf.position());
0818                buf.position(p);
0819            }
0820
0821            // After this method is called there will either be an exception
0822            // or else there will be space in the buffer
0823            private boolean makeSpace() {
0824                clearCaches();
0825                int offset = savedScannerPosition == -1 ? position
0826                        : savedScannerPosition;
0827                buf.position(offset);
0828                // Gain space by compacting buffer
0829                if (offset > 0) {
0830                    buf.compact();
0831                    translateSavedIndexes(offset);
0832                    position -= offset;
0833                    buf.flip();
0834                    return true;
0835                }
0836                // Gain space by growing buffer
0837                int newSize = buf.capacity() * 2;
0838                CharBuffer newBuf = CharBuffer.allocate(newSize);
0839                newBuf.put(buf);
0840                newBuf.flip();
0841                translateSavedIndexes(offset);
0842                position -= offset;
0843                buf = newBuf;
0844                matcher.reset(buf);
0845                return true;
0846            }
0847
0848            // When a buffer compaction/reallocation occurs the saved indexes must
0849            // be modified appropriately
0850            private void translateSavedIndexes(int offset) {
0851                if (savedScannerPosition != -1)
0852                    savedScannerPosition -= offset;
0853            }
0854
0855            // If we are at the end of input then NoSuchElement;
0856            // If there is still input left then InputMismatch
0857            private void throwFor() {
0858                skipped = false;
0859                if ((sourceClosed) && (position == buf.limit()))
0860                    throw new NoSuchElementException();
0861                else
0862                    throw new InputMismatchException();
0863            }
0864
0865            // Returns true if a complete token or partial token is in the buffer.
0866            // It is not necessary to find a complete token since a partial token
0867            // means that there will be another token with or without more input.
0868            private boolean hasTokenInBuffer() {
0869                matchValid = false;
0870                matcher.usePattern(delimPattern);
0871                matcher.region(position, buf.limit());
0872
0873                // Skip delims first
0874                if (matcher.lookingAt())
0875                    position = matcher.end();
0876
0877                // If we are sitting at the end, no more tokens in buffer
0878                if (position == buf.limit())
0879                    return false;
0880
0881                return true;
0882            }
0883
0884            /*
0885             * Returns a "complete token" that matches the specified pattern 
0886             * 
0887             * A token is complete if surrounded by delims; a partial token
0888             * is prefixed by delims but not postfixed by them
0889             * 
0890             * The position is advanced to the end of that complete token
0891             * 
0892             * Pattern == null means accept any token at all
0893             *
0894             * Triple return: 
0895             * 1. valid string means it was found
0896             * 2. null with needInput=false means we won't ever find it
0897             * 3. null with needInput=true means try again after readInput
0898             */
0899            private String getCompleteTokenInBuffer(Pattern pattern) {
0900                matchValid = false;
0901
0902                // Skip delims first
0903                matcher.usePattern(delimPattern);
0904                if (!skipped) { // Enforcing only one skip of leading delims
0905                    matcher.region(position, buf.limit());
0906                    if (matcher.lookingAt()) {
0907                        // If more input could extend the delimiters then we must wait 
0908                        // for more input
0909                        if (matcher.hitEnd() && !sourceClosed) {
0910                            needInput = true;
0911                            return null;
0912                        }
0913                        // The delims were whole and the matcher should skip them
0914                        skipped = true;
0915                        position = matcher.end();
0916                    }
0917                }
0918
0919                // If we are sitting at the end, no more tokens in buffer
0920                if (position == buf.limit()) {
0921                    if (sourceClosed)
0922                        return null;
0923                    needInput = true;
0924                    return null;
0925                }
0926
0927                // Must look for next delims. Simply attempting to match the
0928                // pattern at this point may find a match but it might not be
0929                // the first longest match because of missing input, or it might
0930                // match a partial token instead of the whole thing.
0931
0932                // Then look for next delims
0933                matcher.region(position, buf.limit());
0934                boolean foundNextDelim = matcher.find();
0935                if (foundNextDelim && (matcher.end() == position)) {
0936                    // Zero length delimiter match; we should find the next one
0937                    // using the automatic advance past a zero length match;
0938                    // Otherwise we have just found the same one we just skipped
0939                    foundNextDelim = matcher.find();
0940                }
0941                if (foundNextDelim) {
0942                    // In the rare case that more input could cause the match
0943                    // to be lost and there is more input coming we must wait 
0944                    // for more input. Note that hitting the end is okay as long
0945                    // as the match cannot go away. It is the beginning of the
0946                    // next delims we want to be sure about, we don't care if
0947                    // they potentially extend further.
0948                    if (matcher.requireEnd() && !sourceClosed) {
0949                        needInput = true;
0950                        return null;
0951                    }
0952                    int tokenEnd = matcher.start();
0953                    // There is a complete token.
0954                    if (pattern == null) {
0955                        // Must continue with match to provide valid MatchResult
0956                        pattern = FIND_ANY_PATTERN;
0957                    }
0958                    //  Attempt to match against the desired pattern
0959                    matcher.usePattern(pattern);
0960                    matcher.region(position, tokenEnd);
0961                    if (matcher.matches()) {
0962                        String s = matcher.group();
0963                        position = matcher.end();
0964                        return s;
0965                    } else { // Complete token but it does not match
0966                        return null;
0967                    }
0968                }
0969
0970                // If we can't find the next delims but no more input is coming,
0971                // then we can treat the remainder as a whole token
0972                if (sourceClosed) {
0973                    if (pattern == null) {
0974                        // Must continue with match to provide valid MatchResult
0975                        pattern = FIND_ANY_PATTERN;
0976                    }
0977                    // Last token; Match the pattern here or throw
0978                    matcher.usePattern(pattern);
0979                    matcher.region(position, buf.limit());
0980                    if (matcher.matches()) {
0981                        String s = matcher.group();
0982                        position = matcher.end();
0983                        return s;
0984                    }
0985                    // Last piece does not match
0986                    return null;
0987                }
0988
0989                // There is a partial token in the buffer; must read more
0990                // to complete it
0991                needInput = true;
0992                return null;
0993            }
0994
0995            // Finds the specified pattern in the buffer up to horizon.
0996            // Returns a match for the specified input pattern.
0997            private String findPatternInBuffer(Pattern pattern, int horizon) {
0998                matchValid = false;
0999                matcher.usePattern(pattern);
1000                int bufferLimit = buf.limit();
1001                int horizonLimit = -1;
1002                int searchLimit = bufferLimit;
1003                if (horizon > 0) {
1004                    horizonLimit = position + horizon;
1005                    if (horizonLimit < bufferLimit)
1006                        searchLimit = horizonLimit;
1007                }
1008                matcher.region(position, searchLimit);
1009                if (matcher.find()) {
1010                    if (matcher.hitEnd() && (!sourceClosed)) {
1011                        // The match may be longer if didn't hit horizon or real end
1012                        if (searchLimit != horizonLimit) {
1013                            // Hit an artificial end; try to extend the match
1014                            needInput = true;
1015                            return null;
1016                        }
1017                        // The match could go away depending on what is next
1018                        if ((searchLimit == horizonLimit)
1019                                && matcher.requireEnd()) {
1020                            // Rare case: we hit the end of input and it happens
1021                            // that it is at the horizon and the end of input is 
1022                            // required for the match.
1023                            needInput = true;
1024                            return null;
1025                        }
1026                    }
1027                    // Did not hit end, or hit real end, or hit horizon
1028                    position = matcher.end();
1029                    return matcher.group();
1030                }
1031
1032                if (sourceClosed)
1033                    return null;
1034
1035                // If there is no specified horizon, or if we have not searched
1036                // to the specified horizon yet, get more input
1037                if ((horizon == 0) || (searchLimit != horizonLimit))
1038                    needInput = true;
1039                return null;
1040            }
1041
1042            // Returns a match for the specified input pattern anchored at
1043            // the current position
1044            private String matchPatternInBuffer(Pattern pattern) {
1045                matchValid = false;
1046                matcher.usePattern(pattern);
1047                matcher.region(position, buf.limit());
1048                if (matcher.lookingAt()) {
1049                    if (matcher.hitEnd() && (!sourceClosed)) {
1050                        // Get more input and try again
1051                        needInput = true;
1052                        return null;
1053                    }
1054                    position = matcher.end();
1055                    return matcher.group();
1056                }
1057
1058                if (sourceClosed)
1059                    return null;
1060
1061                // Read more to find pattern
1062                needInput = true;
1063                return null;
1064            }
1065
1066            // Throws if the scanner is closed
1067            private void ensureOpen() {
1068                if (closed)
1069                    throw new IllegalStateException("Scanner closed");
1070            }
1071
1072            // Public methods
1073
1074            /**
1075             * Closes this scanner.
1076             *
1077             * <p> If this scanner has not yet been closed then if its underlying
1078             * {@linkplain java.lang.Readable readable} also implements the {@link
1079             * java.io.Closeable} interface then the readable's <tt>close</tt> method
1080             * will be invoked.  If this scanner is already closed then invoking this
1081             * method will have no effect.
1082             * 
1083             * <p>Attempting to perform search operations after a scanner has
1084             * been closed will result in an {@link IllegalStateException}.
1085             *
1086             */
1087            public void close() {
1088                if (closed)
1089                    return;
1090                if (source instanceof  Closeable) {
1091                    try {
1092                        ((Closeable) source).close();
1093                    } catch (IOException ioe) {
1094                        lastException = ioe;
1095                    }
1096                }
1097                sourceClosed = true;
1098                source = null;
1099                closed = true;
1100            }
1101
1102            /**
1103             * Returns the <code>IOException</code> last thrown by this
1104             * <code>Scanner</code>'s underlying <code>Readable</code>. This method
1105             * returns <code>null</code> if no such exception exists.
1106             *
1107             * @return the last exception thrown by this scanner's readable
1108             */
1109            public IOException ioException() {
1110                return lastException;
1111            }
1112
1113            /**
1114             * Returns the <code>Pattern</code> this <code>Scanner</code> is currently
1115             * using to match delimiters.
1116             *
1117             * @return this scanner's delimiting pattern.
1118             */
1119            public Pattern delimiter() {
1120                return delimPattern;
1121            }
1122
1123            /**
1124             * Sets this scanner's delimiting pattern to the specified pattern.
1125             *
1126             * @param pattern A delimiting pattern
1127             * @return this scanner
1128             */
1129            public Scanner useDelimiter(Pattern pattern) {
1130                delimPattern = pattern;
1131                return this ;
1132            }
1133
1134            /**
1135             * Sets this scanner's delimiting pattern to a pattern constructed from
1136             * the specified <code>String</code>.
1137             *
1138             * <p> An invocation of this method of the form 
1139             * <tt>useDelimiter(pattern)</tt> behaves in exactly the same way as the
1140             * invocation <tt>useDelimiter(Pattern.compile(pattern))</tt>.
1141             *
1142             * <p> Invoking the {@link #reset} method will set the scanner's delimiter
1143             * to the <a href= "#default-delimiter">default</a>.
1144             *
1145             * @param pattern A string specifying a delimiting pattern
1146             * @return this scanner
1147             */
1148            public Scanner useDelimiter(String pattern) {
1149                delimPattern = patternCache.forName(pattern);
1150                return this ;
1151            }
1152
1153            /**
1154             * Returns this scanner's locale.
1155             *
1156             * <p>A scanner's locale affects many elements of its default
1157             * primitive matching regular expressions; see 
1158             * <a href= "#localized-numbers">localized numbers</a> above.
1159             *
1160             * @return this scanner's locale
1161             */
1162            public Locale locale() {
1163                return this .locale;
1164            }
1165
1166            /**
1167             * Sets this scanner's locale to the specified locale.
1168             *
1169             * <p>A scanner's locale affects many elements of its default
1170             * primitive matching regular expressions; see 
1171             * <a href= "#localized-numbers">localized numbers</a> above.
1172             *
1173             * <p>Invoking the {@link #reset} method will set the scanner's locale to
1174             * the <a href= "#initial-locale">initial locale</a>.
1175             *
1176             * @param locale A string specifying the locale to use
1177             * @return this scanner
1178             */
1179            public Scanner useLocale(Locale locale) {
1180                if (locale.equals(this .locale))
1181                    return this ;
1182
1183                this .locale = locale;
1184                DecimalFormat df = (DecimalFormat) NumberFormat
1185                        .getNumberInstance(locale);
1186                DecimalFormatSymbols dfs = DecimalFormatSymbols
1187                        .getInstance(locale);
1188
1189                // These must be literalized to avoid collision with regex
1190                // metacharacters such as dot or parenthesis
1191                groupSeparator = "\\" + dfs.getGroupingSeparator();
1192                decimalSeparator = "\\" + dfs.getDecimalSeparator();
1193
1194                // Quoting the nonzero length locale-specific things
1195                // to avoid potential conflict with metacharacters
1196                nanString = "\\Q" + dfs.getNaN() + "\\E";
1197                infinityString = "\\Q" + dfs.getInfinity() + "\\E";
1198                positivePrefix = df.getPositivePrefix();
1199                if (positivePrefix.length() > 0)
1200                    positivePrefix = "\\Q" + positivePrefix + "\\E";
1201                negativePrefix = df.getNegativePrefix();
1202                if (negativePrefix.length() > 0)
1203                    negativePrefix = "\\Q" + negativePrefix + "\\E";
1204                positiveSuffix = df.getPositiveSuffix();
1205                if (positiveSuffix.length() > 0)
1206                    positiveSuffix = "\\Q" + positiveSuffix + "\\E";
1207                negativeSuffix = df.getNegativeSuffix();
1208                if (negativeSuffix.length() > 0)
1209                    negativeSuffix = "\\Q" + negativeSuffix + "\\E";
1210
1211                // Force rebuilding and recompilation of locale dependent
1212                // primitive patterns
1213                integerPattern = null;
1214                floatPattern = null;
1215
1216                return this ;
1217            }
1218
1219            /**
1220             * Returns this scanner's default radix.
1221             *
1222             * <p>A scanner's radix affects elements of its default
1223             * number matching regular expressions; see 
1224             * <a href= "#localized-numbers">localized numbers</a> above.
1225             *
1226             * @return the default radix of this scanner
1227             */
1228            public int radix() {
1229                return this .defaultRadix;
1230            }
1231
1232            /**
1233             * Sets this scanner's default radix to the specified radix.
1234             *
1235             * <p>A scanner's radix affects elements of its default
1236             * number matching regular expressions; see 
1237             * <a href= "#localized-numbers">localized numbers</a> above.
1238             *
1239             * <p>If the radix is less than <code>Character.MIN_RADIX</code>
1240             * or greater than <code>Character.MAX_RADIX</code>, then an
1241             * <code>IllegalArgumentException</code> is thrown.
1242             *
1243             * <p>Invoking the {@link #reset} method will set the scanner's radix to
1244             * <code>10</code>.
1245             *
1246             * @param radix The radix to use when scanning numbers
1247             * @return this scanner
1248             * @throws IllegalArgumentException if radix is out of range
1249             */
1250            public Scanner useRadix(int radix) {
1251                if ((radix < Character.MIN_RADIX)
1252                        || (radix > Character.MAX_RADIX))
1253                    throw new IllegalArgumentException("radix:" + radix);
1254
1255                if (this .defaultRadix == radix)
1256                    return this ;
1257                this .defaultRadix = radix;
1258                // Force rebuilding and recompilation of radix dependent patterns
1259                integerPattern = null;
1260                return this ;
1261            }
1262
1263            // The next operation should occur in the specified radix but
1264            // the default is left untouched.
1265            private void setRadix(int radix) {
1266                if (this .radix != radix) {
1267                    // Force rebuilding and recompilation of radix dependent patterns
1268                    integerPattern = null;
1269                    this .radix = radix;
1270                }
1271            }
1272
1273            /**
1274             * Returns the match result of the last scanning operation performed
1275             * by this scanner. This method throws <code>IllegalStateException</code>
1276             * if no match has been performed, or if the last match was
1277             * not successful.
1278             *
1279             * <p>The various <code>next</code>methods of <code>Scanner</code>
1280             * make a match result available if they complete without throwing an
1281             * exception. For instance, after an invocation of the {@link #nextInt}
1282             * method that returned an int, this method returns a 
1283             * <code>MatchResult</code> for the search of the
1284             * <a href="#Integer-regex"><i>Integer</i></a> regular expression
1285             * defined above. Similarly the {@link #findInLine}, 
1286             * {@link #findWithinHorizon}, and {@link #skip} methods will make a
1287             * match available if they succeed.
1288             *
1289             * @return a match result for the last match operation
1290             * @throws IllegalStateException  If no match result is available
1291             */
1292            public MatchResult match() {
1293                if (!matchValid)
1294                    throw new IllegalStateException("No match result available");
1295                return matcher.toMatchResult();
1296            }
1297
1298            /**
1299             * <p>Returns the string representation of this <code>Scanner</code>. The
1300             * string representation of a <code>Scanner</code> contains information
1301             * that may be useful for debugging. The exact format is unspecified.
1302             *
1303             * @return  The string representation of this scanner
1304             */
1305            public String toString() {
1306                StringBuilder sb = new StringBuilder();
1307                sb.append("java.util.Scanner");
1308                sb.append("[delimiters=" + delimPattern + "]");
1309                sb.append("[position=" + position + "]");
1310                sb.append("[match valid=" + matchValid + "]");
1311                sb.append("[need input=" + needInput + "]");
1312                sb.append("[source closed=" + sourceClosed + "]");
1313                sb.append("[skipped=" + skipped + "]");
1314                sb.append("[group separator=" + groupSeparator + "]");
1315                sb.append("[decimal separator=" + decimalSeparator + "]");
1316                sb.append("[positive prefix=" + positivePrefix + "]");
1317                sb.append("[negative prefix=" + negativePrefix + "]");
1318                sb.append("[positive suffix=" + positiveSuffix + "]");
1319                sb.append("[negative suffix=" + negativeSuffix + "]");
1320                sb.append("[NaN string=" + nanString + "]");
1321                sb.append("[infinity string=" + infinityString + "]");
1322                return sb.toString();
1323            }
1324
1325            /**
1326             * Returns true if this scanner has another token in its input.
1327             * This method may block while waiting for input to scan.
1328             * The scanner does not advance past any input.
1329             *
1330             * @return true if and only if this scanner has another token
1331             * @throws IllegalStateException if this scanner is closed
1332             * @see java.util.Iterator
1333             */
1334            public boolean hasNext() {
1335                ensureOpen();
1336                saveState();
1337                while (!sourceClosed) {
1338                    if (hasTokenInBuffer())
1339                        return revertState(true);
1340                    readInput();
1341                }
1342                boolean result = hasTokenInBuffer();
1343                return revertState(result);
1344            }
1345
1346            /**
1347             * Finds and returns the next complete token from this scanner.
1348             * A complete token is preceded and followed by input that matches
1349             * the delimiter pattern. This method may block while waiting for input 
1350             * to scan, even if a previous invocation of {@link #hasNext} returned 
1351             * <code>true</code>.
1352             *
1353             * @return the next token
1354             * @throws NoSuchElementException if no more tokens are available
1355             * @throws IllegalStateException if this scanner is closed
1356             * @see java.util.Iterator
1357             */
1358            public String next() {
1359                ensureOpen();
1360                clearCaches();
1361
1362                while (true) {
1363                    String token = getCompleteTokenInBuffer(null);
1364                    if (token != null) {
1365                        matchValid = true;
1366                        skipped = false;
1367                        return token;
1368                    }
1369                    if (needInput)
1370                        readInput();
1371                    else
1372                        throwFor();
1373                }
1374            }
1375
1376            /**
1377             * The remove operation is not supported by this implementation of
1378             * <code>Iterator</code>.
1379             *
1380             * @throws UnsupportedOperationException if this method is invoked.
1381             * @see java.util.Iterator
1382             */
1383            public void remove() {
1384                throw new UnsupportedOperationException();
1385            }
1386
1387            /**
1388             * Returns true if the next token matches the pattern constructed from the 
1389             * specified string. The scanner does not advance past any input.
1390             *
1391             * <p> An invocation of this method of the form <tt>hasNext(pattern)</tt>
1392             * behaves in exactly the same way as the invocation 
1393             * <tt>hasNext(Pattern.compile(pattern))</tt>.
1394             *
1395             * @param pattern a string specifying the pattern to scan
1396             * @return true if and only if this scanner has another token matching
1397             *         the specified pattern
1398             * @throws IllegalStateException if this scanner is closed
1399             */
1400            public boolean hasNext(String pattern) {
1401                return hasNext(patternCache.forName(pattern));
1402            }
1403
1404            /**
1405             * Returns the next token if it matches the pattern constructed from the 
1406             * specified string.  If the match is successful, the scanner advances 
1407             * past the input that matched the pattern.
1408             *
1409             * <p> An invocation of this method of the form <tt>next(pattern)</tt>
1410             * behaves in exactly the same way as the invocation 
1411             * <tt>next(Pattern.compile(pattern))</tt>.
1412             *
1413             * @param pattern a string specifying the pattern to scan
1414             * @return the next token
1415             * @throws NoSuchElementException if no such tokens are available
1416             * @throws IllegalStateException if this scanner is closed
1417             */
1418            public String next(String pattern) {
1419                return next(patternCache.forName(pattern));
1420            }
1421
1422            /**
1423             * Returns true if the next complete token matches the specified pattern.
1424             * A complete token is prefixed and postfixed by input that matches
1425             * the delimiter pattern. This method may block while waiting for input.
1426             * The scanner does not advance past any input.
1427             *
1428             * @param pattern the pattern to scan for
1429             * @return true if and only if this scanner has another token matching
1430             *         the specified pattern
1431             * @throws IllegalStateException if this scanner is closed
1432             */
1433            public boolean hasNext(Pattern pattern) {
1434                ensureOpen();
1435                if (pattern == null)
1436                    throw new NullPointerException();
1437                hasNextPattern = null;
1438                saveState();
1439
1440                while (true) {
1441                    if (getCompleteTokenInBuffer(pattern) != null) {
1442                        matchValid = true;
1443                        cacheResult();
1444                        return revertState(true);
1445                    }
1446                    if (needInput)
1447                        readInput();
1448                    else
1449                        return revertState(false);
1450                }
1451            }
1452
1453            /**
1454             * Returns the next token if it matches the specified pattern. This 
1455             * method may block while waiting for input to scan, even if a previous
1456             * invocation of {@link #hasNext(Pattern)} returned <code>true</code>. 
1457             * If the match is successful, the scanner advances past the input that 
1458             * matched the pattern.
1459             *
1460             * @param pattern the pattern to scan for
1461             * @return the next token
1462             * @throws NoSuchElementException if no more tokens are available
1463             * @throws IllegalStateException if this scanner is closed
1464             */
1465            public String next(Pattern pattern) {
1466                ensureOpen();
1467                if (pattern == null)
1468                    throw new NullPointerException();
1469
1470                // Did we already find this pattern?
1471                if (hasNextPattern == pattern)
1472                    return getCachedResult();
1473                clearCaches();
1474
1475                // Search for the pattern
1476                while (true) {
1477                    String token = getCompleteTokenInBuffer(pattern);
1478                    if (token != null) {
1479                        matchValid = true;
1480                        skipped = false;
1481                        return token;
1482                    }
1483                    if (needInput)
1484                        readInput();
1485                    else
1486                        throwFor();
1487                }
1488            }
1489
1490            /**
1491             * Returns true if there is another line in the input of this scanner.
1492             * This method may block while waiting for input. The scanner does not 
1493             * advance past any input.
1494             *
1495             * @return true if and only if this scanner has another line of input
1496             * @throws IllegalStateException if this scanner is closed
1497             */
1498            public boolean hasNextLine() {
1499                saveState();
1500
1501                String result = findWithinHorizon(linePattern(), 0);
1502                if (result != null) {
1503                    MatchResult mr = this .match();
1504                    String lineSep = mr.group(1);
1505                    if (lineSep != null) {
1506                        result = result.substring(0, result.length()
1507                                - lineSep.length());
1508                        cacheResult(result);
1509
1510                    } else {
1511                        cacheResult();
1512                    }
1513                }
1514                revertState();
1515                return (result != null);
1516            }
1517
1518            /**
1519             * Advances this scanner past the current line and returns the input
1520             * that was skipped.
1521             *
1522             * This method returns the rest of the current line, excluding any line
1523             * separator at the end. The position is set to the beginning of the next 
1524             * line.
1525             *
1526             * <p>Since this method continues to search through the input looking
1527             * for a line separator, it may buffer all of the input searching for
1528             * the line to skip if no line separators are present.
1529             *
1530             * @return the line that was skipped
1531             * @throws NoSuchElementException if no line was found
1532             * @throws IllegalStateException if this scanner is closed
1533             */
1534            public String nextLine() {
1535                if (hasNextPattern == linePattern())
1536                    return getCachedResult();
1537                clearCaches();
1538
1539                String result = findWithinHorizon(linePattern, 0);
1540                if (result == null)
1541                    throw new NoSuchElementException("No line found");
1542                MatchResult mr = this .match();
1543                String lineSep = mr.group(1);
1544                if (lineSep != null)
1545                    result = result.substring(0, result.length()
1546                            - lineSep.length());
1547                if (result == null)
1548                    throw new NoSuchElementException();
1549                else
1550                    return result;
1551            }
1552
1553            // Public methods that ignore delimiters
1554
1555            /**
1556             * Attempts to find the next occurrence of a pattern constructed from the
1557             * specified string, ignoring delimiters.
1558             *
1559             * <p>An invocation of this method of the form <tt>findInLine(pattern)</tt>
1560             * behaves in exactly the same way as the invocation 
1561             * <tt>findInLine(Pattern.compile(pattern))</tt>.
1562             *
1563             * @param pattern a string specifying the pattern to search for
1564             * @return the text that matched the specified pattern
1565             * @throws IllegalStateException if this scanner is closed
1566             */
1567            public String findInLine(String pattern) {
1568                return findInLine(patternCache.forName(pattern));
1569            }
1570
1571            /**
1572             * Attempts to find the next occurrence of the specified pattern ignoring
1573             * delimiters. If the pattern is found before the next line separator, the
1574             * scanner advances past the input that matched and returns the string that
1575             * matched the pattern.
1576             * If no such pattern is detected in the input up to the next line
1577             * separator, then <code>null</code> is returned and the scanner's 
1578             * position is unchanged. This method may block waiting for input that 
1579             * matches the pattern.
1580             *
1581             * <p>Since this method continues to search through the input looking
1582             * for the specified pattern, it may buffer all of the input searching for
1583             * the desired token if no line separators are present.
1584             *
1585             * @param pattern the pattern to scan for
1586             * @return the text that matched the specified pattern
1587             * @throws IllegalStateException if this scanner is closed
1588             */
1589            public String findInLine(Pattern pattern) {
1590                ensureOpen();
1591                if (pattern == null)
1592                    throw new NullPointerException();
1593                clearCaches();
1594                // Expand buffer to include the next newline or end of input
1595                int endPosition = 0;
1596                saveState();
1597                while (true) {
1598                    String token = findPatternInBuffer(separatorPattern(), 0);
1599                    if (token != null) {
1600                        endPosition = matcher.start();
1601                        break; // up to next newline
1602                    }
1603                    if (needInput) {
1604                        readInput();
1605                    } else {
1606                        endPosition = buf.limit();
1607                        break; // up to end of input
1608                    }
1609                }
1610                revertState();
1611                int horizonForLine = endPosition - position;
1612                // If there is nothing between the current pos and the next
1613                // newline simply return null, invoking findWithinHorizon 
1614                // with "horizon=0" will scan beyond the line bound.
1615                if (horizonForLine == 0)
1616                    return null;
1617                // Search for the pattern
1618                return findWithinHorizon(pattern, horizonForLine);
1619            }
1620
1621            /**
1622             * Attempts to find the next occurrence of a pattern constructed from the
1623             * specified string, ignoring delimiters.
1624             *
1625             * <p>An invocation of this method of the form 
1626             * <tt>findWithinHorizon(pattern)</tt> behaves in exactly the same way as 
1627             * the invocation 
1628             * <tt>findWithinHorizon(Pattern.compile(pattern, horizon))</tt>.
1629             *
1630             * @param pattern a string specifying the pattern to search for
1631             * @return the text that matched the specified pattern
1632             * @throws IllegalStateException if this scanner is closed
1633             * @throws IllegalArgumentException if horizon is negative
1634             */
1635            public String findWithinHorizon(String pattern, int horizon) {
1636                return findWithinHorizon(patternCache.forName(pattern), horizon);
1637            }
1638
1639            /**
1640             * Attempts to find the next occurrence of the specified pattern.
1641             *
1642             * <p>This method searches through the input up to the specified
1643             * search horizon, ignoring delimiters. If the pattern is found the 
1644             * scanner advances past the input that matched and returns the string 
1645             * that matched the pattern. If no such pattern is detected then the 
1646             * null is returned and the scanner's position remains unchanged. This 
1647             * method may block waiting for input that matches the pattern.
1648             *
1649             * <p>A scanner will never search more than <code>horizon</code> code
1650             * points beyond its current position. Note that a match may be clipped
1651             * by the horizon; that is, an arbitrary match result may have been 
1652             * different if the horizon had been larger. The scanner treats the
1653             * horizon as a transparent, non-anchoring bound (see {@link 
1654             * Matcher#useTransparentBounds} and {@link Matcher#useAnchoringBounds}).
1655             *
1656             * <p>If horizon is <code>0</code>, then the horizon is ignored and
1657             * this method continues to search through the input looking for the 
1658             * specified pattern without bound. In this case it may buffer all of
1659             * the input searching for the pattern.
1660             *
1661             * <p>If horizon is negative, then an IllegalArgumentException is
1662             * thrown.
1663             *
1664             * @param pattern the pattern to scan for
1665             * @return the text that matched the specified pattern
1666             * @throws IllegalStateException if this scanner is closed
1667             * @throws IllegalArgumentException if horizon is negative
1668             */
1669            public String findWithinHorizon(Pattern pattern, int horizon) {
1670                ensureOpen();
1671                if (pattern == null)
1672                    throw new NullPointerException();
1673                if (horizon < 0)
1674                    throw new IllegalArgumentException("horizon < 0");
1675                clearCaches();
1676
1677                // Search for the pattern
1678                while (true) {
1679                    String token = findPatternInBuffer(pattern, horizon);
1680                    if (token != null) {
1681                        matchValid = true;
1682                        return token;
1683                    }
1684                    if (needInput)
1685                        readInput();
1686                    else
1687                        break; // up to end of input
1688                }
1689                return null;
1690            }
1691
1692            /**
1693             * Skips input that matches the specified pattern, ignoring delimiters.
1694             * This method will skip input if an anchored match of the specified
1695             * pattern succeeds.
1696             *
1697             * <p>If a match to the specified pattern is not found at the
1698             * current position, then no input is skipped and a 
1699             * <tt>NoSuchElementException</tt> is thrown.
1700             *
1701             * <p>Since this method seeks to match the specified pattern starting at
1702             * the scanner's current position, patterns that can match a lot of
1703             * input (".*", for example) may cause the scanner to buffer a large
1704             * amount of input.
1705             *
1706             * <p>Note that it is possible to skip something without risking a
1707             * <code>NoSuchElementException</code> by using a pattern that can
1708             * match nothing, e.g., <code>sc.skip("[ \t]*")</code>.
1709             *
1710             * @param pattern a string specifying the pattern to skip over
1711             * @return this scanner
1712             * @throws NoSuchElementException if the specified pattern is not found
1713             * @throws IllegalStateException if this scanner is closed
1714             */
1715            public Scanner skip(Pattern pattern) {
1716                ensureOpen();
1717                if (pattern == null)
1718                    throw new NullPointerException();
1719                clearCaches();
1720
1721                // Search for the pattern
1722                while (true) {
1723                    String token = matchPatternInBuffer(pattern);
1724                    if (token != null) {
1725                        matchValid = true;
1726                        position = matcher.end();
1727                        return this ;
1728                    }
1729                    if (needInput)
1730                        readInput();
1731                    else
1732                        throw new NoSuchElementException();
1733                }
1734            }
1735
1736            /**
1737             * Skips input that matches a pattern constructed from the specified
1738             * string.
1739             *
1740             * <p> An invocation of this method of the form <tt>skip(pattern)</tt>
1741             * behaves in exactly the same way as the invocation 
1742             * <tt>skip(Pattern.compile(pattern))</tt>.
1743             *
1744             * @param pattern a string specifying the pattern to skip over
1745             * @return this scanner
1746             * @throws IllegalStateException if this scanner is closed
1747             */
1748            public Scanner skip(String pattern) {
1749                return skip(patternCache.forName(pattern));
1750            }
1751
1752            // Convenience methods for scanning primitives
1753
1754            /**
1755             * Returns true if the next token in this scanner's input can be
1756             * interpreted as a boolean value using a case insensitive pattern 
1757             * created from the string "true|false".  The scanner does not
1758             * advance past the input that matched.
1759             *
1760             * @return true if and only if this scanner's next token is a valid
1761             *         boolean value
1762             * @throws IllegalStateException if this scanner is closed
1763             */
1764            public boolean hasNextBoolean() {
1765                return hasNext(boolPattern());
1766            }
1767
1768            /**
1769             * Scans the next token of the input into a boolean value and returns
1770             * that value. This method will throw <code>InputMismatchException</code>
1771             * if the next token cannot be translated into a valid boolean value.
1772             * If the match is successful, the scanner advances past the input that 
1773             * matched.
1774             *
1775             * @return the boolean scanned from the input
1776             * @throws InputMismatchException if the next token is not a valid boolean
1777             * @throws NoSuchElementException if input is exhausted
1778             * @throws IllegalStateException if this scanner is closed
1779             */
1780            public boolean nextBoolean() {
1781                clearCaches();
1782                return Boolean.parseBoolean(next(boolPattern()));
1783            }
1784
1785            /**
1786             * Returns true if the next token in this scanner's input can be
1787             * interpreted as a byte value in the default radix using the 
1788             * {@link #nextByte} method. The scanner does not advance past any input.
1789             *
1790             * @return true if and only if this scanner's next token is a valid
1791             *         byte value
1792             * @throws IllegalStateException if this scanner is closed
1793             */
1794            public boolean hasNextByte() {
1795                return hasNextByte(defaultRadix);
1796            }
1797
1798            /**
1799             * Returns true if the next token in this scanner's input can be
1800             * interpreted as a byte value in the specified radix using the 
1801             * {@link #nextByte} method. The scanner does not advance past any input.
1802             *
1803             * @param radix the radix used to interpret the token as a byte value
1804             * @return true if and only if this scanner's next token is a valid
1805             *         byte value
1806             * @throws IllegalStateException if this scanner is closed
1807             */
1808            public boolean hasNextByte(int radix) {
1809                setRadix(radix);
1810                boolean result = hasNext(integerPattern());
1811                if (result) { // Cache it
1812                    try {
1813                        String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? processIntegerToken(hasNextResult)
1814                                : hasNextResult;
1815                        typeCache = Byte.parseByte(s, radix);
1816                    } catch (NumberFormatException nfe) {
1817                        result = false;
1818                    }
1819                }
1820                return result;
1821            }
1822
1823            /**
1824             * Scans the next token of the input as a <tt>byte</tt>.
1825             *
1826             * <p> An invocation of this method of the form 
1827             * <tt>nextByte()</tt> behaves in exactly the same way as the
1828             * invocation <tt>nextByte(radix)</tt>, where <code>radix</code>
1829             * is the default radix of this scanner.
1830             *
1831             * @return the <tt>byte</tt> scanned from the input
1832             * @throws InputMismatchException
1833             *         if the next token does not match the <i>Integer</i>
1834             *         regular expression, or is out of range
1835             * @throws NoSuchElementException if input is exhausted
1836             * @throws IllegalStateException if this scanner is closed
1837             */
1838            public byte nextByte() {
1839                return nextByte(defaultRadix);
1840            }
1841
1842            /**
1843             * Scans the next token of the input as a <tt>byte</tt>.
1844             * This method will throw <code>InputMismatchException</code>
1845             * if the next token cannot be translated into a valid byte value as
1846             * described below. If the translation is successful, the scanner advances
1847             * past the input that matched.
1848             *
1849             * <p> If the next token matches the <a
1850             * href="#Integer-regex"><i>Integer</i></a> regular expression defined 
1851             * above then the token is converted into a <tt>byte</tt> value as if by
1852             * removing all locale specific prefixes, group separators, and locale
1853             * specific suffixes, then mapping non-ASCII digits into ASCII
1854             * digits via {@link Character#digit Character.digit}, prepending a
1855             * negative sign (-) if the locale specific negative prefixes and suffixes
1856             * were present, and passing the resulting string to
1857             * {@link Byte#parseByte(String, int) Byte.parseByte} with the
1858             * specified radix.
1859             *
1860             * @param radix the radix used to interpret the token as a byte value
1861             * @return the <tt>byte</tt> scanned from the input
1862             * @throws InputMismatchException
1863             *         if the next token does not match the <i>Integer</i>
1864             *         regular expression, or is out of range
1865             * @throws NoSuchElementException if input is exhausted
1866             * @throws IllegalStateException if this scanner is closed
1867             */
1868            public byte nextByte(int radix) {
1869                // Check cached result
1870                if ((typeCache != null) && (typeCache instanceof  Byte)
1871                        && this .radix == radix) {
1872                    byte val = ((Byte) typeCache).byteValue();
1873                    useTypeCache();
1874                    return val;
1875                }
1876                setRadix(radix);
1877                clearCaches();
1878                // Search for next byte
1879                try {
1880                    String s = next(integerPattern());
1881                    if (matcher.group(SIMPLE_GROUP_INDEX) == null)
1882                        s = processIntegerToken(s);
1883                    return Byte.parseByte(s, radix);
1884                } catch (NumberFormatException nfe) {
1885                    position = matcher.start(); // don't skip bad token
1886                    throw new InputMismatchException(nfe.getMessage());
1887                }
1888            }
1889
1890            /**
1891             * Returns true if the next token in this scanner's input can be
1892             * interpreted as a short value in the default radix using the 
1893             * {@link #nextShort} method. The scanner does not advance past any input.
1894             *
1895             * @return true if and only if this scanner's next token is a valid
1896             *         short value in the default radix
1897             * @throws IllegalStateException if this scanner is closed
1898             */
1899            public boolean hasNextShort() {
1900                return hasNextShort(defaultRadix);
1901            }
1902
1903            /**
1904             * Returns true if the next token in this scanner's input can be
1905             * interpreted as a short value in the specified radix using the 
1906             * {@link #nextShort} method. The scanner does not advance past any input.
1907             *
1908             * @param radix the radix used to interpret the token as a short value
1909             * @return true if and only if this scanner's next token is a valid
1910             *         short value in the specified radix
1911             * @throws IllegalStateException if this scanner is closed
1912             */
1913            public boolean hasNextShort(int radix) {
1914                setRadix(radix);
1915                boolean result = hasNext(integerPattern());
1916                if (result) { // Cache it
1917                    try {
1918                        String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? processIntegerToken(hasNextResult)
1919                                : hasNextResult;
1920                        typeCache = Short.parseShort(s, radix);
1921                    } catch (NumberFormatException nfe) {
1922                        result = false;
1923                    }
1924                }
1925                return result;
1926            }
1927
1928            /**
1929             * Scans the next token of the input as a <tt>short</tt>.
1930             *
1931             * <p> An invocation of this method of the form 
1932             * <tt>nextShort()</tt> behaves in exactly the same way as the
1933             * invocation <tt>nextShort(radix)</tt>, where <code>radix</code>
1934             * is the default radix of this scanner.
1935             *
1936             * @return the <tt>short</tt> scanned from the input
1937             * @throws InputMismatchException
1938             *         if the next token does not match the <i>Integer</i>
1939             *         regular expression, or is out of range
1940             * @throws NoSuchElementException if input is exhausted
1941             * @throws IllegalStateException if this scanner is closed
1942             */
1943            public short nextShort() {
1944                return nextShort(defaultRadix);
1945            }
1946
1947            /**
1948             * Scans the next token of the input as a <tt>short</tt>.
1949             * This method will throw <code>InputMismatchException</code>
1950             * if the next token cannot be translated into a valid short value as
1951             * described below. If the translation is successful, the scanner advances
1952             * past the input that matched.
1953             *
1954             * <p> If the next token matches the <a
1955             * href="#Integer-regex"><i>Integer</i></a> regular expression defined 
1956             * above then the token is converted into a <tt>short</tt> value as if by
1957             * removing all locale specific prefixes, group separators, and locale
1958             * specific suffixes, then mapping non-ASCII digits into ASCII
1959             * digits via {@link Character#digit Character.digit}, prepending a
1960             * negative sign (-) if the locale specific negative prefixes and suffixes
1961             * were present, and passing the resulting string to
1962             * {@link Short#parseShort(String, int) Short.parseShort} with the 
1963             * specified radix.
1964             *
1965             * @param radix the radix used to interpret the token as a short value
1966             * @return the <tt>short</tt> scanned from the input
1967             * @throws InputMismatchException
1968             *         if the next token does not match the <i>Integer</i>
1969             *         regular expression, or is out of range
1970             * @throws NoSuchElementException if input is exhausted
1971             * @throws IllegalStateException if this scanner is closed
1972             */
1973            public short nextShort(int radix) {
1974                // Check cached result
1975                if ((typeCache != null) && (typeCache instanceof  Short)
1976                        && this .radix == radix) {
1977                    short val = ((Short) typeCache).shortValue();
1978                    useTypeCache();
1979                    return val;
1980                }
1981                setRadix(radix);
1982                clearCaches();
1983                // Search for next short
1984                try {
1985                    String s = next(integerPattern());
1986                    if (matcher.group(SIMPLE_GROUP_INDEX) == null)
1987                        s = processIntegerToken(s);
1988                    return Short.parseShort(s, radix);
1989                } catch (NumberFormatException nfe) {
1990                    position = matcher.start(); // don't skip bad token
1991                    throw new InputMismatchException(nfe.getMessage());
1992                }
1993            }
1994
1995            /**
1996             * Returns true if the next token in this scanner's input can be
1997             * interpreted as an int value in the default radix using the 
1998             * {@link #nextInt} method. The scanner does not advance past any input.
1999             *
2000             * @return true if and only if this scanner's next token is a valid
2001             *         int value
2002             * @throws IllegalStateException if this scanner is closed
2003             */
2004            public boolean hasNextInt() {
2005                return hasNextInt(defaultRadix);
2006            }
2007
2008            /**
2009             * Returns true if the next token in this scanner's input can be
2010             * interpreted as an int value in the specified radix using the 
2011             * {@link #nextInt} method. The scanner does not advance past any input.
2012             *
2013             * @param radix the radix used to interpret the token as an int value
2014             * @return true if and only if this scanner's next token is a valid
2015             *         int value
2016             * @throws IllegalStateException if this scanner is closed
2017             */
2018            public boolean hasNextInt(int radix) {
2019                setRadix(radix);
2020                boolean result = hasNext(integerPattern());
2021                if (result) { // Cache it
2022                    try {
2023                        String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? processIntegerToken(hasNextResult)
2024                                : hasNextResult;
2025                        typeCache = Integer.parseInt(s, radix);
2026                    } catch (NumberFormatException nfe) {
2027                        result = false;
2028                    }
2029                }
2030                return result;
2031            }
2032
2033            /**
2034             * The integer token must be stripped of prefixes, group separators,
2035             * and suffixes, non ascii digits must be converted into ascii digits
2036             * before parse will accept it.
2037             */
2038            private String processIntegerToken(String token) {
2039                String result = token.replaceAll("" + groupSeparator, "");
2040                boolean isNegative = false;
2041                int preLen = negativePrefix.length();
2042                if ((preLen > 0) && result.startsWith(negativePrefix)) {
2043                    isNegative = true;
2044                    result = result.substring(preLen);
2045                }
2046                int sufLen = negativeSuffix.length();
2047                if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2048                    isNegative = true;
2049                    result = result.substring(result.length() - sufLen, result
2050                            .length());
2051                }
2052                if (isNegative)
2053                    result = "-" + result;
2054                return result;
2055            }
2056
2057            /**
2058             * Scans the next token of the input as an <tt>int</tt>.
2059             *
2060             * <p> An invocation of this method of the form 
2061             * <tt>nextInt()</tt> behaves in exactly the same way as the
2062             * invocation <tt>nextInt(radix)</tt>, where <code>radix</code>
2063             * is the default radix of this scanner.
2064             *
2065             * @return the <tt>int</tt> scanned from the input
2066             * @throws InputMismatchException
2067             *         if the next token does not match the <i>Integer</i>
2068             *         regular expression, or is out of range
2069             * @throws NoSuchElementException if input is exhausted
2070             * @throws IllegalStateException if this scanner is closed
2071             */
2072            public int nextInt() {
2073                return nextInt(defaultRadix);
2074            }
2075
2076            /**
2077             * Scans the next token of the input as an <tt>int</tt>.
2078             * This method will throw <code>InputMismatchException</code>
2079             * if the next token cannot be translated into a valid int value as
2080             * described below. If the translation is successful, the scanner advances
2081             * past the input that matched.
2082             *
2083             * <p> If the next token matches the <a
2084             * href="#Integer-regex"><i>Integer</i></a> regular expression defined 
2085             * above then the token is converted into an <tt>int</tt> value as if by
2086             * removing all locale specific prefixes, group separators, and locale
2087             * specific suffixes, then mapping non-ASCII digits into ASCII
2088             * digits via {@link Character#digit Character.digit}, prepending a
2089             * negative sign (-) if the locale specific negative prefixes and suffixes
2090             * were present, and passing the resulting string to
2091             * {@link Integer#parseInt(String, int) Integer.parseInt} with the
2092             * specified radix.
2093             *
2094             * @param radix the radix used to interpret the token as an int value
2095             * @return the <tt>int</tt> scanned from the input
2096             * @throws InputMismatchException
2097             *         if the next token does not match the <i>Integer</i>
2098             *         regular expression, or is out of range
2099             * @throws NoSuchElementException if input is exhausted
2100             * @throws IllegalStateException if this scanner is closed
2101             */
2102            public int nextInt(int radix) {
2103                // Check cached result
2104                if ((typeCache != null) && (typeCache instanceof  Integer)
2105                        && this .radix == radix) {
2106                    int val = ((Integer) typeCache).intValue();
2107                    useTypeCache();
2108                    return val;
2109                }
2110                setRadix(radix);
2111                clearCaches();
2112                // Search for next int
2113                try {
2114                    String s = next(integerPattern());
2115                    if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2116                        s = processIntegerToken(s);
2117                    return Integer.parseInt(s, radix);
2118                } catch (NumberFormatException nfe) {
2119                    position = matcher.start(); // don't skip bad token
2120                    throw new InputMismatchException(nfe.getMessage());
2121                }
2122            }
2123
2124            /**
2125             * Returns true if the next token in this scanner's input can be
2126             * interpreted as a long value in the default radix using the 
2127             * {@link #nextLong} method. The scanner does not advance past any input.
2128             *
2129             * @return true if and only if this scanner's next token is a valid
2130             *         long value
2131             * @throws IllegalStateException if this scanner is closed
2132             */
2133            public boolean hasNextLong() {
2134                return hasNextLong(defaultRadix);
2135            }
2136
2137            /**
2138             * Returns true if the next token in this scanner's input can be
2139             * interpreted as a long value in the specified radix using the 
2140             * {@link #nextLong} method. The scanner does not advance past any input.
2141             *
2142             * @param radix the radix used to interpret the token as a long value
2143             * @return true if and only if this scanner's next token is a valid
2144             *         long value
2145             * @throws IllegalStateException if this scanner is closed
2146             */
2147            public boolean hasNextLong(int radix) {
2148                setRadix(radix);
2149                boolean result = hasNext(integerPattern());
2150                if (result) { // Cache it
2151                    try {
2152                        String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? processIntegerToken(hasNextResult)
2153                                : hasNextResult;
2154                        typeCache = Long.parseLong(s, radix);
2155                    } catch (NumberFormatException nfe) {
2156                        result = false;
2157                    }
2158                }
2159                return result;
2160            }
2161
2162            /**
2163             * Scans the next token of the input as a <tt>long</tt>.
2164             *
2165             * <p> An invocation of this method of the form 
2166             * <tt>nextLong()</tt> behaves in exactly the same way as the
2167             * invocation <tt>nextLong(radix)</tt>, where <code>radix</code>
2168             * is the default radix of this scanner.
2169             *
2170             * @return the <tt>long</tt> scanned from the input
2171             * @throws InputMismatchException
2172             *         if the next token does not match the <i>Integer</i>
2173             *         regular expression, or is out of range
2174             * @throws NoSuchElementException if input is exhausted
2175             * @throws IllegalStateException if this scanner is closed
2176             */
2177            public long nextLong() {
2178                return nextLong(defaultRadix);
2179            }
2180
2181            /**
2182             * Scans the next token of the input as a <tt>long</tt>.
2183             * This method will throw <code>InputMismatchException</code>
2184             * if the next token cannot be translated into a valid long value as
2185             * described below. If the translation is successful, the scanner advances
2186             * past the input that matched.
2187             *
2188             * <p> If the next token matches the <a
2189             * href="#Integer-regex"><i>Integer</i></a> regular expression defined 
2190             * above then the token is converted into a <tt>long</tt> value as if by
2191             * removing all locale specific prefixes, group separators, and locale
2192             * specific suffixes, then mapping non-ASCII digits into ASCII
2193             * digits via {@link Character#digit Character.digit}, prepending a
2194             * negative sign (-) if the locale specific negative prefixes and suffixes
2195             * were present, and passing the resulting string to
2196             * {@link Long#parseLong(String, int) Long.parseLong} with the
2197             * specified radix.
2198             *
2199             * @param radix the radix used to interpret the token as an int value
2200             * @return the <tt>long</tt> scanned from the input
2201             * @throws InputMismatchException
2202             *         if the next token does not match the <i>Integer</i>
2203             *         regular expression, or is out of range
2204             * @throws NoSuchElementException if input is exhausted
2205             * @throws IllegalStateException if this scanner is closed
2206             */
2207            public long nextLong(int radix) {
2208                // Check cached result
2209                if ((typeCache != null) && (typeCache instanceof  Long)
2210                        && this .radix == radix) {
2211                    long val = ((Long) typeCache).longValue();
2212                    useTypeCache();
2213                    return val;
2214                }
2215                setRadix(radix);
2216                clearCaches();
2217                try {
2218                    String s = next(integerPattern());
2219                    if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2220                        s = processIntegerToken(s);
2221                    return Long.parseLong(s, radix);
2222                } catch (NumberFormatException nfe) {
2223                    position = matcher.start(); // don't skip bad token
2224                    throw new InputMismatchException(nfe.getMessage());
2225                }
2226            }
2227
2228            /**
2229             * The float token must be stripped of prefixes, group separators,
2230             * and suffixes, non ascii digits must be converted into ascii digits
2231             * before parseFloat will accept it.
2232             *
2233             * If there are non-ascii digits in the token these digits must
2234             * be processed before the token is passed to parseFloat.
2235             */
2236            private String processFloatToken(String token) {
2237                String result = token.replaceAll(groupSeparator, "");
2238                if (!decimalSeparator.equals("\\."))
2239                    result = result.replaceAll(decimalSeparator, ".");
2240                boolean isNegative = false;
2241                int preLen = negativePrefix.length();
2242                if ((preLen > 0) && result.startsWith(negativePrefix)) {
2243                    isNegative = true;
2244                    result = result.substring(preLen);
2245                }
2246                int sufLen = negativeSuffix.length();
2247                if ((sufLen > 0) && result.endsWith(negativeSuffix)) {
2248                    isNegative = true;
2249                    result = result.substring(result.length() - sufLen, result
2250                            .length());
2251                }
2252                if (result.equals(nanString))
2253                    result = "NaN";
2254                if (result.equals(infinityString))
2255                    result = "Infinity";
2256                if (isNegative)
2257                    result = "-" + result;
2258
2259                // Translate non-ASCII digits
2260                Matcher m = NON_ASCII_DIGIT.matcher(result);
2261                if (m.find()) {
2262                    StringBuilder inASCII = new StringBuilder();
2263                    for (int i = 0; i < result.length(); i++) {
2264                        char nextChar = result.charAt(i);
2265                        if (Character.isDigit(nextChar)) {
2266                            int d = Character.digit(nextChar, 10);
2267                            if (d != -1)
2268                                inASCII.append(d);
2269                            else
2270                                inASCII.append(nextChar);
2271                        } else {
2272                            inASCII.append(nextChar);
2273                        }
2274                    }
2275                    result = inASCII.toString();
2276                }
2277
2278                return result;
2279            }
2280
2281            /**
2282             * Returns true if the next token in this scanner's input can be
2283             * interpreted as a float value using the {@link #nextFloat} 
2284             * method. The scanner does not advance past any input.
2285             *
2286             * @return true if and only if this scanner's next token is a valid
2287             *         float value
2288             * @throws IllegalStateException if this scanner is closed
2289             */
2290            public boolean hasNextFloat() {
2291                setRadix(10);
2292                boolean result = hasNext(floatPattern());
2293                if (result) { // Cache it
2294                    try {
2295                        String s = processFloatToken(hasNextResult);
2296                        typeCache = Float.valueOf(Float.parseFloat(s));
2297                    } catch (NumberFormatException nfe) {
2298                        result = false;
2299                    }
2300                }
2301                return result;
2302            }
2303
2304            /**
2305             * Scans the next token of the input as a <tt>float</tt>.
2306             * This method will throw <code>InputMismatchException</code>
2307             * if the next token cannot be translated into a valid float value as
2308             * described below. If the translation is successful, the scanner advances
2309             * past the input that matched.
2310             *
2311             * <p> If the next token matches the <a
2312             * href="#Float-regex"><i>Float</i></a> regular expression defined above
2313             * then the token is converted into a <tt>float</tt> value as if by
2314             * removing all locale specific prefixes, group separators, and locale
2315             * specific suffixes, then mapping non-ASCII digits into ASCII
2316             * digits via {@link Character#digit Character.digit}, prepending a
2317             * negative sign (-) if the locale specific negative prefixes and suffixes
2318             * were present, and passing the resulting string to
2319             * {@link Float#parseFloat Float.parseFloat}. If the token matches
2320             * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2321             * is passed to {@link Float#parseFloat(String) Float.parseFloat} as 
2322             * appropriate.
2323             *
2324             * @return the <tt>float</tt> scanned from the input
2325             * @throws InputMismatchException
2326             *         if the next token does not match the <i>Float</i>
2327             *         regular expression, or is out of range
2328             * @throws NoSuchElementException if input is exhausted
2329             * @throws IllegalStateException if this scanner is closed
2330             */
2331            public float nextFloat() {
2332                // Check cached result
2333                if ((typeCache != null) && (typeCache instanceof  Float)) {
2334                    float val = ((Float) typeCache).floatValue();
2335                    useTypeCache();
2336                    return val;
2337                }
2338                setRadix(10);
2339                clearCaches();
2340                try {
2341                    return Float
2342                            .parseFloat(processFloatToken(next(floatPattern())));
2343                } catch (NumberFormatException nfe) {
2344                    position = matcher.start(); // don't skip bad token
2345                    throw new InputMismatchException(nfe.getMessage());
2346                }
2347            }
2348
2349            /**
2350             * Returns true if the next token in this scanner's input can be
2351             * interpreted as a double value using the {@link #nextDouble} 
2352             * method. The scanner does not advance past any input.
2353             *
2354             * @return true if and only if this scanner's next token is a valid
2355             *         double value
2356             * @throws IllegalStateException if this scanner is closed
2357             */
2358            public boolean hasNextDouble() {
2359                setRadix(10);
2360                boolean result = hasNext(floatPattern());
2361                if (result) { // Cache it
2362                    try {
2363                        String s = processFloatToken(hasNextResult);
2364                        typeCache = Double.valueOf(Double.parseDouble(s));
2365                    } catch (NumberFormatException nfe) {
2366                        result = false;
2367                    }
2368                }
2369                return result;
2370            }
2371
2372            /**
2373             * Scans the next token of the input as a <tt>double</tt>.
2374             * This method will throw <code>InputMismatchException</code>
2375             * if the next token cannot be translated into a valid double value.
2376             * If the translation is successful, the scanner advances past the input 
2377             * that matched.
2378             *
2379             * <p> If the next token matches the <a
2380             * href="#Float-regex"><i>Float</i></a> regular expression defined above
2381             * then the token is converted into a <tt>double</tt> value as if by
2382             * removing all locale specific prefixes, group separators, and locale
2383             * specific suffixes, then mapping non-ASCII digits into ASCII
2384             * digits via {@link Character#digit Character.digit}, prepending a
2385             * negative sign (-) if the locale specific negative prefixes and suffixes
2386             * were present, and passing the resulting string to
2387             * {@link Double#parseDouble Double.parseDouble}. If the token matches
2388             * the localized NaN or infinity strings, then either "Nan" or "Infinity"
2389             * is passed to {@link Double#parseDouble(String) Double.parseDouble} as 
2390             * appropriate.
2391             *
2392             * @return the <tt>double</tt> scanned from the input
2393             * @throws InputMismatchException
2394             *         if the next token does not match the <i>Float</i>
2395             *         regular expression, or is out of range
2396             * @throws NoSuchElementException if the input is exhausted
2397             * @throws IllegalStateException if this scanner is closed
2398             */
2399            public double nextDouble() {
2400                // Check cached result
2401                if ((typeCache != null) && (typeCache instanceof  Double)) {
2402                    double val = ((Double) typeCache).doubleValue();
2403                    useTypeCache();
2404                    return val;
2405                }
2406                setRadix(10);
2407                clearCaches();
2408                // Search for next float
2409                try {
2410                    return Double
2411                            .parseDouble(processFloatToken(next(floatPattern())));
2412                } catch (NumberFormatException nfe) {
2413                    position = matcher.start(); // don't skip bad token
2414                    throw new InputMismatchException(nfe.getMessage());
2415                }
2416            }
2417
2418            // Convenience methods for scanning multi precision numbers
2419
2420            /**
2421             * Returns true if the next token in this scanner's input can be
2422             * interpreted as a <code>BigInteger</code> in the default radix using the 
2423             * {@link #nextBigInteger} method. The scanner does not advance past any 
2424             * input.
2425             *
2426             * @return true if and only if this scanner's next token is a valid
2427             *         <code>BigInteger</code>
2428             * @throws IllegalStateException if this scanner is closed
2429             */
2430            public boolean hasNextBigInteger() {
2431                return hasNextBigInteger(defaultRadix);
2432            }
2433
2434            /**
2435             * Returns true if the next token in this scanner's input can be
2436             * interpreted as a <code>BigInteger</code> in the specified radix using 
2437             * the {@link #nextBigInteger} method. The scanner does not advance past 
2438             * any input.
2439             *
2440             * @param radix the radix used to interpret the token as an integer
2441             * @return true if and only if this scanner's next token is a valid
2442             *         <code>BigInteger</code>
2443             * @throws IllegalStateException if this scanner is closed
2444             */
2445            public boolean hasNextBigInteger(int radix) {
2446                setRadix(radix);
2447                boolean result = hasNext(integerPattern());
2448                if (result) { // Cache it
2449                    try {
2450                        String s = (matcher.group(SIMPLE_GROUP_INDEX) == null) ? processIntegerToken(hasNextResult)
2451                                : hasNextResult;
2452                        typeCache = new BigInteger(s, radix);
2453                    } catch (NumberFormatException nfe) {
2454                        result = false;
2455                    }
2456                }
2457                return result;
2458            }
2459
2460            /**
2461             * Scans the next token of the input as a {@link java.math.BigInteger
2462             * BigInteger}.
2463             *
2464             * <p> An invocation of this method of the form 
2465             * <tt>nextBigInteger()</tt> behaves in exactly the same way as the
2466             * invocation <tt>nextBigInteger(radix)</tt>, where <code>radix</code>
2467             * is the default radix of this scanner.
2468             *
2469             * @return the <tt>BigInteger</tt> scanned from the input
2470             * @throws InputMismatchException
2471             *         if the next token does not match the <i>Integer</i>
2472             *         regular expression, or is out of range
2473             * @throws NoSuchElementException if the input is exhausted
2474             * @throws IllegalStateException if this scanner is closed
2475             */
2476            public BigInteger nextBigInteger() {
2477                return nextBigInteger(defaultRadix);
2478            }
2479
2480            /**
2481             * Scans the next token of the input as a {@link java.math.BigInteger
2482             * BigInteger}.
2483             *
2484             * <p> If the next token matches the <a
2485             * href="#Integer-regex"><i>Integer</i></a> regular expression defined
2486             * above then the token is converted into a <tt>BigInteger</tt> value as if
2487             * by removing all group separators, mapping non-ASCII digits into ASCII
2488             * digits via the {@link Character#digit Character.digit}, and passing the
2489             * resulting string to the {@link
2490             * java.math.BigInteger#BigInteger(java.lang.String) 
2491             * BigInteger(String, int)} constructor with the specified radix.
2492             *
2493             * @param radix the radix used to interpret the token
2494             * @return the <tt>BigInteger</tt> scanned from the input
2495             * @throws InputMismatchException
2496             *         if the next token does not match the <i>Integer</i>
2497             *         regular expression, or is out of range
2498             * @throws NoSuchElementException if the input is exhausted
2499             * @throws IllegalStateException if this scanner is closed
2500             */
2501            public BigInteger nextBigInteger(int radix) {
2502                // Check cached result
2503                if ((typeCache != null) && (typeCache instanceof  BigInteger)
2504                        && this .radix == radix) {
2505                    BigInteger val = (BigInteger) typeCache;
2506                    useTypeCache();
2507                    return val;
2508                }
2509                setRadix(radix);
2510                clearCaches();
2511                // Search for next int
2512                try {
2513                    String s = next(integerPattern());
2514                    if (matcher.group(SIMPLE_GROUP_INDEX) == null)
2515                        s = processIntegerToken(s);
2516                    return new BigInteger(s, radix);
2517                } catch (NumberFormatException nfe) {
2518                    position = matcher.start(); // don't skip bad token
2519                    throw new InputMismatchException(nfe.getMessage());
2520                }
2521            }
2522
2523            /**
2524             * Returns true if the next token in this scanner's input can be
2525             * interpreted as a <code>BigDecimal</code> using the 
2526             * {@link #nextBigDecimal} method. The scanner does not advance past any 
2527             * input.
2528             *
2529             * @return true if and only if this scanner's next token is a valid
2530             *         <code>BigDecimal</code>
2531             * @throws IllegalStateException if this scanner is closed
2532             */
2533            public boolean hasNextBigDecimal() {
2534                setRadix(10);
2535                boolean result = hasNext(decimalPattern());
2536                if (result) { // Cache it
2537                    try {
2538                        String s = processFloatToken(hasNextResult);
2539                        typeCache = new BigDecimal(s);
2540                    } catch (NumberFormatException nfe) {
2541                        result = false;
2542                    }
2543                }
2544                return result;
2545            }
2546
2547            /**
2548             * Scans the next token of the input as a {@link java.math.BigDecimal
2549             * BigDecimal}.
2550             *
2551             * <p> If the next token matches the <a
2552             * href="#Decimal-regex"><i>Decimal</i></a> regular expression defined
2553             * above then the token is converted into a <tt>BigDecimal</tt> value as if
2554             * by removing all group separators, mapping non-ASCII digits into ASCII
2555             * digits via the {@link Character#digit Character.digit}, and passing the
2556             * resulting string to the {@link
2557             * java.math.BigDecimal#BigDecimal(java.lang.String) BigDecimal(String)}
2558             * constructor.
2559             *
2560             * @return the <tt>BigDecimal</tt> scanned from the input
2561             * @throws InputMismatchException
2562             *         if the next token does not match the <i>Decimal</i>
2563             *         regular expression, or is out of range
2564             * @throws NoSuchElementException if the input is exhausted
2565             * @throws IllegalStateException if this scanner is closed
2566             */
2567            public BigDecimal nextBigDecimal() {
2568                // Check cached result
2569                if ((typeCache != null) && (typeCache instanceof  BigDecimal)) {
2570                    BigDecimal val = (BigDecimal) typeCache;
2571                    useTypeCache();
2572                    return val;
2573                }
2574                setRadix(10);
2575                clearCaches();
2576                // Search for next float
2577                try {
2578                    String s = processFloatToken(next(decimalPattern()));
2579                    return new BigDecimal(s);
2580                } catch (NumberFormatException nfe) {
2581                    position = matcher.start(); // don't skip bad token
2582                    throw new InputMismatchException(nfe.getMessage());
2583                }
2584            }
2585
2586            /**
2587             * Resets this scanner.
2588             *
2589             * <p> Resetting a scanner discards all of its explicit state
2590             * information which may have been changed by invocations of {@link
2591             * #useDelimiter}, {@link #useLocale}, or {@link #useRadix}.
2592             *
2593             * <p> An invocation of this method of the form
2594             * <tt>scanner.reset()</tt> behaves in exactly the same way as the
2595             * invocation
2596             *
2597             * <blockquote><pre>
2598             *   scanner.useDelimiter("\\p{javaWhitespace}+")
2599             *          .useLocale(Locale.getDefault())
2600             *          .useRadix(10);
2601             * </pre></blockquote>
2602             *
2603             * @return this scanner
2604             *
2605             * @since 1.6
2606             */
2607            public Scanner reset() {
2608                delimPattern = WHITESPACE_PATTERN;
2609                useLocale(Locale.getDefault());
2610                useRadix(10);
2611                clearCaches();
2612                return this;
2613            }
2614        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.